Skip to content

Environment Variables

Every Luke service is configured entirely through environment variables — there are no per-environment config files baked into the images. Spring services read ${VAR:default} placeholders from their application*.yml; the Vite UIs inline VITE_* variables at build time; the Python agents fleet reads os.getenv(...). Sensible local-dev defaults let each service boot with zero configuration, and production values are injected by the Render Blueprint (see Deployment Topology).

This page is a factual, per-service reference of the variables each service reads, their defaults where one exists, and whether the value is a secret. It reflects the fleet as of July 2026.

Fail-fast production guards

Several services refuse to boot if a required secret is missing or left at an insecure development default. These guards run only under the production Spring profile (SPRING_PROFILES_ACTIVE=postgres,prod for core-engine) or when a service is explicitly told it is in production (AGENTS_ENV=production):

  • core-engine — the prod profile activates guards such as H2ConsoleGuard (refuses boot if the H2 console is enabled) and the insecure-key checks over the HMAC / secret-store master keys left at their *-change-me defaults.
  • auth-engineDevModeGuard refuses boot if LUKE_AUTH_DEV_MODE=true without the dev Spring profile, so a single env var can never open the dev backdoors in a shared/prod environment. Related guards enforce a stable gateway signing key and reject WORKOS_MARK_EMAIL_VERIFIED=true outside dev-mode.
  • luke-agents — with AGENTS_ENV=production the app refuses to start unless it is locked down: AGENTS_API_KEY set, AGENTS_CORS not *, and AGENTS_REQUIRE_TENANT=true.

Leave these guards' variables at their defaults for local development; set the hardened values in qa/uat/prod. See Security for the full threat model.


Core Engine

The Core Engine is the largest surface — it embeds the FluxNova/Camunda-7 engine plus the merged capability data layer (forms, email, signatures, documents, phone, workflow, embed, secrets). Local dev runs on H2 with no setup; production activates the postgres,prod profiles.

Runtime & database

VariablePurposeDefaultSecret?
PORTHTTP listen port (Render injects this)8080No
SPRING_PROFILES_ACTIVEActivate profiles; use postgres,prod in production(none → H2 dev)No
DB_URLFull JDBC URL (wins over host/port fields)H2 file ./luke-data/luke-engineNo
DB_USERNAMEDatabase usersa (H2) / luke (postgres)No
DB_PASSWORDDatabase password(empty) / lukeYes
DB_DRIVERJDBC driver classorg.h2.DriverNo
POSTGRES_HOSTPostgres host (when DB_URL unset)localhostNo
POSTGRES_PORTPostgres port5432No
POSTGRES_DATABASEPostgres database nameluke_camundaNo
DB_SCHEMAPer-env schema for shared-Postgres isolationpublicNo
H2_CONSOLE_ENABLEDEnable the H2 SQL console (dev only; H2ConsoleGuard blocks under prod)falseNo

Camunda / FluxNova engine

VariablePurposeDefaultSecret?
CAMUNDA_ADMIN_USERBootstrap admin user idadminNo
CAMUNDA_ADMIN_PASSWORDBootstrap admin passwordadminYes

Tenancy, auth & internal wiring

VariablePurposeDefaultSecret?
LUKE_PARENT_CLUSTER_IDOperations ("parent cluster") tenant idparent_clusterNo
LUKE_PARENT_CLUSTER_NAMEParent-cluster display nameParent ClusterNo
ALLOWED_ORIGINSComma-separated CORS origin patternshttp://localhost:*No
LUKE_INTERNAL_SHARED_SECRETShared secret guarding /api/internal/** (must match callers)(unset → 403 all)Yes
LUKE_AUTH_GATEWAY_ENABLEDAccept gateway-signed act-as Bearer tokens on /engine-rest/*falseNo
LUKE_AUTH_GATEWAY_JWKS_URLJWKS URL to verify gateway tokens(unset)No
LUKE_AUTH_GATEWAY_ISSUERExpected token issuerluke-auth-engineNo
LUKE_AUTH_GATEWAY_AUDIENCEExpected token audienceluke-core-engineNo
CAPABILITIES_BASE_URLCapability-engine base URL (legacy; merged in-process)http://localhost:8082No
CORE_ENGINE_BASE_URLSelf base URL for form process-start pathhttp://localhost:8080No
CAPABILITY_OPERATOR_USEROperator user for capability admin routes(unset → open)No
CAPABILITY_OPERATOR_PASSWORDOperator password for capability admin routes(unset)Yes

Forms & render

VariablePurposeDefaultSecret?
FORMS_PUBLIC_BASE_URLPublic origin for outbound recipient linkshttp://localhost:8080No
FORMS_RECIPIENT_HMAC_SECRETHMAC secret for recipient fill-session tokensdev-recipient-secret-change-meYes
FORMS_RECIPIENT_SESSION_TTL_MSRecipient fill-session TTL1800000No
LUKE_FORMS_INTAKE_PROCESS_KEYBPMN key started per form submissionFormSubmissionIntakeProcessNo
LUKE_FORMS_SUBMISSION_PDF_ENABLEDGlobal kill-switch for submission-PDF rendertrueNo
LUKE_RENDER_URLfile-proxy headless-Chromium render base URL (unset → skip PDF)(unset)No

Embed & secrets store

VariablePurposeDefaultSecret?
LUKE_EMBED_HMAC_SECRETHMAC secret for public embed tokensdev-embed-secret-change-meYes
LUKE_SECRETS_ACTIVE_KEY_IDActive AES-256-GCM key iddevNo
LUKE_SECRETS_KEY_DEVAES-256-GCM master key materialdev-secrets-master-key-change-meYes

Email (Postmark)

VariablePurposeDefaultSecret?
POSTMARK_BASE_URLPostmark API base URLhttps://api.postmarkapp.comNo
POSTMARK_ACCOUNT_TOKENPostmark account-level token(unset)Yes
POSTMARK_SERVER_TOKENPostmark server token(unset)Yes
EMAIL_DEFAULT_FROMDefault From address(unset)No
POSTMARK_MESSAGE_STREAMMessage streamoutboundNo
EMAIL_SENDER_BASE_DOMAINSending base domain(unset)No
EMAIL_SENDER_DEFAULT_LOCAL_PARTDefault local-partno-replyNo
EMAIL_VERIFICATION_CODE_LENGTHOTP code length6No
EMAIL_VERIFICATION_TTL_SECONDSOTP validity window600No
EMAIL_VERIFICATION_MAX_ATTEMPTSMax OTP attempts5No
OTP_TEMPLATE_ALIASPostmark template alias for OTP emailluke-otpNo
EMAIL_PRODUCT_NAMEBrand name merged into OTP emailLukeflowNo

Signatures (PAdES e-sign)

VariablePurposeDefaultSecret?
SIGN_PUBLIC_BASE_URLPublic base for /sign/:token linkshttp://localhost:5173No
LUKE_SIGN_MAX_UPLOADMax PDF upload size25MBNo
LUKE_SIGNATURES_CEREMONY_PROCESS_KEYBPMN key for the signature ceremonySignatureCeremonyProcessNo
LUKE_SIGNATURES_OUTBOX_ENABLEDRun the signature outbox poller (one HA node)trueNo
LUKE_SIGNATURES_OUTBOX_POLL_MSOutbox poll interval2000No
LUKE_SIGN_RETENTION_DAYSSigned-document retention window2555No
LUKE_SIGN_REASONPAdES signature reasonSigned via Luke e-signatureNo
LUKE_SIGN_LOCATIONPAdES signature location(unset)No
LUKE_SIGN_TRUST_MODEself (ESIGN/UETA) or qtsp (eIDAS)selfNo
LUKE_SIGN_TSA_ENABLEDEnable RFC-3161 timestampingtrueNo
LUKE_SIGN_TSA_URLTimestamp authority URLhttp://timestamp.digicert.comNo
LUKE_SIGN_KEYSTORE_BASE64Base64 PKCS#12 signing keystore(unset)Yes
LUKE_SIGN_KEYSTORE_PASSWORDKeystore password(unset)Yes
LUKE_SIGN_KEY_ALIASKey alias inside the keystore(unset)No
LUKE_SIGN_BLOCK_IP_RISKCSV of IP-risk classes to hard-block(empty → flag only)No

Document store (S3 / blob)

VariablePurposeDefaultSecret?
LUKE_DOCSTORE_PROVIDERlocal (file FS) or s3localNo
LUKE_DOCSTORE_LOCAL_DIRLocal FS directory (local provider)./luke-data/docstoreNo
LUKE_DOCSTORE_BUCKETObject-storage bucket(unset)No
LUKE_DOCSTORE_REGIONBucket region(unset)No
LUKE_DOCSTORE_ENDPOINTS3-compatible endpoint (R2/B2/MinIO)(unset)No
LUKE_DOCSTORE_ACCESS_KEYObject-storage access key(unset)Yes
LUKE_DOCSTORE_SECRET_KEYObject-storage secret key(unset)Yes
LUKE_DOC_RETENTION_DAYSDefault per-capability retention (0 = none)0No
LUKE_DOC_RETENTION_DAYS_SIGNATURESSignatures retention window2555No
LUKE_DOC_PURGE_ENABLEDEnable the retention purge job (prod only)falseNo
LUKE_DOC_PURGE_DRY_RUNLog-only purge (no state change)trueNo
LUKE_DOC_PURGE_INTERVAL_MSPurge job interval86400000No

Phone (Vapi) & Workflow (Nango)

VariablePurposeDefaultSecret?
VAPI_BASE_URLVapi API base URLhttps://api.vapi.aiNo
VAPI_API_KEYGlobal fallback Vapi private key(unset)Yes
VAPI_WEBHOOK_SECRETShared secret echoed in X-Vapi-Secret(unset)Yes
VAPI_WEBHOOK_REQUIRE_SECRETReject unsigned webhooks (set true in prod)falseNo
LUKE_PHONE_CALL_PROCESS_KEYBPMN key started per callPhoneCallProcessNo
LUKE_PHONE_OUTBOX_ENABLEDRun the phone outbox poller (one HA node)trueNo
LUKE_PHONE_OUTBOX_POLL_MSOutbox poll interval2000No
NANGO_BASE_URLNango API base URLhttps://api.nango.devNo
NANGO_SECRET_KEYNango platform secret key (server-only)(unset)Yes
NANGO_MAX_CONNECTIONS_PER_TENANTPer-tenant active-connection quota25No
NANGO_WEBHOOK_REQUIRE_SIGNATUREReject unsigned webhooks (set true in prod)falseNo
LUKE_WORKFLOW_OUTBOX_ENABLEDRun the workflow outbox poller (one HA node)trueNo
LUKE_WORKFLOW_OUTBOX_POLL_MSOutbox poll interval2000No

Auth Engine

The Auth Engine is a stateless reverse-proxy / gateway that runs WorkOS login flows and mints short-lived act-as-user tokens. It holds no database.

Runtime & upstreams

VariablePurposeDefaultSecret?
PORTHTTP listen port8083No
CORE_ENGINE_URLUpstream engine the gateway proxies tohttp://localhost:8080No
FILE_PROXY_URLRoute /api/documents/** to file-proxy when set(unset → core)No
ALLOWED_ORIGINSConsumer-UI CORS originshttp://localhost:*No

Dev-mode, rate-limit & sessions

VariablePurposeDefaultSecret?
LUKE_AUTH_DEV_MODEAllow X-Dev-User//dev/token (requires dev profile; DevModeGuard)falseNo
SESSION_CACHE_TTL/session translator cache TTL (seconds)60No
AUTH_RATELIMIT_MAXMax requests per IP+path window10No
AUTH_RATELIMIT_WINDOW_SECONDSRate-limit window60No
AUTH_RATELIMIT_MAX_KEYSMax tracked rate-limit keys50000No

Service accounts

VariablePurposeDefaultSecret?
LUKE_AUTH_SERVICE_KEYSCSV key=userId pairs (may be SHA-256 hashed, ;exp=, ;scope=)(empty)Yes
LUKE_AUTH_SERVICE_OPERATOR_TOKENToken enabling live key revocation(empty → disabled)Yes

WorkOS (authentication)

VariablePurposeDefaultSecret?
WORKOS_CLIENT_IDWorkOS client id(unset)No
WORKOS_API_KEYWorkOS API key(unset)Yes
WORKOS_API_BASEWorkOS API base URLhttps://api.workos.comNo
WORKOS_JWKS_URLJWKS for access-token verification(derived from base+client)No
WORKOS_ISSUERExpected token issuer(unset)No
WORKOS_AUDIENCEExpected token audience(unset)No
WORKOS_STRICT_VALIDATIONRequire issuer/audience (fail-closed) in prodfalseNo
WORKOS_REDIRECT_URIOAuth callback URL (must be registered)http://localhost:8083/auth/callbackNo
WORKOS_UI_CALLBACK_URLUI SSO-callback the browser lands onhttp://localhost:5173/sso-callbackNo
WORKOS_COOKIE_SECUREMark refresh cookie SecuretrueNo
WORKOS_COOKIE_SAMESITERefresh cookie SameSiteLaxNo
WORKOS_MARK_EMAIL_VERIFIEDDEV-ONLY: create users pre-verified (guarded)falseNo

Self-service onboarding

VariablePurposeDefaultSecret?
ONBOARDING_OPERATOR_USEROperator user for /api/admin/onboard-user(unset → skip)No
ONBOARDING_OPERATOR_PASSWORDOperator password(unset)Yes
ONBOARDING_DEFAULT_TENANTTenant new users join (blank → skip provisioning)(unset)No
ONBOARDING_DEFAULT_ROLEDefault role on provisioning(unset)No
ONBOARDING_DEFAULT_ACCESS_LEVELDefault access levelREAD_WRITENo

Gateway signing key

VariablePurposeDefaultSecret?
GATEWAY_PRIVATE_KEYPEM PKCS#8 RSA key signing act-as tokens (else ephemeral)(unset → ephemeral)Yes
GATEWAY_REQUIRE_STABLE_KEYRequire a stable key (boot fails if unset) — set true in prodfalseNo
GATEWAY_PREVIOUS_PUBLIC_KEYPrevious PEM public key for zero-downtime rotation(unset)No
GATEWAY_ISSUERIssuer stamped on act-as tokensluke-auth-engineNo
GATEWAY_AUDIENCEAudience stamped on act-as tokensluke-core-engineNo
GATEWAY_TTL_SECONDSAct-as token validity60No

File Proxy

The File Proxy is the S3 byte-tier and headless-Chromium PDF renderer. It reuses the same LUKE_DOCSTORE_* keys as core-engine so both point at the same provisioned buckets.

VariablePurposeDefaultSecret?
PORTHTTP listen port8095No
LUKE_CORE_BASE_URLcore-engine base URL for authZ + Document statehttp://localhost:8080No
LUKE_INTERNAL_SHARED_SECRETShared secret for core's /api/internal/** (match core)(unset)Yes
LUKE_DOCSTORE_PROVIDERlocal or s3localNo
LUKE_DOCSTORE_LOCAL_DIRLocal FS directory./luke-data/docstoreNo
LUKE_DOCSTORE_BUCKETObject-storage bucket(unset)No
LUKE_DOCSTORE_REGIONBucket region(unset)No
LUKE_DOCSTORE_ENDPOINTS3-compatible endpoint(unset)No
LUKE_DOCSTORE_ACCESS_KEYAccess key(unset)Yes
LUKE_DOCSTORE_SECRET_KEYSecret key(unset)Yes
LUKE_DOCSTORE_KMS_KEYOptional KMS key id for SSE(unset)No
LUKE_DOCSTORE_MAX_BYTESBroker-enforced upload cap (bytes)26214400 (25 MiB)No
LUKE_DOCSTORE_MAX_FILE_SIZEContainer multipart file cap25MBNo
LUKE_DOCSTORE_MAX_REQUEST_SIZEContainer multipart request cap30MBNo

Agents (luke-agents)

The Agents fleet is a FastAPI + Groq multi-agent service. It reads plain os.getenv(...) values (no Spring). Setting AGENTS_ENV=production turns on the lockdown guard described in the warning above.

Server & security

VariablePurposeDefaultSecret?
AGENTS_ENVSet production to enforce the lockdown guard(unset → dev)No
AGENTS_API_KEYCaller key (sent as X-Agents-Key); required in prod(unset)Yes
AGENTS_CORSAllowed browser origins (CSV; must not be * in prod)*No
AGENTS_REQUIRE_TENANTRequire tenant header (behind gateway); true in prodfalseNo
AGENTS_DEFAULT_TENANTFallback tenant idpublicNo
AGENTS_ACTORActor label for audit(unset)No
RATE_LIMIT_MAXPer-caller action cap200No
RATE_LIMIT_WINDOW_SECONDSRate-limit window10800 (3h)No
REDIS_URLShared rate-limit store (required multi-worker)(unset → per-worker)Yes

LLM brains

VariablePurposeDefaultSecret?
AGENTS_BRAINForce brain: groq | openai | gemini | ollama(auto; Groq wins)No
GROQ_API_KEYGroq API key (default brain)(unset)Yes
GROQ_MODELGroq modelopenai/gpt-oss-120bNo
GROQ_FALLBACK_MODELGroq fallback modelllama-3.3-70b-versatileNo
OPENAI_API_KEYOpenAI API key(unset)Yes
OPENAI_MODELOpenAI modelgpt-5-nanoNo
OPENAI_REASONING_EFFORTReasoning effort (blank for nano)(empty)No
GEMINI_API_KEYGemini API key(unset)Yes
GEMINI_MODELGemini modelgemini-2.0-flashNo
OLLAMA_MODELLocal Ollama model (dev fallback)qwen2.5:7bNo
LLM_TIMEOUT_SECONDSPer-call LLM timeout30No

Sentiment agent (LukeSense)

VariablePurposeDefaultSecret?
SENTIMENT_GROQ_MODELCheaper Groq model for sentimentllama-3.1-8b-instantNo
SENTIMENT_MODELPin a model for the active brain(empty)No
SENTIMENT_BATCH_MAXMax texts per batch call50No
SENTIMENT_DOC_CHUNK_CHARSPer-section chunk size for documents2000No

Transcripts, retention & PII

VariablePurposeDefaultSecret?
DATABASE_URLPostgres for transcript store (unset → JSONL, dev only)(unset)Yes
AGENTS_DB_SCHEMASchema for transcript tablesluke_agentsNo
TRANSCRIPTS_ENABLEDRecord chat turnstrueNo
TRANSCRIPTS_DIRJSONL directory when no DATABASE_URLdata/transcriptsNo
AGENTS_RETENTION_DAYSPurge turns older than N days (0/unset = keep)(unset)No
AGENTS_REDACT_PIIBest-effort scrub of emails/phones/SSNsfalseNo
AGENTS_EXPORT_AUDIT_LOGJSONL path auditing fine-tune exports(unset)No

Consumer UI

The Consumer UI (luke-consumer-ui) is a Vite/React app. VITE_* variables are inlined at build time — they are baked into the bundle, never read at runtime, so none of them may hold a secret.

VariablePurposeDefaultSecret?
VITE_AUTH_API_URLauth-engine (gateway) base URLhttp://localhost:8083No
VITE_FORM_AGENT_URLluke-agents base URL (AI form builder)https://luke-agents.onrender.comNo
VITE_WORKFLOW_AGENT_URLluke-agents base URL for the workflow agent(falls back to VITE_FORM_AGENT_URL)No
VITE_SIGNATURES_API_URLe-signature API base URLhttp://localhost:8090No
VITE_WORKFLOW_ENABLEDReveal the hidden Workflows capabilityfalse (hidden)No
VITE_FORMS_ALLOW_AUTOFILLAllow browser/password-manager autofill on formsfalse (suppressed)No
VITE_SENTRY_DSNSentry DSN (no-op unless set)(unset)No
VITE_SENTRY_TRACES_RATESentry performance trace sample rate (0..1)0.1No
VITE_RELEASERelease tag for Sentry events(unset)No

Core UI

The Core UI (luke-core-ui, TailAdmin operations console) is likewise a build-time Vite app — no secrets.

VariablePurposeDefaultSecret?
VITE_API_BASE_URLDeployed core-engine URL (empty → same-origin dev proxy)(empty)No
VITE_CAMUNDA_BASE_URLLocal dev proxy target for /engine-rest and /apihttp://localhost:8080No
VITE_TASK_ENGINE_URLTask/e-sign engine URLhttp://localhost:8090No
VITE_SENTRY_DSNSentry DSN (no-op unless set)(unset)No
VITE_SENTRY_TRACES_RATESentry performance trace sample rate (0..1)0.1No
VITE_RELEASERelease tag for Sentry events(unset)No

Lukeflow Manual · documentation snapshot July 2026