Skip to content

Environment variables ​

Every process (API, worker, migrate) validates these at start-up with EnvSchema and refuses to start on an invalid value. Required means no default and not optional; an optional variable with no default is unset when absent. Regenerate with pnpm env:reference.

Database ​

VariableTypeDefaultRequiredDescription
DATABASE_URLurlyes
DATABASE_APP_URLurlnoNon-owner connection used by the API and worker so row-level security applies.

Temporal ​

VariableTypeDefaultRequiredDescription
TEMPORAL_ADDRESSstringlocalhost:7233no
TEMPORAL_NAMESPACEstringdefaultno
TEMPORAL_TASK_QUEUEstringaletheia-workflowsno
TEMPORAL_BACKTEST_TASK_QUEUEstringaletheia-backtestsnoLong-running backtests run on their own queue so they never starve decisions.
TEMPORAL_APP_TASK_QUEUEstringaletheia-appsnoApp calls (through the app runner) and document scans run on their own queue so vendor latency never starves decisions.

Apps ​

VariableTypeDefaultRequiredDescription
APP_CATALOG_DIRstringnoWhere the API finds the catalogue's index.json and modules (catalog/dist in development, /app/catalog in the image); unset, no platform apps are published at start-up.
APP_RUNNER_URLurlnoWhere the API and the worker reach the app runner (POST /v1/invoke and the other calls); unset, apps are off: nothing is installed or run, and the catalogue is not published.
APP_RUNNER_TOKENstring (min 32 chars)noBearer the API, the worker and the runner share: every call to the runner carries it, and the runner presents it to the API's internal routes. Unset, the runner accepts every request (development only; in production it refuses to start without one).
APP_CALL_TOKEN_SECRETstring (min 32 chars)noSigns the tokens a call reads the tenant's documents with (GET /internal/app-calls/…); held by the API and the worker only, never by the runner. 32 characters at least.
APP_BLOCKED_SHA256string""noHex SHA-256 hashes of modules the operator blocked, comma-separated: every call of one fails with app_blocked and GET /apps/health lists them.
APP_RUNNER_API_URLurlhttp://localhost:4000noWhere the runner fetches modules and documents from: the API's internal routes.
APP_RUNNER_HOSTstring0.0.0.0no
APP_RUNNER_PORTinteger > 04100no
APP_RUNNER_CONCURRENCYinteger ≥ 18noCalls one runner process runs at once; past it the runner answers 429 busy.
APP_RUNNER_TENANT_CONCURRENCYinteger ≥ 14noCalls one tenant may have in flight on one runner process at once.
APP_RUNNER_CACHE_DIRstringnoWhere the runner keeps fetched modules on disk; defaults to aletheia-app-runner under the temp directory.
APP_RUNNER_CACHE_MODULESinteger ≥ 132noCompiled modules the runner keeps in memory; the least recently used go first.
APP_RUNNER_ALLOW_PRIVATE_NETWORKStrue | falsefalsenoLets apps reach http:// URLs and private, loopback and link-local addresses. For development stacks only: in production vendors are https and public.

API ​

VariableTypeDefaultRequiredDescription
API_HOSTstring0.0.0.0no
API_PORTinteger > 04000no
API_INTERNAL_PORTinteger ≥ 14001noThe API's second listener, for the app runner only (GET /internal/app-modules/…, GET /internal/app-calls/…): never behind the ingress or a public Service port.
API_CORS_ORIGINSstring""noBrowser origins allowed to call the API directly; comma-separated. None by default: the admin console and the collection terminal call it through their own origin.
API_RATE_LIMIT_PER_MINUTEinteger ≥ 0600noRequests a minute one caller may make before the API answers 429 rate_limited with Retry-After; per API instance. A caller is a tenant's person or service user, an applicant's submission, or on the public routes (vendor webhooks, flow previews) a client address; health checks are not counted. 0 turns the limit off.

Zitadel (identity) ​

VariableTypeDefaultRequiredDescription
ZITADEL_ISSUERurlnoIdentity provider (Zitadel). The API refuses to start without the required subset.
ZITADEL_PROJECT_IDstringno
ZITADEL_API_CLIENT_IDstringno
ZITADEL_API_CLIENT_SECRETstringno
ZITADEL_DIRECTORY_PATstringnoPAT of the read-only machine user the reviewer directory uses; unset disables the directory.
ZITADEL_MANAGEMENT_PATstringnoPAT of the machine user that manages service users and their keys (Connect › API keys) and the tenants' people (Settings › Team); it needs user and user-grant management in the tenant organisations. Unset disables those routes.
ZITADEL_SIGNUP_PATstringnoPAT of the aletheia-signup machine user (instance role IAM_ORG_MANAGER): POST /signup creates a workspace's organisation, grants it the project and creates its admin. Signup is off without it, RESEND_API_KEY, SIGNUP_EMAIL_FROM and SIGNUP_CONSOLE_URL.

Signup ​

VariableTypeDefaultRequiredDescription
RESEND_API_KEYstringnoResend API key; the signup email carries the new admin's temporary password.
SIGNUP_EMAIL_FROMstring (min 3 chars)noSender of the signup email, Name <address> on a domain verified in Resend.
SIGNUP_EMAIL_REPLY_TOstringnoReply-To of the signup email; the sender when unset.
SIGNUP_CONSOLE_URLurlnoThe admin console's public address, in the signup email and the answer to the form.
TURNSTILE_SECRET_KEYstringnoCloudflare Turnstile secret. When set, POST /signup requires a token that passes; unset accepts the form without a bot check (development only).
SIGNUP_MAX_PER_HOURinteger ≥ 020noWorkspaces signup may create per hour across the deployment; 0 turns signup off.

Submission tokens ​

VariableTypeDefaultRequiredDescription
SUBMISSION_TOKEN_SECRETstring (min 32 chars)noSigns the links end customers use to open a collection flow.

Collection flow ​

VariableTypeDefaultRequiredDescription
COLLECTION_FLOW_URLurlnoPublic base URL of the collection terminal, used to build those links.
COLLECTION_TERMINAL_TENANT_NAMEstringnoThe name the collection terminal shows for tenants without their own branding (Settings › Branding). A tenant's own name or logo replaces it and the logo below together.
COLLECTION_TERMINAL_LOGO_URLurlnoThe logo for those tenants (https).
COLLECTION_TERMINAL_PRIMARY_COLORstringnoThe brand color for those tenants, #rgb or #rrggbb.
COLLECTION_TERMINAL_COLOR_SCHEMElight | dark | systemnolight, dark or system (the applicant's device) for those tenants.
COLLECTION_TERMINAL_SUPPORT_URLurlnoWhere "Help" leads for those tenants (https); a tenant's own support page or address replaces this and the address below together.
COLLECTION_TERMINAL_SUPPORT_EMAILstringnoThe support address for those tenants.
COLLECTION_TERMINAL_PRIVACY_URLurlnoThe privacy notice for those tenants (https).
COLLECTION_TERMINAL_TERMS_URLurlnoThe terms for those tenants (https).
COLLECTION_TERMINAL_RETURN_URLurlnoWhere "Back to …" leads after an approval, for those tenants (https).
COLLECTION_TERMINAL_SHOW_DECISIONtrue | falsefalsenotrue shows applicants the decision itself (approved, not approved) for flows that set no outcome visibility; false, where their application stands.

Webhooks ​

VariableTypeDefaultRequiredDescription
WEBHOOK_PUBLIC_URLurlnoPublic base URL vendors call back on (<url>/webhooks/apps/<app>).
WEBHOOK_ALLOW_PRIVATE_NETWORKStrue | falsefalsenoLets outbound webhooks reach http:// URLs and private, loopback and link-local addresses. For development stacks only: in production endpoints are https and public.

Object storage ​

VariableTypeDefaultRequiredDescription
STORAGE_ENDPOINTurlnoS3-compatible object storage for documents (Garage in the dev stack). Unset disables documents.
STORAGE_PUBLIC_ENDPOINTurlnoEndpoint browsers reach for direct uploads and downloads; defaults to STORAGE_ENDPOINT.
STORAGE_REGIONstringgarageno
STORAGE_BUCKETstringaletheia-documentsno
STORAGE_ACCESS_KEYstringno
STORAGE_SECRET_KEYstringno
STORAGE_CORS_ORIGINSstringnoComma-separated browser origins allowed to upload directly (the collection terminal and the admin console).

Documents ​

VariableTypeDefaultRequiredDescription
DOCUMENT_SCANNERnonenonenoDocument scanner engine; none marks every document clean (ClamAV is deferred).

OpenTelemetry ​

VariableTypeDefaultRequiredDescription
OTEL_EXPORTER_OTLP_ENDPOINTurlnoOTLP/HTTP collector base URL; unset disables tracing and metric export entirely.
OTEL_SERVICE_NAMEstringnoOverrides the default service name (aletheia-api, aletheia-worker).
OTEL_TRACES_SAMPLERstringno
OTEL_TRACES_SAMPLER_ARGstringno
OTEL_SDK_DISABLEDbooleanfalseno
OTEL_PG_STATEMENTSbooleanfalsenoInclude SQL statement text on database spans (postgres.js).

Metrics ​

VariableTypeDefaultRequiredDescription
METRICS_PORTinteger > 0noServes Prometheus /metrics on this port when set (API and worker use their own).

Worker ​

VariableTypeDefaultRequiredDescription
WORKER_HEALTH_PORTinteger > 0noThe worker's GET /healthz port; unset disables the health server.

Schema check ​

VariableTypeDefaultRequiredDescription
SCHEMA_CHECKstrict | lenientnoWhat to do when the database schema is behind the bundled migrations: strict refuses to start (production default), lenient logs a warning (development default).

General ​

VariableTypeDefaultRequiredDescription
NODE_ENVdevelopment | test | productiondevelopmentno
LOG_LEVELtrace | debug | info | warn | error | fatalinfono
SECRET_STORE_KEYstringno32 random bytes, base64: seals the secrets written through the API, app secrets and the signing secrets of outbound webhooks. Unset disables those writes (and outbound webhooks).
TRACE_URL_TEMPLATEstringnoA link to one trace in your tracing backend, with {traceId} where the id goes, such as https://grafana.example/explore?traceId={traceId}. A run's page links the trace of its start there for callers with ops:read; unset or empty, there is no link.
DEPLOYMENT_REGIONstringnoWhere this deployment keeps its data, as a label such as eu-fra; GET /tenants/me reports it as the tenant's region (Settings › Tenant). Unset or empty reports none.

Released under the Apache-2.0 License.