Quick start
This walks you from an empty machine to a secret that your tools can use but never see. It assumes you’ve installed kovra.
kovra 0.12.1 ships for macOS, so the commands below are shown in a macOS terminal; Windows is coming soon — see Platform support.
1. Initialize the vault
Section titled “1. Initialize the vault”~/my-app % kovra initInitialized vault at ~/.vaults (OS keyring).This creates the vault registry and a per-vault master key, custodied in the macOS Keychain. The master key encrypts every entry at rest; you never handle it directly.
2. Store a secret
Section titled “2. Store a secret”Secrets are addressed by a coordinate of the form
secret:<env>/<component>/<key>. kovra reads the value from a hidden prompt —
it never appears in argv or your shell history:
~/my-app % kovra add secret:dev/db/passwordAdded dev/db/password (Medium).(Scripting? Pipe the value in with kovra add secret:dev/db/password --stdin.)
With no --sensitivity flag a secret is born medium; you can set a tier and a
description explicitly:
~/my-app % kovra add secret:dev/app/api-key --description "App API key"Added dev/app/api-key (Medium).List what’s stored — metadata only, never values:
~/my-app % kovra list┌────────┬─────────────────┬─────────────┬─────────┬─────────────┐│ ORIGIN ┆ COORDINATE ┆ SENSITIVITY ┆ MODE ┆ FINGERPRINT │╞════════╪═════════════════╪═════════════╪═════════╪═════════════╡│ global ┆ dev/app/api-key ┆ medium ┆ literal ┆ c8a476b5 │├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤│ global ┆ dev/db/password ┆ medium ┆ literal ┆ 73c128b4 │└────────┴─────────────────┴─────────────┴─────────┴─────────────┘The fingerprint is a short, truncated hash — enough to confirm “same value as
before”, never enough to reconstruct it. Critical values — high, inject-only and
anything in prod — show — instead: not even a truncated hash. Filter with kovra list --env dev or
--component app.
If you ever need a value back at a terminal, kovra show reveals exactly one
coordinate. An ordinary secret prints straight away:
~/my-app % kovra show secret:dev/db/password(revealing dev/db/password to stdout — ephemeral, not stored)dev-db-pw-•••••A high or prod secret first asks for a bioProve (Touch
ID, or your login password on a Mac without it); see
step 3. The most protected secrets
(inject-only) are never revealed at all — they can only be injected.
3. Inject secrets into a process
Section titled “3. Inject secrets into a process”Tools shouldn’t read the vault directly — they get values through injection.
You describe the mapping once in a committable .env.refs file that holds
addresses, not values:
# .env.refs — safe to commit; contains no secret values.project = my-app
# Vault-backed, parameterized by --env (${ENV} is substituted at run time).DATABASE_URL=secret:${ENV}/db/passwordAPI_KEY=secret:${ENV}/app/api-key
# Passthrough from the environment, with a fallback if unset.LOG_LEVEL=${env:LOG_LEVEL | info}
# A plain literal (not a secret).PORT=8080Then run any command with the resolved values injected straight into the child process — nothing is written to disk, argv, or shell history:
~/my-app % kovra run --env dev -- your-appapp started · DATABASE_URL=14 chars · API_KEY set=yes · PORT=8080With --env dev, ${ENV} resolves to dev, so DATABASE_URL is read from
secret:dev/db/password. The values land in your app’s environment and nowhere
else.
Production adds two guards
Section titled “Production adds two guards”Switch the environment to prod and the same command is held to a higher bar — a
prod secret is born high, and a high/prod injection is governed by two
independent guards: it must target an allowlisted executable, and it pauses
for an bioProve. Run it against an un-reviewed program
and kovra refuses, by design:
~/my-app % kovra run --env prod -- your-appError: `your-app` is not on the executor allowlist; high/prod injection refusedAllowlist the reviewed executable with --allow and bioProve
(one confirmation covers every secret in the run):
~/my-app % kovra run --env prod --allow ./deploy -- ./deploy# Touch ID prompt — approve to inject prod/db/password, prod/app/api-keydeploying with DATABASE_URL=12 chars, API_KEY set=yesNot sure what your repo needs? Let kovra propose an .env.refs by scanning your
source for env-var references (it reads variable names only — never a value):
~/my-app % kovra scaffold --out .env.refsWrote 2 proposed coordinate(s) to .env.refs — review before use.4. Wire up Claude Code
Section titled “4. Wire up Claude Code”Onboard the current repo so an AI agent can use your secrets without seeing the sensitive ones:
~/my-app % kovra setupVault ready; project `my-app`.Updated .mcp.json (register the kovra MCP server).Updated CLAUDE.md (insert/update the kovra conventions block).Updated .claude/settings.json (deny Read of secrets files).Updated .claude/settings.local.json (install the credential gate's Claude Code hooks).Credential gate: Claude Code now asks kovra before a prompt or a tool output reaches the model (it reloads hooks on its own). Notes: - Hooks fail closed on a crash only from Claude Code 2.1.295 (`onFailure`). - Recommended: set CLAUDE_CODE_DISABLE_FILE_MENTIONS=1 in your user settings (~/.claude/settings.json, "env") or your shell (Claude Code 2.1.299+). Then @file mentions go through Read and the gate. Project settings ignore it, so kovra setup does not write it.kovrad: registered to run at login.Setup complete. Review CLAUDE.md and .mcp.json, then reload your agent to pick up the MCP server.This registers the kovra MCP server in ./.mcp.json and adds a conventions
block to ./CLAUDE.md. From then on, Claude Code sees scoped metadata — that
a secret exists, its sensitivity, its coordinate — and can run commands through
the wrapper, but the plaintext of your high / prod / inject-only secrets
never enters the model’s context.
On macOS it also installs the credential gate: Claude Code asks kovra before a prompt or a tool output reaches the model, so a credential you paste is blocked and one a tool returns is redacted.
Preview the changes without writing anything with kovra setup --dry-run.
Where to go next
Section titled “Where to go next”You now have the full loop: store → inject → delegate to an agent, with the sensitive plaintext never leaving the vault. From here:
- Overview — the concepts map: coordinates, sensitivity tiers,
agent scope, and the
.env.refscontract. - How it works — the everyday flows end to end, at a high level.
- Secrets in the age of AI Agents — kovra’s whitepaper: the problem, the tensions, the solution, and an honest account of kovra’s risks and limitations.