SOPS+age secrets, split CD workflows, GitHub OAuth for Grafana

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>
This commit is contained in:
Ullrich Schäfer 2026-03-27 16:56:01 +01:00
parent 206f6ac941
commit 57094323d2
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9
15 changed files with 541 additions and 138 deletions

View file

@ -0,0 +1,27 @@
## MODIFIED Requirements
### Requirement: CI/CD pipeline
GitHub Actions SHALL use separate workflows for app deployment and infrastructure deployment, with secrets decrypted from a SOPS-encrypted file.
#### Scenario: App deployment
- **WHEN** code changes are pushed to main in apps/ or packages/
- **THEN** the cd-apps workflow builds Docker images, pushes to ghcr.io, and deploys app containers
#### Scenario: Infrastructure deployment
- **WHEN** changes are pushed to main in infrastructure/
- **THEN** the cd-infra workflow copies configs and restarts infrastructure services without rebuilding app images
#### Scenario: Secret decryption at deploy time
- **WHEN** either CD workflow runs
- **THEN** the SOPS-encrypted secrets file is decrypted and provided to docker-compose as an env file
### Requirement: Grafana authentication
Grafana SHALL authenticate users via GitHub OAuth, restricted to the trails-cool GitHub organization.
#### Scenario: GitHub OAuth login
- **WHEN** a user navigates to grafana.internal.trails.cool
- **THEN** they are redirected to GitHub for authentication and granted access if they are a member of the trails-cool organization
#### Scenario: No password-based login
- **WHEN** Grafana is deployed
- **THEN** the login form is disabled and only GitHub OAuth is available