DOCUMENTATION HUB·LEVEL_2

Tier A Ops — Vercel Staging Checklist

REF_PATH: tier_a_vercel_staging_checklistSOURCE: APP_DOCUMENTS_DB

Tier A Ops — Vercel Staging Checklist

Branch: main · Reference: GA_OPEN_ROADMAP.md · Template: .env.example

Copy each variable into Vercel → Project → Settings → Environment Variables (scope: Preview and/or Production as appropriate). Never commit real values.


Required shells (populate in dashboard)

VariablePurposeExample shape (not real secrets)
DATABASE_URLPrisma + LangGraph checkpointer (pooled Supabase URL, port 6543, ?pgbouncer=true)postgresql://USER:PASS@HOST:6543/postgres?pgbouncer=true
DIRECT_URLMigrations / session pooler (port 5432)postgresql://USER:PASS@HOST:5432/postgres
IRONFRAME_CRON_SECRETBearer / x-cron-secret for POST /api/internal/cron/* (Vercel Cron + manual smoke)openssl rand -hex 32
PUBLIC_KEY_IDVault Supervisor PKI key id (must match dynamic PEM env suffix)vault-key-2026
PUBLIC_KEY_<NORMALIZED_ID>PEM SPKI for Gate A verify (PUBLIC_KEY_IDPUBLIC_KEY_VAULT_KEY_2026)-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----

PKI naming: vault-key-2026 normalizes to PUBLIC_KEY_VAULT_KEY_2026. Dev fallbacks: PUBLIC_KEY or VAULT_SUPERVISOR_PUBLIC_KEY (replace on staging).


Tier A — strongly recommended (same Vercel project)

VariablePurpose
NEXT_PUBLIC_SUPABASE_URLAuth + session (middleware)
NEXT_PUBLIC_SUPABASE_ANON_KEYSupabase anon / publishable key
GOOGLE_API_KEYSovereign bus / Ironquery RAG
NEXT_PUBLIC_APP_URLCanonical origin for Ironcast / transparency links
RESEND_API_KEYIroncast email dispatch
THREAT_CONFIRMATION_RECIPIENTSComma-separated alert inboxes
ELECTRICITY_MAPS_API_KEYIronwatch / carbon intensity
IRONFRAME_INTERNAL_GATES_SECRETMiddleware stale-lockdown / quarantine probes (optional; falls back to cron secret)

Vercel Cron routes (vercel.json)

Authenticated with Authorization: Bearer <IRONFRAME_CRON_SECRET> or header x-cron-secret: <IRONFRAME_CRON_SECRET>:

SchedulePath
0 9 1 * */api/internal/cron/carbon-budget-reallocation
0 6 * * */api/internal/cron/gridcore-rate-poll
*/30 * * * */api/internal/cron/health-posture-triage

Smoke (after deploy):

curl -sS -X POST "$APP_URL/api/internal/cron/health-posture-triage" \
  -H "Authorization: Bearer $IRONFRAME_CRON_SECRET"

Verification (local or CI)

npx tsc --noEmit
npx vitest run tests/integration/pki-verification.test.ts tests/integration/epic13-telemetry-triage.test.ts
npm run live-fire:telemetry-ingest   # requires local .env.local + npm run dev

Checkbox

  • DATABASE_URL + DIRECT_URL (Supabase staging)
  • IRONFRAME_CRON_SECRET (staging + production, distinct values)
  • PUBLIC_KEY_ID + matching PUBLIC_KEY_* PEM (no dev fallback strings in prod)
  • Supabase public keys + NEXT_PUBLIC_APP_URL
  • GOOGLE_API_KEY, RESEND_API_KEY, THREAT_CONFIRMATION_RECIPIENTS
  • Cron smoke: gridcore-rate-poll, health-posture-triage, carbon-budget-reallocation
  • PKI: npx vitest run tests/integration/pki-verification.test.ts