Skip to content

Configuration

The backend reads settings from environment variables prefixed STEPT_ (or a .env file in backend/). Unknown variables are ignored.

VariableDefaultPurpose
STEPT_ENVdevdev | test | prod — prod enables the boot guardrails
STEPT_SECRET_KEYdev-secret-key-change-meSigns all JWTs and derives the encryption key (see warning below)
STEPT_BACKEND_PORT8600API port
STEPT_PUBLIC_BASE_URLhttp://localhost:8600Public API origin — widget snippet src, OAuth redirect URIs
STEPT_APP_BASE_URLhttp://localhost:5273Dashboard origin — CORS allow-list seed, links in emails
STEPT_CORS_ORIGINS[]Extra allowed origins for the dashboard API
STEPT_EXTENSION_WEB_STORE_URLemptyChrome Web Store link shown for the recorder extension
VariableDefaultPurpose
STEPT_DATABASE_URLsqlite+aiosqlite:///./stept.dbUse postgresql+asyncpg://… in production (pgvector)
STEPT_REDIS_URLunsetEnables the ARQ worker queue, Redis rate limits and pub/sub. Unset = in-process fallbacks (single node only)
STEPT_DB_POOL_SIZE10Connection pool size
STEPT_STORAGE_DIR./data/uploadsAttachment/upload storage path
STEPT_MAX_UPLOAD_MB25Upload size cap
VariableDefaultPurpose
STEPT_ACCESS_TOKEN_TTL_MINUTES15Access-token lifetime
STEPT_REFRESH_TOKEN_TTL_DAYS30Refresh-cookie lifetime (rotating, reuse-detected)
STEPT_INVITATION_TTL_DAYS7Member invitation validity
STEPT_RATE_LIMIT_ENABLEDtrueToggle for the abuse rate limits
STEPT_TRUSTED_PROXY_HOPS0How many X-Forwarded-For hops to trust (e.g. 2 behind Cloudflare + Caddy)
STEPT_EXPOSE_API_DOCSunsetOpenAPI/Swagger at /api/v1/docs — on unless env=prod; set to force either way
VariableDefaultPurpose
STEPT_SMTP_HOSTunsetUnset = transactional email is only logged to the console (invites, password resets)
STEPT_SMTP_PORT25
STEPT_SMTP_USER / STEPT_SMTP_PASSWORDunset
STEPT_SMTP_TLSfalse
STEPT_EMAIL_FROMStept <[email protected]>From header
STEPT_INBOUND_EMAIL_DOMAINunsetEnables auto-generated in-{hex}@{domain} forwarding addresses on email inboxes

Per-inbox email transports (SES, Resend, Postmark, SendGrid, Mailgun, per-inbox SMTP, Gmail/Microsoft OAuth) are configured per inbox in the dashboard, not via env vars.

Integration credentials (instance-level OAuth apps)

Section titled “Integration credentials (instance-level OAuth apps)”
VariablePurpose
STEPT_GOOGLE_CLIENT_ID / STEPT_GOOGLE_CLIENT_SECRETGmail + Google Drive
STEPT_MICROSOFT_CLIENT_ID / STEPT_MICROSOFT_CLIENT_SECRETMicrosoft 365
STEPT_SLACK_CLIENT_ID / STEPT_SLACK_CLIENT_SECRET / STEPT_SLACK_SIGNING_SECRETSlack
STEPT_NOTION_CLIENT_ID / STEPT_NOTION_CLIENT_SECRETNotion
STEPT_CONFLUENCE_CLIENT_ID / STEPT_CONFLUENCE_CLIENT_SECRETConfluence
STEPT_OAUTH_BASE_OVERRIDEDev/test only: redirect OAuth endpoints at a stub

Workspaces can override any of these with their own OAuth app in the dashboard — the workspace credential always wins. AI provider keys (OpenAI, Anthropic, …) are not env vars: each workspace adds them in the dashboard, encrypted at rest.

VariableDefaultPurpose
STEPT_EMBEDDING_DIM384Vector dimension of the local fallback embedder
VariableDefaultPurpose
STEPT_SCHEDULER_ENABLEDtruePeriodic jobs (SLA scans, scheduled syncs). In the compose stack it runs in a dedicated single-replica scheduler container and is disabled on api
STEPT_SCHEDULER_TICK_SECONDS15Scheduler tick interval
STEPT_WEB_CONCURRENCY4 (deploy)uvicorn worker count (read by the container entrypoint)
STEPT_API_KEYunsetMCP stdio mode only — the client credential; never authenticates HTTP

STEPT_SECRET_KEY is load-bearing twice: it signs every JWT (sessions, widget tokens, password resets, extension tokens, OAuth state) and the encryption key for stored secrets — AI provider keys, channel credentials, OAuth tokens — is derived from it. Rotating it invalidates all stored credentials, which then need re-entering. Generate a strong one once: python -c 'import secrets; print(secrets.token_urlsafe(48))'.

With STEPT_ENV=prod the app refuses to boot if the secret key is a known default or shorter than 32 characters, or if either base URL is non-localhost http://. Database schema comes from migrations in prod (docker compose run --rm api migrate) — auto table creation only runs in dev.