Environment Variables Reference
This guide covers all environment variables available in Onetime Secret v0.24+.
Environment Variables
Section titled “Environment Variables”Set these in your .env file or environment or add them to your docker commands or docker-compose.yml file. All variables are optional unless marked as required.
# Variables marked [derived] are generated by `rake ots:init` via HKDF from SECRET.
# ═══════════════════════════════════════════════════════════# SECRETS & CRYPTOGRAPHY# ═══════════════════════════════════════════════════════════
# Root secret. All derived secrets use HKDF (RFC 5869) with# this as input keying material. Backup this value securely.# Changing it will invalidate all secrets. Required.SECRET=
# [derived] Rack session signing key#SESSION_SECRET=
# [derived] Secret link verification key (Familia::VerifiableIdentifier).# Used to generate secret/receipt keys. Derived from SECRET via HKDF.#IDENTIFIER_SECRET=
# HMAC key for Rodauth auth operations (TOTP, login tokens).# Cannot be recovered from SECRET. Back this up.#AUTH_SECRET=
# Argon2 pepper for password hashing (full auth mode).# Folded into every password hash via Rodauth's argon2_secret.# Cannot be recovered from SECRET. WARNING: Changing this invalidates# ALL existing password hashes. Back this up.# See: apps/web/auth/config/features/argon2.rb#ARGON2_SECRET=
# Cross-region subscription federation.# Must be identical across all regions in a multi-region deploy.# Not auto-generated — set manually and share across instances.#FEDERATION_SECRET=
# ═══════════════════════════════════════════════════════════# CONNECTIONS# ═══════════════════════════════════════════════════════════
# Required (one of)REDIS_URL='redis://maindb:5212/0?timeout=5'VALKEY_URL=
# Required for full auth mode (PostgreSQL + RabbitMQ)AUTH_DATABASE_URL=postgresql://onetime_user:CHANGEME@authdb/onetime_authAUTH_DATABASE_URL_MIGRATIONS=postgresql://onetime_migrator:CHANGEME@authdb/onetime_authRABBITMQ_URL=amqp://guest:guest@mqhost:5672/dev
# ═══════════════════════════════════════════════════════════# SITE IDENTITY & CORE# ═══════════════════════════════════════════════════════════
# Public hostname. Include port if non-standard.HOST=localhost:3000SSL=true
# Runtime environmentRACK_ENV=productionNODE_ENV=production
# ═══════════════════════════════════════════════════════════# SECRET TTL CONFIGURATION# ═══════════════════════════════════════════════════════════
# Available TTL choices for users (space-separated seconds).# Example: '300 3600 86400 604800 2592000'# 5m 1h 1d 7d 30d#TTL_OPTIONS=
# Default TTL when not specified (seconds). Default: 604800 (7 days)#DEFAULT_TTL=604800
# Maximum TTL for anonymous/free tier users (seconds).# Default: 604800 (7 days). Max: 31536000 (365 days).# Clamped between 0 and 365 days; invalid values use default.# @see https://github.com/onetimesecret/onetimesecret/issues/2390#PLAN_TTL_ANONYMOUS=604800
# ═══════════════════════════════════════════════════════════# EMAIL# ═══════════════════════════════════════════════════════════
EMAILER_MODE=smtpSMTP_HOST=SMTP_PORT=587SMTP_USERNAME=SMTP_PASSWORD=SMTP_AUTH=loginSMTP_TLS=true
FROM_EMAIL=secure@onetimesecret.comFROM_NAME=secure@onetimesecret.com
EMAILER_REGION=VERIFIER_EMAIL=secure@onetimesecret.comVERIFIER_DOMAIN=onetimesecret.com
# ═══════════════════════════════════════════════════════════# AUTHENTICATION# ═══════════════════════════════════════════════════════════
# 'full' enables Rodauth-based auth with PostgreSQL.# Other modes may use simpler auth flows.AUTHENTICATION_MODE=full
AUTH_ENABLED=trueAUTH_SIGNUP=trueAUTH_SIGNIN=trueAUTH_AUTOVERIFY=false
# Full-mode featuresAUTH_EMAIL_AUTH_ENABLED=trueAUTH_LOCKOUT_ENABLED=trueAUTH_MFA_ENABLED=falseAUTH_WEBAUTHN_ENABLED=falseAUTH_PASSWORD_REQUIREMENTS_ENABLED=trueAUTH_ACTIVE_SESSIONS_ENABLED=trueAUTH_VERIFY_ACCOUNT_ENABLED=true
# Restrict the login page to a single authentication method.# Set exactly ONE of these to 'true'. The result maps to# full.restrict_to in auth config (values: password, email_auth,# webauthn, sso). If more than one is set, all are ignored# (safe fallback to showing all enabled methods).# If none are set, all enabled methods are shown (default).#AUTH_PASSWORD_ONLY=false#AUTH_EMAIL_AUTH_ONLY=false#AUTH_WEBAUTHN_ONLY=false#AUTH_SSO_ONLY=false
# ═══════════════════════════════════════════════════════════# ORGANIZATIONS# ═══════════════════════════════════════════════════════════
# Toggle on to show the Organizations context switcher in the UI, next to# the equivalent Domain context switcher. This allows users to update their# default organization settings and add additional organizations to their# account. When billing is enabled, the subscription plans are per-org.ENABLE_ORGS=false
# When enabled, allows organizations with the manage_sso entitlement to# configure SSO for each of their custom domains.ORGS_SSO_ENABLED=false
# When enabled, allows organizations with the custom_mail_sender entitlement# to configure custom sender identity (from name, from address) for their# domains. Uses installation-level email provider credentials.ORGS_CUSTOM_MAIL_ENABLED=false
# When enabled, allows organizations with the incoming_secrets entitlement# to configure incoming secret receiving for their custom domains. Secrets# sent to the domain are routed to the organization's inbox.ORGS_INCOMING_SECRETS_ENABLED=false
# ═══════════════════════════════════════════════════════════# EMAIL PROVIDER DNS SETTINGS# ═══════════════════════════════════════════════════════════# These settings control DNS record generation for DKIM, SPF, and related# email authentication when setting up custom mail sender domains.# The installation-level email provider (EMAILER_MODE) handles sending;# these settings generate the correct DNS records for domain verification.
# --- AWS SES ---# AWS region for SES endpoints (affects MX record values).# Default: us-east-1#EMAIL_PROVIDERS_SES_REGION=us-east-1
# --- SendGrid ---# Subdomain for SendGrid domain authentication.# Default: em#EMAIL_PROVIDERS_SENDGRID_SUBDOMAIN=em
# --- Lettermint ---# Lettermint has TWO separate APIs with different auth:# 1. Sending API - uses x-lettermint-token header (project token)# 2. Team API - uses Authorization: Bearer header (team token)## Project token for Lettermint Sending API (email delivery).# Required when EMAILER_MODE=lettermintLETTERMINT_API_TOKEN=
# Team token for Lettermint Team API (domain provisioning).# Required for custom mail sender domain management (ORGS_CUSTOM_MAIL_ENABLED=true)# https://dash.lettermint.co/team/api-tokensLETTERMINT_TEAM_TOKEN=
# API base URL (for enterprise/on-premise deployments).# Default: https://api.lettermint.co/v1#LETTERMINT_BASE_URL=https://api.lettermint.co/v1
# SPF include domain.# Default: lettermint.co#EMAIL_PROVIDERS_LETTERMINT_SPF_INCLUDE=lettermint.co
# ═══════════════════════════════════════════════════════════# SSO / OMNIAUTH# ═══════════════════════════════════════════════════════════
# Master toggle for SSO. Must be true for any provider below.AUTH_SSO_ENABLED=false
# [deprecated] Use per-provider DISPLAY_NAME vars instead.#SSO_DISPLAY_NAME=
# --- Generic OIDC provider ---# Required: OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_REDIRECT_URI# Optional: OIDC_CLIENT_SECRET (omit for PKCE-only flows)OIDC_ISSUER=OIDC_CLIENT_ID=OIDC_CLIENT_SECRET=OIDC_REDIRECT_URI=https://example.com/auth/sso/oidc/callback#OIDC_ROUTE_NAME=oidc
# --- Microsoft Entra ID ---# Required: ENTRA_TENANT_ID, ENTRA_CLIENT_ID, ENTRA_CLIENT_SECRET, ENTRA_REDIRECT_URIENTRA_TENANT_ID=ENTRA_CLIENT_ID=ENTRA_CLIENT_SECRET=ENTRA_REDIRECT_URI=https://example.com/auth/sso/entra/callback#ENTRA_ROUTE_NAME=entra#ENTRA_DISPLAY_NAME=Microsoft
# --- GitHub ---# Required: GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_REDIRECT_URIGITHUB_CLIENT_ID=GITHUB_CLIENT_SECRET=GITHUB_REDIRECT_URI=https://example.com/auth/sso/github/callback#GITHUB_ROUTE_NAME=github#GITHUB_DISPLAY_NAME=GitHub
# --- Google ---# Required: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URIGOOGLE_CLIENT_ID=GOOGLE_CLIENT_SECRET=GOOGLE_REDIRECT_URI=https://example.com/auth/sso/google/callback#GOOGLE_ROUTE_NAME=google#GOOGLE_DISPLAY_NAME=Google
# ═══════════════════════════════════════════════════════════# STRIPE BILLING# ═══════════════════════════════════════════════════════════
STRIPE_API_KEY=PUBLIC_STRIPE_API_KEY=STRIPE_WEBHOOK_SIGNING_SECRET=
# ═══════════════════════════════════════════════════════════# CUSTOM DOMAINS# ═══════════════════════════════════════════════════════════
DOMAINS_ENABLED=falseDEFAULT_DOMAIN=
# Validation strategy: passthrough (default), approximated, caddy_on_demandDOMAINS_VALIDATION_STRATEGY=passthrough
# Approximated provider settings (when strategy=approximated)APPROXIMATED_API_KEY=APPROXIMATED_PROXY_IP=APPROXIMATED_PROXY_HOST=APPROXIMATED_PROXY_NAME=APPROXIMATED_VHOST_TARGET=
# ═══════════════════════════════════════════════════════════# FEATURE FLAGS# ═══════════════════════════════════════════════════════════
REGIONS_ENABLED=falseJURISDICTION=
I18N_ENABLED=trueI18N_DEFAULT_LOCALE=en
INCOMING_ENABLED=falseINCOMING_RECIPIENT_1=
FOOTER_LINKS=truePRICING_URL=/pricingTERMS_URL=/termsPRIVACY_URL=/privacySTATUS_URL=ABOUT_URL=/aboutCONTACT_URL=/feedback
# Workspace footer links (authenticated users)# Leave blank to use default computed URLs based on SUPPORT_HOSTWORKSPACE_API_DOCS_URL=WORKSPACE_BRANDING_GUIDE_URL=WORKSPACE_FEEDBACK_URL=/feedback
# ═══════════════════════════════════════════════════════════# UI / HOMEPAGE# ═══════════════════════════════════════════════════════════
# Controls homepage experience based on IP/headers.# Mode: 'internal', 'external', or blank (default)UI_HOMEPAGE_MODE=UI_HOMEPAGE_MATCHING_CIDRS=UI_HOMEPAGE_MODE_HEADER=UI_HOMEPAGE_DEFAULT_MODE=UI_HOMEPAGE_TRUSTED_PROXY_DEPTH=UI_HOMEPAGE_TRUSTED_IP_HEADER=
# One of: DefaultLogo.vue, LegacyLogo.vue, OnetimeSecretLogo.vue#LOGO_URL=
# Company name used in page titles, MFA authenticator labels, and header logo text.#SITE_NAME=One-Time Secret
# Whether to show the site name text next to the logo icon in the masthead.# Set to 'false' to display icon-only while keeping SITE_NAME for titles and MFA.#LOGO_SHOW_NAME=true
# ═══════════════════════════════════════════════════════════# JOB SYSTEM# ═══════════════════════════════════════════════════════════
JOBS_ENABLED=trueSNEAKERS_PID_PATH=tmp/pids/sneakers.pidSCHEDULER_PID_PATH=tmp/pids/scheduler.pidWORKER_HEARTBEAT_INTERVAL=600Set these in your .env file or environment or add them to your docker commands or docker-compose.yml file. All variables are optional unless marked as required.
Core Application Settings
Section titled “Core Application Settings”SECRET=your-32-char-hex-key # Secret key for sessions and encryption (REQUIRED) - DO NOT change after settingPORT=3000 # Port for the web server to listen on (default: 3000)HOST=localhost:3000 # Host and port combination used for generating linksSSL=false # Controls https/http when generating links (set to true when behind a reverse proxy)SERVER_TYPE=puma # Web server type: pumaRACK_ENV=production # Application environment: development, production, testDatabase & Storage
Section titled “Database & Storage”REDIS_URL=redis://localhost:6379/0 # Redis/Valkey connection string for sessions, secrets, and all application dataVariables beginning with REDIS_ can alternately be set with the VALKEY_ prefix (e.g., VALKEY_URL). The app accepts either.
Authentication & Security
Section titled “Authentication & Security”AUTH_ENABLED=true # Enable authentication system (disables API auth when false)AUTH_SIGNUP=true # Allow new user registrationAUTH_SIGNIN=true # Allow existing users to sign inAUTH_AUTOVERIFY=false # Skip email verification for new accountsAUTHENTICATION_MODE=simple # Authentication mode: none, simple, full (full requires PostgreSQL + RabbitMQ)AUTH_DATABASE_URL= # Database URL for auth (only used in full mode, configured in etc/config.yaml)FEDERATION_SECRET= # Secret for federation between instances (auto-generated by `install.sh init` as a multi-word passphrase)Note: “Colonel” is our term for “admin” users. Colonel accounts are created using bin/ots customer create email@example.com && bin/ots customer promote email@example.com. Colonels can access the admin area at /colonel which shows basic system stats. The admin interface currently has limited functionality - no user management and only readonly configuration viewing.
User Interface & Features
Section titled “User Interface & Features”UI_ENABLED=true # Enable web user interface (shows minimal page when disabled)API_ENABLED=true # Enable REST API endpoints (returns 404 when disabled)CSP_ENABLED=true # Enable Content Security Policy headersHEADER_ENABLED=true # Show site header with brandingHEADER_NAV_ENABLED=true # Show navigation links in headerHEADER_PREFIX=DOMAINS_ENABLED=false # Enable custom domain supportREGIONS_ENABLED=false # Enable multi-region deployment support. This doesn't affect # the functionality of the application. But it does enable UI # components for linking to other regions.Branding & Content
Section titled “Branding & Content”LOGO_URL= # URL to custom logo image (defaults to built-in logo)LOGO_ALT=LOGO_LINK=FOOTER_LINKS=ABOUT_URL=ABOUT_EXTERNAL=falseCONTACT_URL=PRIVACY_URL=PRIVACY_EXTERNAL=falseTERMS_URL=TERMS_EXTERNAL=falseSTATUS_URL=STATUS_EXTERNAL=falseSending Emails
Section titled “Sending Emails”EMAILER_MODE=smtp # Email service mode (smtp, sendgrid, etc.)EMAILER_REGION= # Email service region (for cloud providers)FROM_EMAIL=noreply@localhost # Default sender email addressFROM= # Sender name (alternative to FROMNAME)FROMNAME= # Display name for senderSMTP_HOST= # SMTP server hostnameSMTP_PORT=587 # SMTP server port (usually 587 for TLS, 25 for plain)SMTP_USERNAME= # SMTP authentication usernameSMTP_PASSWORD= # SMTP authentication passwordSMTP_TLS=true # Enable TLS encryption for SMTPSMTP_AUTH=login # SMTP authentication method (login, plain, etc.)Secrets & TTL
Section titled “Secrets & TTL”DEFAULT_TTL=604800 # Default secret expiration in seconds (604800 = 7 days)TTL_OPTIONS=300,1800,3600,86400 # Available TTL options presented to users, comma separated (seconds)DEFAULT_DOMAIN= # Default domain for secret links (uses HOST if empty)ALLOW_NIL_GLOBAL_SECRET=false # Allow operation with missing SECRET key (emergency recovery)Validating Email Addresses
Section titled “Validating Email Addresses”Email address validation is handled by the Truemail library, which supports multiple validation types including regex, MX record lookup, and SMTP verification.
VERIFIER_DOMAIN= # Domain for SMTP verification (required for SMTP validation)VERIFIER_EMAIL= # Email address for SMTP verification (required for SMTP validation)Note: Many additional Truemail configuration options are available in the YAML config under the truemail: section, including validation types, timeout settings, allowed/blocked domains, DNS servers, and more. See etc/config.yaml for the full configuration.
Internationalization
Section titled “Internationalization”I18N_ENABLED=true # Enable internationalizationI18N_DEFAULT_LOCALE=en # Default language localeDevelopment & Debugging
Section titled “Development & Debugging”ONETIME_DEBUG=false # Enable debug modeLOG_HTTP_REQUESTS=false # Log HTTP requestsSTDOUT_SYNC=true # Sync stdout outputDIAGNOSTICS_ENABLED=false # Enable diagnosticsFRONTEND_HOST=http://localhost:5173 # Frontend dev server URL (development only)VITE_API_BASE_URL= # Vite API base URL overrideMonitoring & Error Tracking
Section titled “Monitoring & Error Tracking”See the sentry documentation for more information on configuring Sentry.
SENTRY_DSN=SENTRY_DSN_BACKEND=SENTRY_DSN_FRONTEND=SENTRY_LOG_ERRORS=trueSENTRY_MAX_BREADCRUMBS=50SENTRY_SAMPLE_RATE=1.0SENTRY_VUE_TRACK_COMPONENTS=true