type: service
status: active
timestamp: 2026-06-24
tags: [service, security, encryption, age, sops-backend]

age — modern file encryption (X25519 + ChaCha20-Poly1305)

Modern file encryption (X25519+ChaCha20-Poly1305) — SOPS master-key backend, single key file

age — modern file encryption

What it is

A 2019-era file-encryption tool by Filippo Valsorda (Go-language cryptographer, ex-Google, ex-Cloudflare). Designed as a modern replacement for gpg --encrypt with a minimal feature set.

Why we use it (instead of PGP/KMS)

ConcernageGPGAWS KMS
Setup time30 sec (age-keygen)30 min (keyring + web of trust)hours (IAM + KMS policies)
Cloud dependencyNoneNoneAWS account
Failure modesLose the key fileGPG agent issues, expired subkeys, web-of-trust corruptionIAM misconfig, KMS region outage, billing
Cost$0$0$0.03 / 10K decrypt requests
Multi-recipientYes (additive)Yes (additive)Yes (KMS grants)
Offline decryptionYes, foreverYes, foreverRequires AWS reachable

For a solo dev with no compliance requirement, age wins on simplicity. The cost is real but small: it has no integration with hardware tokens, no revocation list, no formal trust model. Trade-offs we accept.

Our setup

Where the keys live:

Generate (one-time, only if rotating):

age-keygen -o ~/.config/sops/age/keys.txt    # generates new keypair
# Copy the public age1... line into .sops.yaml
# Copy the AGE-SECRET-KEY-1... into Bitwarden CLI

On a fresh machine:

bw get item age-key | jq -r .notes > ~/.config/sops/age/keys.txt
export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt
# Now sops -d works in any submodule

CI (GitHub Actions):

- name: Decrypt secrets
  env:
    SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}    # the private key as a single env var
  run: sops decrypt -i .env.enc

Key rotation

Rotation is a Bitwarden CLI update + a re-encrypt of every .env.enc family-wide. ~5 min if all submodules are cloned locally. We have not rotated yet (and have no scheduled rotation) — the cost of a real rotation only justifies if the current key is suspected compromised. See [[runbooks/rotate-age-key]] (write when first needed).

Anti-patterns


Edit on GitHub · Back to index