feat: keep secrets in sync via age-encrypted master key (#208) #223

Merged
guettlibot merged 4 commits from issue-208-fix into main 2026-05-24 14:35:17 +00:00
guettlibot commented 2026-05-24 14:32:53 +00:00 (Migrated from codeberg.org)

Summary

  • Introduces an age-encrypted secrets.age file (committed to the repo) as a single source of truth for all production secrets
  • Only one secret needs to be stored in CI: SECRETS_AGE_KEY (the age private key)
  • When a secret changes locally, re-run scripts/secrets-encrypt.sh and commit the new secrets.age — CI gets the update on next push with no manual variable editing
  • The deploy workflow now has a single "Decrypt production secrets" step instead of N individual secret references

How to migrate

  1. Generate a key pair once: age-keygen -o ~/.config/age/sharedinbox.key && age-keygen -y ~/.config/age/sharedinbox.key > .age-public-key
  2. Copy secrets.env.example to secrets.env, fill in values
  3. Encrypt: scripts/secrets-encrypt.sh
  4. Commit secrets.age and .age-public-key
  5. Add the private key content to Codeberg as SECRETS_AGE_KEY secret

Test plan

  • bash scripts/test_secrets.sh passes (17 tests: encrypt/decrypt round-trip, multi-line values, GITHUB_ENV output, error cases)
  • Pre-commit hooks pass (all checks including detect-private-key)
  • CheckSecrets function added to Dagger Check() pipeline — runs in CI via task check-dagger
  • Deploy workflow uses SECRETS_AGE_KEY exclusively for production secrets; Dagger access creds unchanged

🤖 Generated with Claude Code

## Summary - Introduces an age-encrypted `secrets.age` file (committed to the repo) as a single source of truth for all production secrets - Only one secret needs to be stored in CI: `SECRETS_AGE_KEY` (the age private key) - When a secret changes locally, re-run `scripts/secrets-encrypt.sh` and commit the new `secrets.age` — CI gets the update on next push with no manual variable editing - The deploy workflow now has a single "Decrypt production secrets" step instead of N individual secret references ## How to migrate 1. Generate a key pair once: `age-keygen -o ~/.config/age/sharedinbox.key && age-keygen -y ~/.config/age/sharedinbox.key > .age-public-key` 2. Copy `secrets.env.example` to `secrets.env`, fill in values 3. Encrypt: `scripts/secrets-encrypt.sh` 4. Commit `secrets.age` and `.age-public-key` 5. Add the private key content to Codeberg as `SECRETS_AGE_KEY` secret ## Test plan - [ ] `bash scripts/test_secrets.sh` passes (17 tests: encrypt/decrypt round-trip, multi-line values, GITHUB_ENV output, error cases) - [ ] Pre-commit hooks pass (all checks including `detect-private-key`) - [ ] `CheckSecrets` function added to Dagger `Check()` pipeline — runs in CI via `task check-dagger` - [ ] Deploy workflow uses `SECRETS_AGE_KEY` exclusively for production secrets; Dagger access creds unchanged 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.