Skip to content

Tutorial — a real project

The quick start is the five-minute tour. This is the longer one: we take a small service — call it billing-api, with a database and a payment API key — from a plain .env all the way to running it through kovra and letting an AI agent work on it without ever seeing the sensitive secrets.

It assumes kovra is installed. Every box has an OS selector; the outputs shown are from macOS.

From the project directory, create the vault and its master key:

zsh
~/billing-api % kovra init
Initialized vault at ~/.vaults (OS keyring).

Say today the app reads a .env with a database password and a payment key. Put those values into the vault instead — kovra reads each from a hidden prompt, so it never lands in argv or your shell history:

zsh
~/billing-api % kovra add secret:dev/db/password
Added dev/db/password (Medium).
zsh
~/billing-api % kovra add secret:dev/app/api-key --description "Stripe test key"
Added dev/app/api-key (Medium).

Now do the same for production. You don’t have to mark these specially — a prod secret is born high automatically, so it can never be silently revealed:

zsh
~/billing-api % kovra add secret:prod/db/password
Added prod/db/password (High).

List what you’ve stored — metadata only, never values:

zsh
~/billing-api % kovra list
┌────────┬─────────────────┬─────────────┬─────────┬─────────────┐
│ ORIGIN ┆ COORDINATE ┆ SENSITIVITY ┆ MODE ┆ FINGERPRINT │
╞════════╪═════════════════╪═════════════╪═════════╪═════════════╡
│ global ┆ dev/app/api-key ┆ medium ┆ literal ┆ c8a476b5 │
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ global ┆ dev/db/password ┆ medium ┆ literal ┆ 73c128b4 │
└────────┴─────────────────┴─────────────┴─────────┴─────────────┘

Delete the plaintext .env and commit a .env.refs instead. It maps the same variable names to coordinates — addresses, not values — so it’s safe in git:

# .env.refs — safe to commit; no secret values.
project = billing-api
DATABASE_URL=secret:${ENV}/db/password
API_KEY=secret:${ENV}/app/api-key
LOG_LEVEL=${env:LOG_LEVEL | info}
PORT=8080

Not sure what your code needs? kovra scaffold --out .env.refs proposes one by scanning your source for env-var names (never a value).

Start the app through kovra. It resolves the .env.refs, looks up each value, and injects them straight into the process — nothing written to disk, argv, or history:

zsh
~/billing-api % kovra run --env dev -- your-app
app started · DATABASE_URL=14 chars · API_KEY set=yes · PORT=8080

The app has its real configuration; the secrets were used, not seen.

Point the same command at prod and kovra holds it to a higher bar. A prod value is high, and a high/prod injection has two independent guards: it must target a reviewed, allowlisted executable, and it pauses for a bioProve. Run it against an un-reviewed program and kovra refuses, by design:

zsh
~/billing-api % kovra run --env prod -- your-app
Error: `your-app` is not on the executor allowlist; high/prod injection refused

Allowlist the reviewed deploy tool with --allow and approve the prompt — one bioProve covers every secret in the run:

zsh
~/billing-api % kovra run --env prod --allow ./deploy -- ./deploy
# bioProve to inject prod/db/password, prod/app/api-key
deploying with DATABASE_URL=12 chars, API_KEY set=yes

For a brand-new secret — a session signing key — don’t invent and paste one. Have kovra generate it server-side; the value exists only inside the vault, never on your screen:

zsh
~/billing-api % kovra generate secret:dev/app/session-secret --length 48
Generated dev/app/session-secret (48 chars, Medium) — value stored, not shown.

Now the payoff. Onboard the repo so a coding agent can work with these secrets safely:

zsh
~/billing-api % kovra setup
Vault ready; project `billing-api`.
Updated .mcp.json (register the kovra MCP server).
Updated CLAUDE.md (insert/update the kovra conventions block).
Setup complete. Review CLAUDE.md and .mcp.json, then reload your agent to pick up the MCP server.

From here, your agent can see that dev/db/password and dev/app/api-key exist, reason about the project, and run your tests with the values injected — but the plaintext of your high/prod/inject-only secrets never enters its context. Ask it to read the prod key and it’s refused, full stop. See kovra over MCP for exactly what the agent can and can’t do.

Finally, a backstop for the day someone pastes a real value into a file by mistake. Install the pre-commit hook:

zsh
~/billing-api % kovra hooks install
Wrote ./.gitleaks.toml
Installed the gitleaks pre-commit hook at ./.git/hooks/pre-commit.

Now a commit that would leak a secret is blocked before it enters history.

billing-api now keeps no plaintext secrets in the repo or the environment. Developers and agents run it through kovra; dev is frictionless, production is gated and attributable, and the sensitive values never leave the vault. From here: