Trailscope reads configuration in three layers, each overriding the one before:
Built-in defaults.
trailscope.toml: ./trailscope.toml if it exists, or the file given with --config or $TRAILSCOPE_CONFIG (which must exist).
Environment variables TRAILSCOPE_<SECTION>_<KEY>, e.g. TRAILSCOPE_CLICKHOUSE_URL sets [clickhouse] url. An empty variable counts as unset, so the compose files can pass optional settings through (TRAILSCOPE_SMTP_HOST: ${TRAILSCOPE_SMTP_HOST:-}) without overriding anything when you leave them out of deploy/.env.
Values that look like numbers are fine for string settings: TRAILSCOPE_CLICKHOUSE_PASSWORD=123456 stays the string "123456". List values in env vars use TOML array syntax: TRAILSCOPE_SERVER_CORS_ORIGINS='["https://a.example"]'.
TTLs are applied to the ClickHouse tables by trailscope migrate (and at startup in all mode). Changing them updates the TTLs in place; existing parts expire as they merge, without a rewrite. The UI shows these values read-only.
Key
Env
Default
Description
days
TRAILSCOPE_RETENTION_DAYS
30
Raw rows and rollups
body_days
TRAILSCOPE_RETENTION_BODY_DAYS
7
Request/response bodies and headers. Must be ≤ days
Encrypts stored secrets (SMTP password, channel URLs and tokens) and signs mute links. When empty, a key is generated and kept in Postgres. Set a long random value in production (openssl rand -base64 48); changing it makes stored secrets unreadable. See alerts.md
Email notifications. Each field can also be entered in the UI (Settings → Notifications). A field set here or through its env var takes precedence over the UI value and shows as locked in the UI. Full details are in alerts.md.
Key
Env
Default
Description
host
TRAILSCOPE_SMTP_HOST
empty
Empty disables email (unless configured in the UI)
port
TRAILSCOPE_SMTP_PORT
587
security
TRAILSCOPE_SMTP_SECURITY
starttls
starttls, tls (implicit TLS, usually port 465) or none
username
TRAILSCOPE_SMTP_USERNAME
empty
Empty sends without authentication
password
TRAILSCOPE_SMTP_PASSWORD
empty
from
TRAILSCOPE_SMTP_FROM
empty
Sender address, e.g. trailscope@example.com. Required to send
Optional single sign-on with any OpenID Connect provider (Google, Microsoft Entra ID, Okta, Auth0, Keycloak, Authentik, Dex…), using the authorization code flow with PKCE. Password sign-in keeps working alongside it.
Key
Env
Default
Description
issuer
TRAILSCOPE_OIDC_ISSUER
empty
Issuer URL; <issuer>/.well-known/openid-configuration must exist. Empty disables OIDC
client_id
TRAILSCOPE_OIDC_CLIENT_ID
empty
client_secret
TRAILSCOPE_OIDC_CLIENT_SECRET
empty
display_name
TRAILSCOPE_OIDC_DISPLAY_NAME
empty
Label on the sign-in button (“Sign in with …”)
auto_create_domains
TRAILSCOPE_OIDC_AUTO_CREATE_DOMAINS
[]
Email domains whose users get a viewer account in the instance’s first organization on first sign-in, e.g. '["example.com"]'
Register <server.public_url>/api/v1/auth/oidc/callback as the redirect URI at the provider, with the scopes openid email profile. On sign-in, Trailscope matches the provider’s subject to a member, then the email address (which must not be marked unverified), and remembers the subject. Someone without an account is signed in only if their email domain is in auto_create_domains; everyone else needs an invite first. Disabled members can’t sign in either way.
Hosted, multi-tenant mode (Trailscope Cloud). Every install counts accepted events per organization, so the admin console shows usage; only with this on are plan limits enforced.
Key
Env
Default
Description
enabled
TRAILSCOPE_CLOUD_ENABLED
false
Enforce each organization’s plan: ingest refuses a suspended organization (403) and one past a plan’s hard monthly limit (429 with Retry-After until the next month, UTC); the API refuses projects and invites beyond the plan’s caps. The organization’s members see their plan and usage under Settings → Organization
Plans are tiers of limits, managed through the management API (below): Free (1M events a month, stops at the limit, 2 projects, 3 members), Team (10M) and Business (50M) come preinstalled. Prices and billing aren’t part of Trailscope; they belong in the operator’s own tools. An event is a request, a job run or a log line; spans are free. Limits are checked from memory and refreshed every 5 seconds, so an organization can go a few seconds’ worth of traffic past its limit.
Turns on the management API under /api/v1/admin (every organization, its plan, limits, suspension, owner invites; plans), answered only to Authorization: Bearer <token>. Use 32 characters or more (openssl rand -hex 32); empty or shorter leaves it off. Meant for the operator’s own tools, such as a separate admin dashboard; sessions and API tokens never reach it