Secrets
This is the part most dotfile tools get wrong, so it is worth reading properly.
The rule
Secrets never touch git. You declare which values are secret; envkit moves them
into the OS keychain on backup and leaves a placeholder in the store. Your shell
fetches them at startup from the keychain, so no plaintext lands in your dotfiles
or your repository.
The keychain is macOS Keychain on darwin, and pass on Linux.
Declaring one
[[file]]
path = ".zshrc"
kind = "shell"
secrets = ["GITHUB_TOKEN"]
On the next backup, envkit lifts the value out of .zshrc, stores it in the
keychain, and writes a placeholder into the store copy. Your shell sources a
generated ~/.config/envkit/secrets.zsh that calls envkit secret get.
That generated file is never committed.
Managing values directly
envkit secret list # names only, never values
envkit secret get GITHUB_TOKEN
envkit secret set GITHUB_TOKEN # prompts, input hidden
envkit secret rm GITHUB_TOKEN
To store a value non-interactively, pipe it in — this keeps it out of your shell
history and out of ps:
printf %s "$VALUE" | envkit secret set GITHUB_TOKEN
Running a command with secrets injected
envkit exec GITHUB_TOKEN -- gh pr list
envkit exec GITHUB_TOKEN:GH_TOKEN -- some-tool # rename on the way in
Prefer this over export — the value exists only for that process.
secret get is fail-soft, and why that matters
A missing key prints a warning and returns an empty string with exit code 0. That is deliberate: a typo in a key name must not break shell startup and lock you out of your terminal.
The trap: an empty return looks exactly like a working call. If a script silently
gets "", check the key exists with envkit secret list before concluding the
store is broken.
A genuine keychain error — a locked keychain, a broken pass — exits non-zero,
so automation still fails loudly on real faults.
The undeclared-secret scan
On backup, envkit scans tracked files for things that look like secrets you did
not declare, and refuses rather than committing one by accident.
envkit backup --allow-unmanaged # override for this run
Or mark a file noscan = true if it trips the scanner repeatedly for good reason.
Moving secrets between machines
The keychain is per-machine, so load restores your files but not your secrets.
Set them on the new machine:
envkit secret set GITHUB_TOKEN
envkit doctor --secrets reads every indexed key and reports the ones with no
value, so you can see what still needs setting rather than discovering it when
something breaks. Plain doctor deliberately skips this: it costs one keychain
read per key and may prompt.