Every variable that configures a Carbon instance, grouped by concern. The source of truth is packages/env.
Carbon reads configuration from environment variables registered in packages/env. Use .env.example as the template. sst.config.ts reads infrastructure-only variables. A minimal instance requires Supabase, a session secret, and Redis; other variables enable optional features.
One of community, cloud, enterprise, or test. Gates edition-specific features.
CONTROLLED_ENVIRONMENTbooleanoptional
Enables ITAR / controlled-environment restrictions: the US-Person certification gate, ITAR hostnames and branding, Slack and analytics disabled, and mandatory two-factor authentication that a company admin cannot turn off.
TENANT_TYPEenumoptional
single when one customer owns the deployment, as a self-hosted install does; multi (the default) for Carbon Cloud. With single, companies can send documents through the server's own mail (Server mail).
Carbon's single Postgres database. The first four are required and crash boot if missing.
SUPABASE_URLurlrequired
Supabase project URL.
SUPABASE_ANON_KEYstringrequired
Public anon key, browser-safe.
SUPABASE_SERVICE_ROLE_KEYstringrequired
Service-role key, server only, never exposed to the client.
SUPABASE_DB_URLurlrequired
Direct Postgres connection string.
SUPABASE_JWT_SECRETstringoptional
Secret used to sign and verify session JWTs. Optional to the app, but the Supabase data plane needs it, so the self-hosting recipes always generate one.
Signs the session cookie. Carbon also derives its Web Push keys from it, so changing it makes each user's browser notifications re-subscribe on their next visit.
SAML signing key — base64-encoded PKCS#1 DER RSA, minimum 2048-bit; the generation command is in .env.example.
Outside Vercel, set both CLOUDFLARE_TURNSTILE_SITE_KEY and CLOUDFLARE_TURNSTILE_SECRET_KEY to enable Cloudflare Turnstile on login forms. Without them, only per-IP rate limits and per-account lockouts apply. Set BOT_PROTECTION to turnstile, or to botid for invisible Vercel BotID protection. BotID runs only on Vercel.
Redis connection (ioredis URL) for the permission cache and queues.
INNGEST_SIGNING_KEYstringoptional
Signs requests to the Inngest jobs runner. Required in production.
INNGEST_EVENT_KEYstringoptional
Key for sending events to Inngest. Required in production.
INNGEST_BASE_URLurloptional
Override the Inngest endpoint (self-hosted or dev).
HEADS UP
Inngest keys are required in production
INNGEST_SIGNING_KEY and INNGEST_EVENT_KEY are optional only when INNGEST_DEV=1. In other environments, the application does not start if either is missing. A self-hosted Inngest server supplies both; the Docker with Caddy recipe generates them.
The database also sends events to Inngest directly, for the event queue, search embeddings and job notifications. Whenever the ERP registers its functions with Inngest (on each deploy, and on each start of a long-running server), it also stores the address for that in the database, built from INNGEST_EVENT_KEY and INNGEST_BASE_URL, so no extra step is needed.
If the database reaches Inngest at a different address than the application does, set that address once:
OAuth credentials for each connector, all optional, set only the ones you use.
XERO_CLIENT_IDstringoptional
Xero OAuth client id.
XERO_CLIENT_SECRETstringoptional
Xero OAuth client secret.
XERO_WEBHOOK_SECRETstringoptional
Verifies inbound Xero webhooks.
QUICKBOOKS_CLIENT_IDstringoptional
QuickBooks OAuth client id.
QUICKBOOKS_CLIENT_SECRETstringoptional
QuickBooks OAuth client secret.
JIRA_CLIENT_IDstringoptional
Jira OAuth client id.
JIRA_CLIENT_SECRETstringoptional
Jira OAuth client secret.
SLACK_CLIENT_IDstringoptional
Slack OAuth client id.
SLACK_CLIENT_SECRETstringoptional
Slack OAuth client secret.
SLACK_OAUTH_REDIRECT_URLurloptional
Callback for the Slack install: https://<erp-host>/api/integrations/slack/oauth. Must be registered on the Slack app. See Connect Slack.
SLACK_SIGNING_SECRETstringoptional
The Slack app's signing secret. Required: without it the Slack install ends on an error, and Carbon refuses Slack interactivity requests it cannot verify.
SLACK_STATE_SECRETstringoptional
Any long random string. Signs the state of a Slack install. Required: without it the install cannot start.
RAMP_CLIENT_IDstringoptional
Client id of the Ramp developer app. Without it the Ramp card reads Not Configured. See Connect Ramp.
RAMP_CLIENT_SECRETstringoptional
Client secret of the Ramp developer app.
ONSHAPE_CLIENT_IDstringoptional
Client id of the Onshape OAuth application for the pull integration (onshape). Without it the Onshape card reads Not Configured.
ONSHAPE_CLIENT_SECRETstringoptional
Client secret of the pull integration's Onshape OAuth application.
ONSHAPE_OAUTH_REDIRECT_URLurloptional
Callback for the pull integration: https://<erp-host>/api/integrations/onshape/oauth. Must be registered on the pull integration's Onshape application.
ONSHAPE_V2_CLIENT_IDstringoptional
Client id of the Onshape OAuth application for the panel integration (onshape-v2), a separate application from the pull integration's. Without it the Onshape V2 card reads Not Configured.
ONSHAPE_V2_CLIENT_SECRETstringoptional
Client secret of the panel integration's Onshape OAuth application.
ONSHAPE_V2_OAUTH_REDIRECT_URLurloptional
Callback for the panel integration: https://<erp-host>/api/integrations/onshape-v2/oauth. Must be registered on the panel integration's Onshape application. Without it the Onshape V2 Connect button fails with "Onshape isn't configured".
GOOGLE_CLIENT_IDstringoptional
Client id of the Google OAuth application used by the Google Calendar and Gmail workflow steps. Without it both cards read Coming soon.
GOOGLE_CLIENT_SECRETstringoptional
Client secret of that Google OAuth application.
GOOGLE_OAUTH_REDIRECT_URLurloptional
Callback for workflow integration connections: https://<erp-host>/api/integrations/connections/callback. Must be registered on the Google OAuth application.
EXCHANGE_RATES_API_KEYstringoptional
Currency exchange-rate feed.
GOOGLE_PLACES_API_KEYstringoptional
Address autocomplete.
The Onshape panel also needs an extension registered on the Onshape application and the
panel's users subscribed to it — see CAD. Panel sessions and push
reviews are held in Redis, so REDIS_URL is required for the panel to work.