Secrets: - Add .sops.yaml with age encryption config - Add encrypted secrets.app.env (app secrets) and secrets.infra.env (Grafana OAuth) - CD decrypts at deploy time with AGE_SECRET_KEY — all other secrets move out of GitHub Actions into version-controlled encrypted files Split CD: - cd-apps.yml: triggered by apps/packages changes, builds Docker images, deploys apps - cd-infra.yml: triggered by infrastructure/ changes, copies configs, restarts services - Remove monolithic cd.yml Grafana auth: - GitHub OAuth (trails-cool org), disable login form - Remove Caddy basic_auth block and all GRAFANA_* env vars/secrets Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
758 B
758 B
ADDED Requirements
Requirement: Encrypted secrets in repository
Production secrets SHALL be stored as a SOPS-encrypted file in the repository, decryptable only with a single age private key.
Scenario: Edit secrets
- WHEN a developer runs
sops infrastructure/secrets.env - THEN the file is decrypted in a temporary editor, and re-encrypted on save
Scenario: CD decryption
- WHEN the CD workflow runs
- THEN the encrypted secrets file is decrypted using the AGE_SECRET_KEY GitHub secret and provided to docker-compose as an env file
Scenario: Secret audit trail
- WHEN a secret is changed
- THEN the change appears in git history as a diff of the encrypted file with a commit message describing what changed