Modular secrets provider + dev/runtime environment bootstrapper. One committable
manifest describes the shape of a project's secrets — where each value comes
from and where it lands on a machine — and envkit sync materializes it
anywhere: desktop, headless box, or CI. Values never touch the repo.
providers ──▶ policy ──▶ stores/targets
rbw · bw · aws-sm · generate · keyring (Secret Service) · systemd-creds (TPM) ·
detect · check · exec plugins .env files (monorepo multi-output) · process env
(v0.2: keychain, SSO login) (v0.3: AF_UNIX broker + systemd LoadCredential)
Adding a provider is ~60 lines of Go plus one registry line — or a standalone
envkit-provider-<name> binary with no envkit changes at all. See
docs/providers.md.
One committed file is the whole configuration: the team shares it, and any
machine with the referenced providers installed fetches from the same
locations. Personal deviations live in the gitignored envkit.local.toml
(same shape — store/creds-dir overrides, provider overrides, static extras).
~/.config/envkit/config.toml is optional user defaults; nothing requires it.
version = 1
[providers.aws-sm] # committed provider settings — the common
profile = "my-team-dev" # locations everyone reads from
region = "us-west-2"
[[secret]]
name = "api-key"
from = "rbw:myapp/api-key" # provider:ref — rbw | generate | detect | check | any envkit-provider-* plugin
to = "keyring:service=myapp,type=api-key" # transparently a TPM systemd-cred on headless machines
env = "MYAPP_API_KEY" # exposure name for `envkit run` / `envkit export`
need = "required" # required | optional | one-of:<group>
[[secret]]
name = "db-password"
from = "generate:hex32" # generated once per machine, NEVER regenerated (even --force)
to = "env:DB_PASSWORD@back-end/.env"
[[envfile]] # monorepo outputs: many .env files from one manifest
path = "back-end/.env"
[envfile.static]
NODE_ENV = "development"envkit sync |
materialize everything; --check dry-run, --force re-pull (generate-once values are never touched) |
envkit check |
readiness report; exit code reflects it (0 ready · 1 missing · 3 auth needed) |
envkit get NAME |
print one secret from local stores (keyring→creds→env fallback); --pull reaches the provider |
envkit run -- CMD |
exec with the manifest environment |
envkit export --format fish |
shell eval |
envkit init |
scaffold; --import pipe-manifest FILE translates a legacy manifest |
envkit rotate NAME |
re-pull one value; --regenerate for generate-once, with confirmation |
envkit doctor |
stores, providers, domain, repo hygiene (gitignore + file modes) |
- Shape, never values: no manifest field accepts a secret literal.
- Config is scoped to the project, not the machine: envkit.toml (committed, shared) > envkit.local.toml (gitignored, personal) > flags. Account boundaries live where they really are — in which vaults/profiles each machine's providers are logged into — not in tool-enforced labels.
- Never block headless: locked vaults degrade to a readiness report with a
remedy hint; prompting happens only in
envkit login. - Store auto-detection: keychain on macOS, keyring in a display session,
TPM-sealed
systemd-creds --useron headless Linux. - Provider modularity: built-ins behind one interface, plus exec plugins —
any
envkit-provider-<name>on PATH (JSON-in, bytes-out; seeinternal/provider/execplugin).
Roadmap: internal/broker/DESIGN.md (LoadCredential broker), aws-sm provider +
.env-setup.json compat (v0.2).
Apache-2.0.