Skip to content

4. Age Encryption for Secrets Management

Date: 2024-12-10

Status

Accepted

Context

Dotfiles repositories often contain sensitive data that must be version controlled securely:

  • API tokens (GitHub, cloud providers)
  • SSH private keys (age keys, deployment keys)
  • Personal credentials

Requirements:

  1. Encryption at rest — Secrets must be encrypted in the Git repository
  2. Simple key management — Avoid GPG's complexity for personal use
  3. Chezmoi integration — Native support for seamless decryption
  4. Portability — Works across all target platforms (Linux, macOS, WSL2)

Alternatives considered:

  • GPG — Industry standard but overly complex for single-user dotfiles (keyservers, web of trust, etc.)
  • git-crypt — Transparent encryption but lacks fine-grained control
  • SOPS — Powerful but overkill for simple dotfile secrets

Decision

We have adopted age encryption for secrets management, integrated with Chezmoi.

Consequences

Positive

  • Simplicity — Single small key file (~/.config/chezmoi/key.txt), no keyserver infrastructure
  • Modern Cryptography — Uses ChaCha20-Poly1305, designed by the Go team for simplicity and security
  • Chezmoi Native — First-class integration via encrypted_ prefix for automatic decryption
  • Fast — Minimal overhead on chezmoi apply
  • Portable — Single binary, works everywhere, no dependencies

Negative

  • Single Point of Failure — Losing the key means losing access to secrets (mitigated by key backup in password manager)
  • No Key Rotation Built-in — Manual process required (addressed via mise run rotate-secrets)

Trade-offs

  • Simplicity vs Features — Chose minimal complexity over GPG's advanced features (multiple keys, signing, etc.)
  • Personal vs Team Use — Optimized for single-user dotfiles; team scenarios would need different approach

Implementation Details

Key Management

  • Key Location: ~/.config/chezmoi/key.txt
  • Key Generation: age-keygen -o ~/.config/chezmoi/key.txt
  • Backup Strategy: Store in password manager (1Password, Bitwarden, etc.)

Chezmoi Integration

Encrypted files use the encrypted_ prefix:

encrypted_dot_secrets.age → ~/.secrets (decrypted on apply)

Chezmoi automatically decrypts using the age key during chezmoi apply.

Secret Rotation

Automated via mise run rotate-secrets:

  1. Generate new age key
  2. Decrypt secrets with old key
  3. Re-encrypt with new key
  4. Backup old key with timestamp

See SECRETS.md for detailed procedures.

Security Considerations

  • Key Protection: Key file has 0600 permissions
  • Password Manager: Key backed up in encrypted vault
  • Rotation Schedule: Annual rotation recommended (see mise run doctor warning)
  • Git History: Encrypted files remain encrypted even in history

References