Settings are read from the environment and from api/.env. All are prefixed STRATL_ except where noted. api/.env.example in the backend repository is the same list with comments and no values.
| Variable |
Default |
Meaning |
ENV |
local |
local, test, staging or production. Staging and production turn on secure cookies, hide codes from the screen, and refuse the default secret key |
DATABASE_URL |
local Postgres stratl_dev |
The async SQLAlchemy URL. On Railway, ${{Postgres.DATABASE_URL}} |
LOG_LEVEL |
INFO |
Structured logs; never content |
WEB_ORIGIN |
http://localhost:5173 |
The browser origin allowed to call the API with cookies (local CORS only) |
PUBLIC_URL |
unset |
Where verifiers reach the API; written into records as custody.key_id_url |
| Variable |
Default |
Meaning |
CUSTODY_BACKEND |
local |
local (a key file and folders under CUSTODY_DIR) or s3-kms |
CUSTODY_DIR |
.stratl-custody |
Local backend folder |
DEFAULT_TENANT |
local |
The workspace used when authentication is off (tests) |
ARTIFACT_MAX_BYTES |
5 MiB |
Largest original accepted |
CUSTODY_REGIONS |
empty |
name=aws-region:bucket,… mapping sign-up regions to buckets; only listed regions are offered at sign-up |
AWS_REGION, S3_BUCKET, S3_PREFIX |
ap-south-1, unset, empty |
The single default placement when CUSTODY_REGIONS is empty |
KMS_ALIAS_PREFIX |
stratl |
KMS aliases are alias/<prefix>-<workspace> |
CHECKPOINT_INTERVAL_SECONDS |
3600 |
Seal when the oldest pending record is this old |
CHECKPOINT_MAX_RECORDS |
1000 |
Or when this many are pending |
TSA_URL |
freetsa.org, then DigiCert |
Comma-separated RFC 3161 authorities, tried in order. Empty disables timestamping (tests only) |
CUSTODY_REPLICATE_BATCH |
200 |
Records copied per tick after taking custody |
STRATL_AWS_ACCOUNT_ID, GCP_SERVICE_ACCOUNT, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET |
unset |
The identities customers grant for bring-your-own custody, shown in the portal |
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY (no prefix) |
unset |
Read by the AWS SDK for managed custody |
| Variable |
Default |
Meaning |
SYNC_ENABLED |
true |
The in-process scheduler: connector runs, checkpoints, key-ledger sealing, custody replication, clean-up |
SYNC_TICK_SECONDS |
30 |
How often it wakes |
LANGFUSE_SECRET_KEY, ANTHROPIC_COMPLIANCE_ACCESS_KEY (no prefix) |
unset |
Referenced by connectors as env:NAME; any variable name works |
| Variable |
Default |
Meaning |
AUTH_MODE |
required |
off exists for the test suite only and makes every endpoint public |
SECRET_KEY |
a public default |
Peppers the code hashes. Generate with openssl rand -base64 48. Changing it voids codes waiting to be used |
SESSION_DAYS |
30 |
Session lifetime |
OTP_TTL_SECONDS, OTP_MAX_ATTEMPTS, OTP_RESEND_SECONDS, OTP_MAX_PER_WINDOW |
600, 5, 60, 5 |
Code rules |
INVITE_TTL_DAYS, INVITE_MAX_PENDING, INVITE_MAX_PER_HOUR |
7, 25, 20 |
Invitation rules |
OTP_PURGE_HOURS, INVITE_PURGE_DAYS |
24, 30 |
Clean-up of used and expired rows |
| Variable |
Default |
Meaning |
RESEND_API_KEY, RESEND_FROM_EMAIL, RESEND_FROM_NAME (also read without prefix) |
unset, onboarding@resend.dev, Stratl |
Codes, invitations and notices. Without a key, codes are logged and, locally, shown on screen; notices are logged and marked dev_log |
NOTICE_USE_LLM |
true |
Draft notices with Claude when ANTHROPIC_API_KEY (no prefix) is set, otherwise the template |
NOTICE_MODEL |
claude-opus-5 |
The model used |
| Variable |
Meaning |
VITE_PUBLIC_API_URL |
Only the address printed in Get started snippets. The browser itself always calls /api, which the dev server or vercel.json forwards |
VITE_DOCS_URL |
Where the Docs icon points; defaults to https://docs.stratl.ai |