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:
parent
206f6ac941
commit
57094323d2
15 changed files with 541 additions and 138 deletions
44
openspec/changes/sops-age-split-cd/proposal.md
Normal file
44
openspec/changes/sops-age-split-cd/proposal.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
## Why
|
||||
|
||||
Secrets are scattered across GitHub Actions secrets with no version control,
|
||||
no audit trail, and painful manual management (the Grafana password hash saga).
|
||||
The CD pipeline is monolithic — changing a Grafana dashboard rebuilds both app
|
||||
Docker images. And Grafana authentication requires managing bcrypt hashes and
|
||||
basic auth layers.
|
||||
|
||||
## What Changes
|
||||
|
||||
- **SOPS + age for secrets**: Encrypt a `.env.production` file in the repo.
|
||||
CD decrypts at deploy time with a single age private key stored as one
|
||||
GitHub secret. All other secrets move from GitHub Actions secrets into the
|
||||
encrypted file — version-controlled, diffable, auditable.
|
||||
- **Split CD into apps vs infra**: Two workflows triggered by path filters.
|
||||
App changes (apps/, packages/) build Docker images and deploy. Infra changes
|
||||
(infrastructure/) copy configs and restart services. No unnecessary rebuilds.
|
||||
- **GitHub OAuth for Grafana**: Replace Caddy basic auth + Grafana login with
|
||||
GitHub OAuth. One login, restricted to the trails-cool GitHub org. Remove
|
||||
GRAFANA_PASSWORD_HASH, GRAFANA_USER, GRAFANA_PASSWORD secrets entirely.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `secret-management`: SOPS + age encrypted secrets in the repository with
|
||||
CD decryption
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `infrastructure`: Split CD workflows, GitHub OAuth for Grafana, remove
|
||||
Caddy basic auth for Grafana
|
||||
|
||||
## Impact
|
||||
|
||||
- **Files**: New `.env.production.enc` (encrypted), `.sops.yaml` config,
|
||||
split `cd-apps.yml` and `cd-infra.yml` workflows, updated docker-compose.yml
|
||||
and Caddyfile
|
||||
- **Dependencies**: `sops` and `age` CLI tools in CD runner (install step)
|
||||
- **GitHub secrets**: Reduced from ~10 secrets to 2 (AGE_SECRET_KEY +
|
||||
DEPLOY_SSH_KEY). Everything else moves into the encrypted env file.
|
||||
- **Grafana**: GitHub OAuth app registration needed (Client ID + Secret go
|
||||
into the SOPS-encrypted file)
|
||||
- **Caddy**: Remove basic auth block for grafana.internal, just proxy through
|
||||
Loading…
Add table
Add a link
Reference in a new issue