Skip to main content
This page documents secret names and configuration boundaries. It does not contain secret values.

General Rules

  • Store hosted deployment credentials in environment-scoped GitHub Actions secrets.
  • Store Vercel app runtime and build-time configuration in the Vercel project environment, not workflow-wide GitHub Actions environment variables.
  • Store local web runtime configuration in apps/web/.env.local.
  • Do not commit tokens, keys, passwords, or rendered env dumps.
  • Do not edit checked-in compose files to inject per-environment secrets.

Local And Self-Hosted Web

LocationPurpose
apps/web/.env.localDocker build secret input and runtime env file for the web app
Shell environmentOptional overrides such as DOCS_PORT, SUPABASE_SERVER_URL, or UPSTASH_REDIS_REST_* when you intentionally override the Docker helpers
tmp/docker-web/prod/Generated local deployment state for blue/green rollout

GitHub Actions Secrets By Area

Vercel-hosted web apps

Vercel workflows use GitHub Environments named vercel-preview-<app> and vercel-production-<app>. Keep the deployment secrets on those environments, not as workflow-level env: entries. Production environments should require reviewers and restrict deployment branches to production; preview environments should require review whenever branch pushes can run repository-controlled code with deployment credentials.
  • VERCEL_TOKEN
  • VERCEL_ORG_ID
  • App-specific VERCEL_PROJECT_ID values such as VERCEL_PLATFORM_PROJECT_ID and VERCEL_APPS_PROJECT_ID
  • QR deployments use VERCEL_QR_PROJECT_ID in the vercel-preview-qr and vercel-production-qr GitHub Environments

Production and preview app configuration

These values belong in the Vercel project environment for each app and target. Do not export them from GitHub Actions workflows. The Vercel deploy workflows run repository code during install and build, so workflow-wide production runtime secrets are a supply-chain exposure path.
  • PRODUCTION_SUPABASE_URL
  • PRODUCTION_SUPABASE_PUBLISHABLE_KEY
  • PRODUCTION_SUPABASE_SECRET_KEY
  • ENCRYPTION_MASTER_KEY
  • Optional Turborepo remote-cache credentials such as TURBO_TOKEN and TURBO_TEAM
Individual workflows may also consume other application-specific secrets depending on the deployed app.

Integration-specific runtime secrets

  • SePay OAuth requires SEPAY_OAUTH_CLIENT_ID, SEPAY_OAUTH_CLIENT_SECRET, SEPAY_OAUTH_TOKEN_ENCRYPTION_SECRET, and a webhook auth secret such as SEPAY_WEBHOOK_API_KEY.
  • SePay web runtimes also require an app origin through WEB_APP_URL, NEXT_PUBLIC_WEB_APP_URL, or NEXT_PUBLIC_APP_URL so OAuth callbacks and webhook provisioning can generate stable platform URLs.
  • SePay workspace enablement is controlled by the workspace secret ENABLE_SEPAY_INTEGRATION=true.
  • SePay runtime overrides may optionally set SEPAY_OAUTH_AUTHORIZE_URL, SEPAY_OAUTH_BASE_URL, and SEPAY_API_BASE_URL when targeting non-default environments.
  • SePay OAuth state is stored in a short-lived HttpOnly callback cookie and is HMAC-signed. The signer uses SEPAY_OAUTH_STATE_SECRET when set; otherwise it falls back to the required SEPAY_OAUTH_CLIENT_SECRET.

Supabase migrations

  • SUPABASE_ACCESS_TOKEN
  • STAGING_DB_PASSWORD
  • STAGING_PROJECT_ID
  • STAGING_DB_URL
  • PRODUCTION_DB_PASSWORD
  • PRODUCTION_PROJECT_ID
  • PRODUCTION_DB_URL
  • MODAL_TOKEN_ID
  • MODAL_TOKEN_SECRET
  • MODAL_ENVIRONMENT as a GitHub Actions variable

Package publishing

  • NPM_TOKEN for npm publication

Docker-Specific Notes

  • The Docker web helper auto-generates a stable local Redis token and injects UPSTASH_REDIS_REST_TOKEN, UPSTASH_REDIS_REST_URL, and the matching internal SRH_TOKEN value for the bundled serverless-redis-http container.
  • SRH_TOKEN is the container’s internal environment variable. The user-facing override surface is UPSTASH_REDIS_REST_TOKEN if you intentionally replace the helper-generated value.
  • The local dev compose file keeps a dev-only fallback token for direct local use, but production Redis compose requires UPSTASH_REDIS_REST_TOKEN during Compose interpolation. Use the Docker web helper or export a strong token before enabling the production redis profile directly.
  • Redis and serverless-redis-http host ports must stay loopback-bound. Do not publish those sidecars on all host interfaces or through Cloudflare Tunnel.
  • apps/web uses Redis for security-sensitive one-time state such as CLI refresh-token replay protection. If UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN are unavailable, CLI refresh requests fail closed instead of minting new sessions.
  • docker compose config expands env values; treat its output as sensitive.

Supabase RPC Authorization Hardening

  • Treat every new SECURITY DEFINER function in public as externally callable until proven otherwise.
  • In the same migration that creates or replaces the function, enforce both:
    1. in-function authorization checks (auth.uid() plus workspace membership/permission gate), and
    2. explicit execute privileges (revoke all ... from public, then grant only required roles such as authenticated/service_role).
  • Do not rely only on apps/web page or API RBAC checks for tenant isolation when an RPC is exposed through the Data API.
  • During review, grep the migration for security definer, auth.uid(), has_workspace_permission, revoke, and grant execute before merge.

Change Management

When a new deployment flow is added:
  1. Add its secret names here.
  2. Add the workflow or runtime page to the relevant devops doc.
  3. Keep the boundary clear between repo config, GitHub Actions config, and machine-local config.