Skip to main content
This page documents apps/api/.env.example, the SaaS distribution template (EDITION=saas). Validated by apps/api/src/config/env.ts — the API fails closed at boot in production if a required secret is missing. Enterprise self-hosted and enterprise_hybrid deployments use the same variable names but different infrastructure values; see Installation.
Never commit real values for anything marked Secret below. Production secrets should live in Cloudflare Worker secrets, your container platform’s secret store, or an equivalent customer-managed vault for enterprise self-hosted deployments.

Edition and runtime

VariableSecretNotes
EDITIONsaas for this template. Self-hosted uses self_hosted / enterprise_hybrid.
NODE_ENVproduction enables strict, fail-closed validation of every production secret.
PORTHTTP port for the Node/Docker runtime.

Core infrastructure

System metadata and tenant data live in two physically separate Postgres databases — see Tenants & Data Boundaries. Each has an owner/admin URL (for migrations) and a restricted app-role URL (for runtime queries).
VariableSecretNotes
PLATFORM_DATABASE_URLYesOwner connection for system-metadata migrations.
PLATFORM_APP_DATABASE_URLYesRestricted runtime connection for system metadata.
TENANT_DATABASE_URLYesOwner connection for tenant-plane migrations.
TENANT_APP_DATABASE_URLYesRestricted runtime connection for the tenant plane; RLS-scoped by app.tenant_id.
REDIS_URLYesSessions, rate limits, nonces. Blank falls back to in-memory (single process only — no real session revoke).

Auth

VariableSecretNotes
JWT_ACCESS_SECRETYesSigns short-lived access tokens.
JWT_REFRESH_SECRETYesSigns refresh tokens.
JWT_ISSUERDefault alforse-api.
JWT_AUDIENCEDefault alforse-clients.
JWT_ACCESS_TTLDefault 15m.
JWT_REFRESH_TTLDefault 30d.
API_HMAC_SECRETYesHMAC for signed, non-browser API requests; required in production.

Public URLs and CORS

VariableSecretProduction value
API_PUBLIC_URLhttps://api.alforse.com/api/v1
WEB_PUBLIC_URLhttps://deals.alforse.com
DEALS_PUBLIC_URLhttps://deals.alforse.com
CONSOLE_PUBLIC_URLhttps://console.alforse.com
CORS_ALLOWED_ORIGINSComma-separated list of the origins above.
PUBLIC_REGISTRATION_ENABLEDMust be false in production unless your deployment explicitly supports public trial signup. Most production tenants use redemption codes or assisted onboarding.

Object storage (S3-compatible / Cloudflare R2)

VariableSecretNotes
OSS_ENDPOINTS3-compatible endpoint. Alforse Cloud uses Cloudflare R2; enterprise self-hosted deployments use the approved customer-managed endpoint.
OSS_BUCKET
OSS_ACCESS_KEYYes
OSS_SECRET_KEYYes
OSS_REGIONauto in production (R2).

OCR

VariableSecretNotes
OCR_ENABLEDProduction: true.
OCR_PROVIDERProduction: mistral.
OCR_ENDPOINTProduction: https://document-ai.alforse.com/extract (the apps/document-ai Worker).
OCR_API_KEYYes
OCR_ALLOW_UNAUTHENTICATEDKeep false for any customer-facing deployment.
OCR_TIMEOUT_MSDefault 60000.

License signing (self-hosted license issuance)

VariableSecretNotes
LICENSE_PRIVATE_KEYYesEd25519 private key (PEM). Required when your deployment issues signed self-hosted licenses.

File scanning and download gating

VariableSecretNotes
FILE_SCAN_MODEexternal routes uploaded files to a scanning service before they’re downloadable; this is the strict/safe default and the only supported mode for a real deployment.
FILE_SCAN_ENDPOINT
FILE_SCAN_API_KEYYes
FILE_SCAN_TEMPORARY_BYPASS_ACKExplicit acknowledgment flag for the temporary bypass.
FILE_SCAN_ALLOW_SKIPPED
FILE_DOWNLOAD_REQUIRES_CLEAN_SCANStrict/safe default is true.

MFA

VariableSecretNotes
MFA_REQUIRED_FOR_ADMINSProduction: true — admins must enroll TOTP MFA on first login.
MFA_SECRET_KEYYesEncrypts stored TOTP secrets; must be 32+ characters in production.

Turnstile (human verification)

VariableSecretNotes
TURNSTILE_ENABLEDProduction: true.
TURNSTILE_SECRET_KEYYesMust match the frontend site key.
TURNSTILE_ALLOWED_HOSTNAMESProduction: deals.alforse.com,console.alforse.com.
Turnstile applies to public auth endpoints (register, redeem, login, password reset, invite accept). If you’re calling those endpoints directly instead of through the Deals/Console UI, see Authentication for how turnstileToken fits into each request.

Data handling / AI gateway

VariableSecretNotes
EXTERNAL_DATA_MODEDefault redacted.
AI_GATEWAY_MODEDefault inspect.
AI_GATEWAY_ALLOWED_PROVIDERSAllowed provider identifiers for AI inspection flows.
AI_GATEWAY_ALLOWED_MODELSAllowed model identifiers for AI inspection flows.

SSO (optional)

Configure providers in complete pairs — a half-configured pair is rejected in production, and a missing pair simply hides that provider from GET /auth/sso/providers.
ProviderVariables
GoogleGOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
LinkedInLINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET
SlackSLACK_CLIENT_ID, SLACK_CLIENT_SECRET
DingTalkDINGTALK_APP_KEY, DINGTALK_APP_SECRET
LarkLARK_APP_ID, LARK_APP_SECRET
All *_SECRET / *_APP_SECRET values are secrets.

Email

Transactional mail (password reset, invitations, MFA backup codes) defaults to the Resend HTTP API — the only transport that’s safe from the Worker runtime, which cannot open raw TCP sockets.
VariableSecretNotes
EMAIL_PROVIDERresend for SaaS. smtp is self-hosted only.
RESEND_API_KEYYes
EMAIL_FROMDefault "Alforse <[email protected]>".
SMTP_HOST / SMTP_PORT / SMTP_SECURE / SMTP_STARTTLS / SMTP_USER / SMTP_PASS / SMTP_FROMSMTP_PASS is a secretSelf-hosted fallback only. With Resend’s SMTP bridge: host smtp.resend.com, user resend, password = your Resend API key.