Addresses spec drift items #3, 5, 6, 7, 8, 9, 10, 11, 12 from #147: - transactional-emails: Resend → Nodemailer + SMTP - infrastructure: CX21 → cx23 - secret-management: single secrets.env → split app/infra files - brouter-integration: 5s failover delay → instant via clientID election - brouter-integration: 2 profiles → 5 (trekking, fastbike, safety, shortest, car) - observability: add version field to health response - observability: add brouter_request_duration_seconds metric - planner-session: remove 30-day max ceiling (not enforced) - shared-packages: clarify map package scope vs planner-specific features Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
16 lines
937 B
Markdown
16 lines
937 B
Markdown
## Requirements
|
|
|
|
### Requirement: Encrypted secrets in repository
|
|
Production secrets SHALL be stored as SOPS-encrypted files in the repository, decryptable only with a single age private key. Secrets are split into two files: `secrets.app.env` (application secrets) and `secrets.infra.env` (infrastructure secrets).
|
|
|
|
#### Scenario: Edit secrets
|
|
- **WHEN** a developer runs `sops infrastructure/secrets.app.env` or `sops infrastructure/secrets.infra.env`
|
|
- **THEN** the file is decrypted in a temporary editor, and re-encrypted on save
|
|
|
|
#### Scenario: CD decryption
|
|
- **WHEN** the CD workflow runs
|
|
- **THEN** both encrypted secrets files are decrypted using the AGE_SECRET_KEY GitHub secret and merged at deploy time as env files for docker-compose
|
|
|
|
#### 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
|