Headless & CI
kovra’s defaults assume a human at a Mac: the master key in the Keychain, and sensitive actions gated behind a bioProve. Unattended environments — CI runners, containers — have neither. kovra runs there too, in passphrase mode.
Passphrase mode (no keyring)
Section titled “Passphrase mode (no keyring)”Set KOVRA_PASSPHRASE and kovra stops using the OS keyring entirely: it derives
the 256-bit master key with Argon2id from your passphrase plus a stable,
non-secret salt stored next to the vault (kdf.salt). Initialize the vault once
to create the salt, then every later run derives the same key:
export KOVRA_PASSPHRASE="$CI_VAULT_PASSPHRASE" # from your CI secret storekovra initKeep the passphrase in your CI provider’s secret store — it is the only thing that unlocks the vault, so treat it like the master key it derives.
Confirmations need the Mac’s desktop
Section titled “Confirmations need the Mac’s desktop”A bioProve needs a person at the Mac. kovra 0.12.1 ships for
macOS, and there every approval is read and approved in kovra’s review window: the Touch
ID sensor inside it, or a code and the macOS dialog with your login password when the Mac
has no Touch ID (or it isn’t set up). In CI, over SSH, or anywhere without a graphical
session, that window can’t be shown: with a paired phone, the request goes to kovra’s
approval app on it (kovra Mobile, coming soon), where a person approves or denies it; with no paired phone, anything
that needs an approval is refused, with a message saying so. The master key and the
pairing are approved only at the Mac. kovra never falls back to an approval a
script or an agent could give itself, and KOVRA_CONFIRMER doesn’t change that on a Mac
(it only applies to development builds).
This has a deliberate consequence: high/prod actions can’t be automated — they
require a person, at the Mac or on the paired phone, by design. So in CI:
low/mediumsecrets inject with no prompt — the everyday CI path:kovra runwithouthigh/prodvalues works unattended.- Anything that needs an approval — injecting a
high/prodvalue, deleting or downgrading a critical secret — is refused, unless a person approves it on the paired phone. There’s no unattended bypass forkovra run; run it from the Mac’s desktop.
The Dashboard’s launch gate can be skipped for dev/CI/containers with --no-confirm
(or KOVRA_UI_NO_CONFIRM=1).
A GitHub Actions sketch
Section titled “A GitHub Actions sketch”jobs: test: runs-on: [self-hosted, macos] env: KOVRA_PASSPHRASE: ${ secrets.KOVRA_VAULT_PASSPHRASE } steps: - uses: actions/checkout@v4 - name: Run tests with injected secrets run: kovra run --env dev -- npm testkovra run --env dev resolves the committed .env.refs and injects the dev
(non-high) values straight into npm test — nothing written to disk, argv, or
the log.