Secrets Audit¶
Status of GH org-level secrets migration to Doppler oep project (BD-1.4 / UNI-53).
Classification Table¶
| Secret name | Source | Used by | Target Doppler path | Status | Owner | Deletable after |
|---|---|---|---|---|---|---|
DOPPLER_ADMIN_TOKEN |
GH org | CI terraform bootstrap; Doppler provider auth | keep-in-gh-forever | keep-forever | infra | never - bootstrap anchor |
DOPPLER_SERVICE_TOKEN_OEP_STG |
GH org | CI terraform (TF_VAR_doppler_service_token_oep_stg); ESO doppler-token-oep-stg K8s Secret |
keep-in-gh-forever | keep-forever | infra | never - ESO + CI Doppler auth chain |
DOPPLER_SERVICE_TOKEN_MANSETY_PRD |
GH org | CI terraform (TF_VAR_doppler_service_token_mansety_prd); ESO doppler-token-mansety-prd K8s Secret |
keep-in-gh-forever | keep-forever | infra | never - ESO + CI Doppler auth chain |
DOPPLER_SERVICE_TOKEN_US_PRD |
GH org | CI terraform (TF_VAR_doppler_service_token_us_prd); ESO doppler-token-us-prd K8s Secret |
keep-in-gh-forever | keep-forever | infra | never - ESO + CI Doppler auth chain |
SENTRY_AUTH_TOKEN |
GH org | App Platform build envs (TF_VAR_sentry_auth_token); legacy AWS pipeline CI |
oep.base.SENTRY_AUTH_TOKEN |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
DIGITALOCEAN_TOKEN |
GH org | Old CI TF plan/apply (TF_VAR_do_token, DIGITALOCEAN_TOKEN) |
oep.base.DIGITALOCEAN_TOKEN |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
CF_API_TOKEN |
GH org | Old CI TF plan/apply (TF_VAR_cf_api_token) |
oep.base.CLOUDFLARE_API_TOKEN (renamed to native CF provider env var) |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
SPACES_ACCESS_KEY |
GH org | Old CI S3 backend + TF provider (AWS_ACCESS_KEY_ID, TF_VAR_spaces_access_key) |
oep.base.SPACES_ACCESS_KEY_ID (canonical; AWS_ACCESS_KEY_ID references it) |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
SPACES_SECRET_KEY |
GH org | Old CI S3 backend + TF provider (AWS_SECRET_ACCESS_KEY, TF_VAR_spaces_secret_key) |
oep.base.SPACES_SECRET_ACCESS_KEY (canonical; AWS_SECRET_ACCESS_KEY references it) |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
ARGOCD_GITHUB_APP_ID |
GH org | Old CI TF apply (TF_VAR_argocd_github_app_id); Argo CD argocd-repo-creds-github K8s Secret |
oep.base.ARGOCD_GITHUB_APP_ID |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
ARGOCD_GITHUB_APP_INSTALLATION_ID |
GH org | Old CI TF apply (TF_VAR_argocd_github_app_installation_id) |
oep.base.ARGOCD_GITHUB_APP_INSTALLATION_ID |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
ARGOCD_GITHUB_APP_PRIVATE_KEY |
GH org | Old CI TF apply (TF_VAR_argocd_github_app_private_key); PEM-encoded RSA key |
oep.base.ARGOCD_GITHUB_APP_PRIVATE_KEY (heredoc-preserved newlines) |
migrated + GH-deleted | infra | after UNI-53 TF plan clean under doppler-run |
Final GH org secret count: 4 (DOPPLER_ADMIN_TOKEN + 3 DOPPLER_SERVICE_TOKEN_*).
Key rename mapping¶
| Old GH secret name | New Doppler key name | Reason |
|---|---|---|
CF_API_TOKEN |
CLOUDFLARE_API_TOKEN |
Matches Cloudflare provider native env var |
SPACES_ACCESS_KEY |
SPACES_ACCESS_KEY_ID (canonical) |
DO Terraform provider native env var; AWS_ACCESS_KEY_ID is a Doppler reference to it |
SPACES_SECRET_KEY |
SPACES_SECRET_ACCESS_KEY (canonical) |
Same; AWS_SECRET_ACCESS_KEY references it |
Spaces dual-key note¶
SPACES_* are the canonical keys (source of truth — rotate these). AWS_* are Doppler
references (${SPACES_ACCESS_KEY_ID} / ${SPACES_SECRET_ACCESS_KEY}) that resolve
automatically, so rotating SPACES_* propagates to all consumers with no extra steps.
| Key name | Type | Consumer |
|---|---|---|
SPACES_ACCESS_KEY_ID |
real value | DigitalOcean Terraform provider (spaces_access_id) |
SPACES_SECRET_ACCESS_KEY |
real value | DigitalOcean Terraform provider (spaces_secret_key) |
AWS_ACCESS_KEY_ID |
${SPACES_ACCESS_KEY_ID} reference |
TF S3 backend, Laravel S3 driver |
AWS_SECRET_ACCESS_KEY |
${SPACES_SECRET_ACCESS_KEY} reference |
TF S3 backend, Laravel S3 driver |
UNI-53 bootstrap seed script¶
See plan §5.2. Script reads values from terraform.tfvars (operator's local copy) and pushes
to Doppler oep.base via doppler secrets set KEY='value' --project oep --config base.
New constants added in Doppler oep.base (not previously in GH secrets):
AWS_ENDPOINT=https://ams3.digitaloceanspaces.comAWS_DEFAULT_REGION=ams3
BD-3 platform additions¶
Keys added to Doppler oep.base during BD-3 platform bootstrap. All consumed by ESO at runtime.
| Key | Consumer ticket | Rotation cadence | Owner | Notes |
|---|---|---|---|---|
CF_ORIGIN_CERT_UNIPUKA_APP |
BD-3.8 (TLS Secrets) | 15y (cert expiry 2041-04-01); reissue in CF dashboard | infra | Wildcard *.unipuka.app; rotate in Doppler then ESO syncs within refreshInterval |
CF_ORIGIN_KEY_UNIPUKA_APP |
BD-3.8 | Same as cert | infra | RSA-2048 private key |
CF_ORIGIN_CERT_MANSETY_COM |
BD-3.8 | 15y (expiry 2041-05-19) | infra | Wildcard *.mansety.com |
CF_ORIGIN_KEY_MANSETY_COM |
BD-3.8 | Same as cert | infra | RSA-2048 private key |
CF_ORIGIN_CERT_US_ACADEMY_NET |
BD-3.8 | 15y (expiry 2041-05-19) | infra | Wildcard *.us-academy.net |
CF_ORIGIN_KEY_US_ACADEMY_NET |
BD-3.8 | Same as cert | infra | RSA-2048 private key |
LOKI_SPACES_KEY |
BD-3.12 (Loki) | 90 days or on compromise | infra | Scoped to unipuka-loki-logs bucket; rotate in DO dashboard + update Doppler + restart Loki pods |
LOKI_SPACES_SECRET |
BD-3.12 | Same as key | infra | Single shared keypair for all tenant logs (multi-tenancy via X-Scope-OrgID) |
ARGOCD_ADMIN_PASSWORD |
BD-3.5/BD-3.14 (Argo CD break-glass) | On engineer offboarding or annually | infra | Plain; bcrypt hash stored separately; use only via port-forward |
ARGOCD_ADMIN_PASSWORD_BCRYPT |
BD-3.5 (argocd-secret patch) | With ARGOCD_ADMIN_PASSWORD |
infra | $2a$10$... format; Argo CD reads this directly |
GRAFANA_ADMIN_PASSWORD |
BD-3.11 (Grafana break-glass) | On engineer offboarding or annually | infra | Plain; use only via port-forward |
CF_TEAM_NAME |
BD-3.14 (Argo OIDC config) | Static (CF team name rarely changes) | infra | Value: unipuka |
CF_ACCESS_GOOGLE_IDP_UUID |
BD-3.14 (CF Access policy) | Static (IdP UUID doesn't change) | infra | Google Workspace IdP UUID |
ARGOCD_CF_ACCESS_CLIENT_SECRET |
BD-3.14 (Argo OIDC clientSecret) | Populated mid-BD-3.14 after Access app applied | infra | From CF Access app OIDC client_secret endpoint |
UNI-54 import drift (post-populate)¶
After doppler secrets upload of per-tenant .env files, expected drift between AWS-era source
.env and the populated Doppler configs (Class-1 keys substituted with DO equivalents):
| Key | AWS source | DO target |
|---|---|---|
DB_HOST |
RDS endpoint | DO Managed MySQL private host (*.b.db.ondigitalocean.com) |
DB_PORT |
3306 | 25060 |
DB_USERNAME |
soa_rds_user |
app (DO-created user) |
DB_PASSWORD |
RDS master password | DO-generated password |
DB_DATABASE |
per-tenant | same (unchanged) |
REDIS_HOST |
ElastiCache endpoint | DO Managed Redis private host |
REDIS_PORT |
6379 | 25061 |
REDIS_PASSWORD |
empty / auth token | DO-generated password |
AWS_BUCKET |
S3 bucket name | DO Spaces bucket name (same naming convention) |
AWS_PUBLIC_BUCKET |
S3 public bucket | DO Spaces public bucket |
AWS_DEFAULT_REGION |
eu-central-1 |
ams3 |
AWS_ACCESS_KEY_ID |
AWS IAM key | DO Spaces key (same key name, sourced from base) |
AWS_SECRET_ACCESS_KEY |
AWS IAM secret | DO Spaces secret (same key name, sourced from base) |
AWS_ENDPOINT |
(absent) | https://ams3.digitaloceanspaces.com (new, sourced from base) |
BD-4 secrets validation¶
Date: June 2026 Conclusion: BD-4 adds no new Doppler keys. No Doppler changes required.
The laravel-app Helm chart (BD-4) consumes secrets exclusively via ExternalSecret bulk-pull
(dataFrom: - extract: key: "/"). All required keys already exist in Doppler from BD-1.5:
| Class | Keys re-validated | Doppler envs |
|---|---|---|
| Class-1 | DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASE, REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, AWS_BUCKET, AWS_PUBLIC_BUCKET |
oep-stg, mansety-prd, us-prd |
| Class-3 | APP_KEY, APP_ENV, APP_NAME, BUGSNAG_API_KEY, SENTRY_LARAVEL_DSN, REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET, HORIZON_PREFIX |
oep-stg, mansety-prd, us-prd |
Validation script: scripts/bd4-preflight.sh - check 9 (Doppler config key count >= 45), check 10 (Class-1 DB/Redis/Spaces keys present), check 11 (Class-3 app runtime keys present).
Cross-link: bd4-prereqs-checklist.md