Bring Your Own Vault

Your secrets stay in your vault.
Only references ever leave it.

SecRefs expands declarative sec:// URIs directly in memory, at runtime. No plaintext secret is ever written to disk, logged, or sent to a third-party SaaS vault - because there is no third party.

quickstart.sh
pnpm add @secrefs/node
+ @secrefs/node 0.1.0
echo 'DB_PASSWORD=sec://aws/prod/db#password' >> .env
npx secrefs run -- node server.js
secrefs: resolved 1 secret reference(s): DB_PASSWORD
server listening on :3000

You already have a vault. Stop copying secrets out of it.

Every plaintext secret that leaves your vault - into a `.env` file, a CI variable, a teammate's clipboard - is a copy you now have to track, rotate, and eventually leak. SecRefs replaces the copy with a pointer.

.env sprawl
.env (committed to 6 places, rotated in 0)
DB_PASSWORD=correcthorsebatterystaple
STRIPE_KEY=sk_live_51N...
VAULT_TOKEN=hvs.CAESIJ...
# ^ now living on 3 laptops, in Slack, and in CI logs
  • Plaintext secrets on disk, in shell history, in CI logs
  • No single source of truth once a value is copy-pasted
  • Rotation means chasing down every place a copy landed
SecRefs
.env (safe to commit)
DB_PASSWORD=sec://aws/prod/db#password
STRIPE_KEY=sec://vault/secret/data/stripe#key
VAULT_TOKEN=sec://local/mock-vault-token
# ^ just pointers - the real values never left the vault
  • Values expand in memory, once, right before your process starts
  • Your vault stays the single source of truth
  • Rotate in the vault; every app picks it up on next restart

How it works

01

Write a reference, not a value

Put sec://aws/prod/db#password in .env instead of the plaintext password. It's safe to commit.

02

Run your app through secrefs

secrefs run -- node server.js intercepts your environment before your app boots.

03

References resolve in memory

Every sec:// value is fetched from its real vault concurrently, entirely in the CLI's memory.

04

Your process gets real values

The child process inherits a fully-hydrated environment. Nothing was ever written to disk.

Interactive

See the expansion happen, safely

Paste a mock .env, pick which lines are mock provider secrets, and watch SecRefs validate and expand them entirely in your browser's memory. Nothing here ever leaves your machine - there's no backend behind this sandbox.

.env
4 sec:// references detected
Resolved entirely in your browser's memory. Nothing is sent over the network.
resolved environment

Hit Expand to simulate resolving every sec:// reference above.

Bring your own vault

AWS Secrets Manager

sec://aws/...

Ambient AWS credentials or an IAM role - never a static key in your config.

HashiCorp Vault

sec://vault/...

KV v1 & v2, authenticated via VAULT_ADDR / VAULT_TOKEN already in your environment.

Local (dev only)

sec://local/...

A gitignored .secrefs.local.json for teammates who don't have vault access yet.

Quickstart

Node.js / CLI
// package.json
pnpm add @secrefs/node
// .env
DB_PASSWORD=sec://aws/prod/db#password
secrefs run -- node server.js
Node.js / library
import { secRefs } from '@secrefs/node';
await secRefs.init();
// process.env.DB_PASSWORD is now the real value
const key = await secRefs.expandString(
'sec://vault/secret/data/stripe#key'
);
Python
pip install secrefs
from secrefs import sec_refs
await sec_refs.init()
# os.environ['DB_PASSWORD'] is now the real value
secrefs-py run -- python app.py