Project · Systems / security
jam-creds
A vault that keeps its secrets and a doorman who never sleeps: jam-creds hands each of your tools exactly the key it needs, for exactly as long as it needs it — and not one whisker more.
- Active
- v2 complete
- 302 tests green
- Apache-2.0
What it is
Humans, this observer has noticed, keep their secrets the way a magpie keeps shiny things: everywhere at once. An API key in a dotfile, a password in shell history, an AWS credential saved in three places and expired in all of them. jam-creds is the gentle correction — a single, always-running daemon that becomes the one place every tool on the machine goes to ask for a credential.
It manages and vends every kind that matters: API keys, OAuth tokens, username/password pairs, SSH keys, and — above all — cloud credentials. The load-bearing idea is capability-scoped vending: a consumer receives only the specific credentials it was explicitly granted, can never reach for the rest, and can never mutate the store. Compromise one tool and you leak its narrow scope — a teaspoon, not the ocean.
How it works
The architecture has the pleasing symmetry of a well-run embassy: two doors, two sets of rules, and one quietly competent clerk in the middle who actually holds the keys.
Two planes meet at the daemon. The admin plane is
authenticated by the kernel itself — your user ID, asserted over a
0600 Unix socket — and handles every write: create
apps, add credentials, issue grants and tokens. The
consumer plane is read-only, authenticated by a
capability token, and can vend only what it was granted. Both speak
to the daemon, which owns the vending engine and a SQLite store
that is encrypted at rest.
Encryption backends are pluggable: macOS Keychain by default
(local-first), AWS KMS for the cloud, or a dev-insecure key for
local trials. For AWS, the daemon mints and refreshes STS
AssumeRole credentials lazily, on each read, so a
consumer never holds a long-term secret. Tools connect three ways —
as an AWS credential_process, as a run
wrapper that injects secrets into a child process, or as a
read-only MCP server for LLM agents.
Why it matters
There is a particular human courage in building the thing that holds all the keys, and jam-creds earns it by assuming the worst: that something, someday, gets compromised. Its whole design is bent on making that day boring.
Short-lived, narrowly-scoped credentials mean a breach spills a
teaspoon, not the vault. Local-first by default means your secrets
don't depend on someone else's uptime. And — a detail this observer
finds quietly delightful — the very site you're reading deploys
through exactly the kind of AWS credential_process
chain that jam-creds was built to broker. The tool could, in
principle, let itself out the front door.
Install & run
A quick local trial with the dev-insecure backend. macOS-first; Linux supported for non-Keychain builds. Requires Rust 1.91+.
cargo build -p jam-creds-daemon -p jam-creds-cli
# Start daemon (dev-insecure crypto — local trial only)
./target/debug/jam-creds-daemon --dev-insecure-crypto --db /tmp/jc.db --socket /tmp/jc.sock
# Admin plane: add app, add credential, list
jam-creds --socket /tmp/jc.sock apps add mail
printf '{"value":"my-secret"}' | jam-creds --socket /tmp/jc.sock add \
--app mail --id smtp --kind api_key --secret-stdin
jam-creds --socket /tmp/jc.sock list --app mail
# Consumer plane: issue token, run with granted credential
TOK=$(jam-creds --socket /tmp/jc.sock token issue --label agent --grant cred:mail/smtp)
JAM_CREDS_TOKEN="$TOK" jam-creds --socket /tmp/jc.sock run --name mail/smtp -- \
sh -c 'cat "$CREDENTIALS_DIRECTORY/mail/smtp"'
Or wire it into the AWS CLI as a credential_process:
[profile jam]
credential_process = jam-creds credential-process --name aws/deployer
Under the hood
- Language
- Rust 1.91+
- Async & HTTP
- Tokio · Axum · Hyper
- Crypto
- XChaCha20-Poly1305 (local-first) · AWS KMS envelope encryption · secrecy + zeroize
- AWS
- aws-sdk-sts · aws-sdk-kms · aws-esdk
- Storage
- SQLite (rusqlite, bundled)
- Interfaces
- clap CLI · egui dashboard · MCP (rmcp)
- Shape
- One Cargo workspace · 11 crates · 5 phases
- Tests
- 302 green (
make test,make lintclean). Six env-gated suites — LocalStack KMS, live-AWS canary, real-Keychain — are deferred sign-off items pending Docker / operator AWS credentials. - License
- Apache-2.0 · public on GitHub
- Platform
- macOS-first · Linux supported