chezmoi Integration¶
Encrypt secrets in your chezmoi dotfiles repo so they travel safely across
machines. chezmoi apply will automatically decrypt them.
Initial setup¶
This example encrypts a Claude Code settings file using chezmoi and nimvault.
# Navigate to the chezmoi source directory
cd ~/.local/share/chezmoi
# Create a vault config with your GPG key ID
mkdir -p .vault
echo "recipient = 9CCCE36402CB49A6" > .vault/config
# ^ replace with your key ID (gpg --list-keys --keyid-format long)
Add a secret¶
cd ~/.local/share/chezmoi
# Add a sensitive file to the vault
nimvault add ~/.claude/settings.json
# Added:
# id: e4a1f7c9b2d30856
# path: ~/.claude/settings.json
# blob: .vault/e4a1f7c9b2d30856.gpg
# Seal all entries (encrypts to .vault/*.gpg)
nimvault seal
# Commit the encrypted blobs
git add .vault/
git commit -m "vault: add claude settings"
git push
Automatic unseal on apply¶
Create a chezmoi run-before script that unseals the vault before applying
dotfiles. This runs every time you call chezmoi apply.
cat > ~/.local/share/chezmoi/.chezmoiscripts/run_before_unseal_vault.sh.tmpl << 'TMPL'
#!/bin/bash --norc
{{ if and (eq .setup_vault "yes") (eq .encrypted "yes") -}}
cd "{{ .chezmoi.sourceDir }}"
if command -v nimvault &>/dev/null && command -v gpg &>/dev/null; then
nimvault unseal 2>/dev/null || true
fi
{{ end -}}
TMPL
Add the template data to your chezmoi config. For .chezmoidata.toml:
[data]
setup_vault = "yes"
encrypted = "yes"
Or for .chezmoi.toml.tmpl (if using prompted config):
[data]
setup_vault = {{ promptString "Enable vault? (yes/no)" | quote }}
encrypted = {{ promptString "Encrypted? (yes/no)" | quote }}
Workflow on a new machine¶
# 1. Install nimvault
nimble install nimvault
# 2. Initialize chezmoi (pulls your dotfiles repo)
chezmoi init https://github.com/YOU/dotfiles.git
# 3. Apply -- the run-before script calls nimvault unseal automatically
chezmoi apply
# nimvault decrypts all vault entries to their target paths
Updating a secret¶
cd ~/.local/share/chezmoi
# Check what changed
nimvault status
# [modified] ~/.claude/settings.json
# Re-encrypt with updated content
nimvault seal
git add .vault/
git commit -m "vault: update claude settings"
git push
Removing a secret¶
cd ~/.local/share/chezmoi
nimvault rm ~/.claude/settings.json
# Removed e4a1f7c9b2d30856 (~/.claude/settings.json)
# The local plaintext file is NOT deleted
git add .vault/
git commit -m "vault: remove claude settings"
Migration from embedded vault.nim¶
If you previously used an inline scripts/vault.nim in your chezmoi repo:
Install nimvault globally (
nimble install nimvault)Add
.vault/configwith your recipient keyUpdate the run-before script to call
nimvault unsealinstead ofnim r scripts/vault.nim unsealRemove
scripts/vault.nimfrom the chezmoi repoThe
.vault/directory and blobs are unchanged: no re-encryption needed