Secrets workflow: sops+age primary, Doppler ALONGSIDE for runtime sync (hybrid)
Secrets workflow — sops+age primary, Doppler for runtime sync
Decision
Two-layer setup:
Source of truth:
.env(gitignored, local) +.env.enc(sops+age encrypted, committed).envhas 326 lines, 134 comments, grouped sections ("# === Cloudflare ===" / "# === Firebase ===" etc.). This structure has real navigational value with 65 keys.- Age key lives in Bitwarden CLI (
bw get item age-key); never committed. - Frequent edits happen on the local
.envdirectly. Periodic snapshot:sops -e .env > .env.enc && git commit.
Runtime sync to GitHub Actions: Doppler ALONGSIDE
- One Doppler project, one config, one GitHub Actions sync with
sync_target=orgpointing atoriz-orgwithvisibility=all. This stays within the free-tier 5-sync cap. - After a local
.envedit, rundoppler secrets upload .env --silentto refresh Doppler. Doppler then auto-pushes to every oriz-org/* repo's secrets. - Replaces the daily
sync-env-to-org-secrets.ymlworkflow (one less moving piece in the umbrella).
- One Doppler project, one config, one GitHub Actions sync with
Why not Doppler as source of truth
Doppler's secret store is a flat key-value map. It does not preserve:
- Comments (134 in our .env)
- Section ordering
- Blank-line separators
- Heredoc multi-line values
For a 65-key .env with section grouping, this is a real loss. The dashboard's tag/search features partially compensate but can't recreate inline # === Section === headers.
Why not pure sops+age (status quo)
Frequent .env edits today require encrypt + commit + workflow run + 65 GitHub Actions API calls. Doppler's doppler secrets upload is a single command that auto-fans-out via the integration — zero extra commits, faster CI propagation, browser editing as a fallback.
Why not delete oriz-org and run pure-personal
Doppler's GitHub integration has only sync_target = org | repo. No user target. Going personal-only would force 75 repo-level syncs ? blow past the 5-sync free-tier cap ? forced onto Team plan ($21/user/mo, $252/year) ? violates [[no-card-on-file]]. This is the load-bearing reason oriz-org stays alive. See research workflow wf_a4581bfc-18c (2026-06-24).
Audit / rotation triggers (when to revisit)
This workflow stays locked unless:
- A second human needs workspace access (Doppler free tier covers 3 users, friction lower than handing them an age key)
- Auto-rotation matters (AWS IAM keys, DB passwords) — Doppler offers it on Team tier ($21/user/mo); evaluate when first credential gets compromised
- Doppler's free tier changes materially (track via the pricing page)
Cross-refs
- env single-source rule: [[security/env-single-source-auto-push]]
- Org-level secrets rule: [[rules/org-level-secrets-only-no-per-repo]]
- No-card-on-file constraint: [[rules/no-card-on-file]]
- The org we depend on: [[branding/oriz-org-rename-from-co]]