Environment variables
This is an operational map, not an exhaustive generated inventory. Most application settings are validated by src/lib/env.ts, but some runtime modules, framework config files, and deployment scripts read environment variables directly. Search the live source before removing or renaming a variable.
For secret-store boundaries and rotation responsibilities, see Credentials and secret stores. Historical environment inventories were retired because copied variable lists drift; use the scopes below and current source.
Configuration scopes
| Scope | Canonical evidence | Examples |
|---|---|---|
| Validated application config | src/lib/env.ts | auth, data stores, connectors, scheduled jobs, service settings |
| Direct runtime reads | focused process.env search | media/storage, notifications, parity/audit helpers, selected jobs |
| Build and tooling | Next/Sentry config and scripts/ | migration gate, deployment metadata, observability |
| Per-client secrets | connector vault | ad, commerce, CRM, attribution credentials |
| Platform-wide secrets | platform-service vault | ClickUp, Apify, Firecrawl, Deepgram, OpenAI, Cloudinary, TikTok Creative Center, Google Cloud |
Runtime
| Var | Where | Purpose |
|---|---|---|
APP_BASE_URL | Vercel | https://launch.lynkr.cc. Pins Inngest's serveHost. Load-bearing — see Deployment. |
AUTH_SECRET | Vercel | Session signing secret (Auth.js / NextAuth v5). Rotate at handoff. There is no NEXTAUTH_SECRET in this codebase. |
AUTH_TRUST_HOST | Vercel | Auth.js host trust. |
NODE_ENV | Vercel | production in prod, development locally. |
MARKETING_SYNC_CRON | Vercel | Cron for syncMarketingMetrics. Production overrides the code default — never read the source for the live cadence. |
CREDENTIAL_ENCRYPTION_KEY | Vercel | AES-256-GCM key for both credential vaults. Stored per-client credentials fail closed when it is missing; some platform-service reads may use explicit environment fallbacks. |
PLATFORM_TOKEN | Vercel | Silently backfills CLICKUP_WEBHOOK_SECRET and MARKETING_API_TOKEN unless those are set individually. |
SUPABASE_DB_URL | Vercel | Read by the build-time migration gate (scripts/migrate-on-deploy.ts), not by the Zod schema — a schema-only audit misses it. When unset, the runner logs that Supabase migrations were skipped. Migrations run only on Vercel production builds; Preview builds never migrate, because they share production database credentials. |
Feature switches and job controls
| Var | Default | Purpose |
|---|---|---|
SYNC_HEALER_ENABLED | off | The sync self-healer does nothing unless this is true. See Scheduled jobs. |
SYNC_HEALER_CRON | 5,25,45 * * * * | Schedule for the healer. |
PAID_TODAY_REFRESH_ENABLED | on | Set false, 0, off or no to stop the half-hourly same-day ad spend refresh. |
CLICKUP_IDENTITY_SYNC_CRON, BIND_ADS_CRON, CREATIVE_METADATA_BACKFILL_CRON, LAUNCHPAD_METADATA_BACKFILL_CRON, SCORE_ADS_CRON | see Scheduled jobs | Schedules for the ClickUp and creative jobs. |
MCP_ALLOW_LEGACY_STATIC_TOKENS, MCP_LEGACY_USER_EMAIL | false / empty | Static bearer tokens for the MCP server are disabled by default and exist only as a time-boxed migration escape hatch. Normal clients use OAuth with user consent. |
GOOGLE_SSO_CLIENT_ID, GOOGLE_SSO_CLIENT_SECRET, GOOGLE_SSO_ALLOWED_DOMAINS, GOOGLE_SSO_HOSTED_DOMAIN, GOOGLE_SSO_ALLOW_AUTO_REGISTER | empty | Google sign-in. Leave the client ID empty to hide Google sign-in. |
SENTRY_DSN, NEXT_PUBLIC_SENTRY_DSN, SENTRY_ENVIRONMENT, SENTRY_TRACES_SAMPLE_RATE | empty | Error monitoring. With no DSN it is a no-op. Request credentials are scrubbed before events leave the app. |
SLACK_WEBHOOK_URL, SLACK_TOKEN | empty | Slack posting. SLACK_TOKEN is the environment fallback for the Slack bot token (service slack, key bot_token) that Spend Guards use; the platform-service vault is the primary store. |
Supabase
| Var | Where | Purpose |
|---|---|---|
SUPABASE_URL | Vercel | Public API URL. |
SUPABASE_ANON_KEY | Vercel (public) | Client-side anon key. RLS enforced. |
SUPABASE_SERVICE_ROLE_KEY | Vercel (server-only) | Server-side full-access key. Never exposed to browser. |
ClickHouse
| Var | Where | Purpose |
|---|---|---|
CLICKHOUSE_URL | Vercel | HTTPS endpoint. |
CLICKHOUSE_USER | Vercel | Read-write app user. |
CLICKHOUSE_PASSWORD | Vercel | Rotate at handoff. |
CLICKHOUSE_DATABASE | Vercel | Code default creative_ingest; set it explicitly when the target differs. |
Inngest
| Var | Where | Purpose |
|---|---|---|
INNGEST_SIGNING_KEY | Vercel | Signs incoming event webhooks. |
INNGEST_EVENT_KEY | Vercel | Sends outbound events. |
Platform integrations
Per-client platform tokens are not environment variables. They live encrypted in the connector vault, referenced by client_ad_accounts.credential_ref — a pointer, not an inline value. There is no client_ad_accounts.credentials column.
Platform-wide service credentials live in the second vault, platform_service_credentials, keyed by (service, key_name). The source catalog includes ClickUp, Apify, Firecrawl, Deepgram, OpenAI, Cloudinary, TikTok Creative Center, and Google Cloud. The current database constraint omits OpenAI; treat OpenAI vault writes as an unresolved schema gap until a migration aligns the constraint.
App-level fallbacks do exist in env (META_*, GOOGLE_ADS_*, TIKTOK_*) alongside the tenant-agnostic GOOGLE_ADS_DEVELOPER_TOKEN. See Credentials and secret stores for the full inventory and which store wins.
Environment scoping
Vercel scopes every variable to Production / Preview / Development independently. A var set only on Production makes preview deployments fail in ways that look like code bugs — and, for SUPABASE_DB_URL, makes a production build skip migrations while still reporting success.
Authentication bypass and automation variables
DEV_SUPERADMIN_EMAIL / DEV_SUPERADMIN_PASSWORD and AUTO_LOGIN_EMAIL / AUTO_LOGIN_PASSWORD alter the normal authentication entry path. Treat them as high-risk deployment settings: confirm their intended scope through the authorized configuration store and test the resulting login behavior.
Local development
Copy .env.example → .env.local. Fill in against a Supabase branch database and a ClickHouse dev service. Never point local dev at prod.