- Activity Log: new entry for AMN Pay Scanner implementation - Environment Variables: document AMN_SCANNER_URL, AMN_SCANNER_WEBHOOK_SECRET, AMN_SCANNER_DEFAULT - PRD status table: mark all components implemented
3.0 KiB
TODO: Secret Management Overhaul + Deploy Migration
Status: Deferred — created 2026-05-29 Owner: infra / nick Trigger: discovered while wiring Telegram startup notifications (2026-05-29)
A dedicated pass to (a) rotate every secret that has lived in git, (b) move secrets out of committed files into the right injection layer, and (c) collapse the two-stack deploy split. All dev data is disposable (no data-migration concern).
1. Rotate secrets (all have been committed in git → treat as compromised)
Rotate at the provider, then place per the build-vs-runtime split (decided 2026-05-29).
→ Runtime (live-stack env injection):
JWT_SECRET(rotation logs everyone out — fine)MONGODB_URIpassword +MONGO_INITDB_ROOT_PASSWORD(same value)REDIS_URIpasswordADMIN_PASSWORDGOOGLE_CLIENT_SECRET(Google Cloud Console)SMTP_PASS(Resend dashboard — revoke + new API key)REQUEST_NETWORK_API_KEY(RN dashboard)REQUEST_NETWORK_WEBHOOK_SECRET(+ update RN webhook config)TELEGRAM_BOT_TOKEN(Mini App bot — @BotFather /revoke)TELEGRAM_WEBHOOK_SECRET_TOKEN(+ re-set on Telegram setWebhook)TG_NOTIFY_BOT_TOKEN(amnGG_MonitorBot — already a dedicated bot; rotate if desired)
→ Build-time (frontend Woodpecker secret, baked into image):
NEXT_PUBLIC_ALCHEMY_API_KEY_*(one secretalchemy_api_keyfeeds all 3 args) — rotate in Alchemy and domain-restrict to dev.amn.gg (it ships in the browser bundle, so the origin allowlist is the real protection).
Public by design — no rotation: Google client IDs, NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID (domain-restrict instead), NEXT_PUBLIC_TELEGRAM_BOT_ID, wallet addresses, REQUEST_NETWORK_MERCHANT_REFERENCE, URLs/flags.
2. Strip secrets from committed files
backend/.env.example— currently holds live values; reduce to reference-only (keys + non-secret defaults). Safe: it is docs-only, not read at runtime.frontend/.env.production— same; not copied into the runtime image by the Dockerfile.- Remove the gitleaks token allowlists once tokens are gone.
3. Collapse the two-stack deploy split
See deploy_architecture_two_stacks (memory). Make escrow-deploy (gitops from nick/deploy) the canonical live stack; retire devEscrow; point the Woodpecker redeploy step at escrow-deploy (8cbe7b2a…) so sync + redeploy target the same project. This also fixes the cosmetic redeploy 400.
- Pending local edits already staged for this in
~/CascadeProjects/escrow/deployment(uncommitted):TG_NOTIFY_BOT_TOKEN+TG_NOTIFY_CHATSadded to.envand wired into both serviceenvironment:blocks indocker-compose.yml. - Container names are identical across both stacks → cutover has a brief collision/downtime window (acceptable; test data).
Injection model (decided)
- Build-time
NEXT_PUBLIC_*→ Woodpecker secrets (frontendbuild_args). - Runtime secrets → live-stack env (deploy-repo
.envonceescrow-deployis canonical).