Skip to content

Environment Variables Reference

This guide covers all environment variables available in Onetime Secret v0.24+.

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_auth
AUTH_DATABASE_URL_MIGRATIONS=postgresql://onetime_migrator:CHANGEME@authdb/onetime_auth
RABBITMQ_URL=amqp://guest:guest@mqhost:5672/dev
# ═══════════════════════════════════════════════════════════
# SITE IDENTITY & CORE
# ═══════════════════════════════════════════════════════════
# Public hostname. Include port if non-standard.
HOST=localhost:3000
SSL=true
# Runtime environment
RACK_ENV=production
NODE_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=smtp
SMTP_HOST=
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_AUTH=login
SMTP_TLS=true
FROM_EMAIL=secure@onetimesecret.com
FROM_NAME=secure@onetimesecret.com
EMAILER_REGION=
VERIFIER_EMAIL=secure@onetimesecret.com
VERIFIER_DOMAIN=onetimesecret.com
# ═══════════════════════════════════════════════════════════
# AUTHENTICATION
# ═══════════════════════════════════════════════════════════
# 'full' enables Rodauth-based auth with PostgreSQL.
# Other modes may use simpler auth flows.
AUTHENTICATION_MODE=full
AUTH_ENABLED=true
AUTH_SIGNUP=true
AUTH_SIGNIN=true
AUTH_AUTOVERIFY=false
# Full-mode features
AUTH_EMAIL_AUTH_ENABLED=true
AUTH_LOCKOUT_ENABLED=true
AUTH_MFA_ENABLED=false
AUTH_WEBAUTHN_ENABLED=false
AUTH_PASSWORD_REQUIREMENTS_ENABLED=true
AUTH_ACTIVE_SESSIONS_ENABLED=true
AUTH_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=lettermint
LETTERMINT_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-tokens
LETTERMINT_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_URI
ENTRA_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_URI
GITHUB_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_URI
GOOGLE_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=false
DEFAULT_DOMAIN=
# Validation strategy: passthrough (default), approximated, caddy_on_demand
DOMAINS_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=false
JURISDICTION=
I18N_ENABLED=true
I18N_DEFAULT_LOCALE=en
INCOMING_ENABLED=false
INCOMING_RECIPIENT_1=
FOOTER_LINKS=true
PRICING_URL=/pricing
TERMS_URL=/terms
PRIVACY_URL=/privacy
STATUS_URL=
ABOUT_URL=/about
CONTACT_URL=/feedback
# Workspace footer links (authenticated users)
# Leave blank to use default computed URLs based on SUPPORT_HOST
WORKSPACE_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=true
SNEAKERS_PID_PATH=tmp/pids/sneakers.pid
SCHEDULER_PID_PATH=tmp/pids/scheduler.pid
WORKER_HEARTBEAT_INTERVAL=600

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.

Terminal window
SECRET=your-32-char-hex-key # Secret key for sessions and encryption (REQUIRED) - DO NOT change after setting
PORT=3000 # Port for the web server to listen on (default: 3000)
HOST=localhost:3000 # Host and port combination used for generating links
SSL=false # Controls https/http when generating links (set to true when behind a reverse proxy)
SERVER_TYPE=puma # Web server type: puma
RACK_ENV=production # Application environment: development, production, test
Terminal window
REDIS_URL=redis://localhost:6379/0 # Redis/Valkey connection string for sessions, secrets, and all application data

Variables beginning with REDIS_ can alternately be set with the VALKEY_ prefix (e.g., VALKEY_URL). The app accepts either.

Terminal window
AUTH_ENABLED=true # Enable authentication system (disables API auth when false)
AUTH_SIGNUP=true # Allow new user registration
AUTH_SIGNIN=true # Allow existing users to sign in
AUTH_AUTOVERIFY=false # Skip email verification for new accounts
AUTHENTICATION_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.

Terminal window
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 headers
HEADER_ENABLED=true # Show site header with branding
HEADER_NAV_ENABLED=true # Show navigation links in header
HEADER_PREFIX=
DOMAINS_ENABLED=false # Enable custom domain support
REGIONS_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.
Terminal window
LOGO_URL= # URL to custom logo image (defaults to built-in logo)
LOGO_ALT=
LOGO_LINK=
FOOTER_LINKS=
ABOUT_URL=
ABOUT_EXTERNAL=false
CONTACT_URL=
PRIVACY_URL=
PRIVACY_EXTERNAL=false
TERMS_URL=
TERMS_EXTERNAL=false
STATUS_URL=
STATUS_EXTERNAL=false
Terminal window
EMAILER_MODE=smtp # Email service mode (smtp, sendgrid, etc.)
EMAILER_REGION= # Email service region (for cloud providers)
FROM_EMAIL=noreply@localhost # Default sender email address
FROM= # Sender name (alternative to FROMNAME)
FROMNAME= # Display name for sender
SMTP_HOST= # SMTP server hostname
SMTP_PORT=587 # SMTP server port (usually 587 for TLS, 25 for plain)
SMTP_USERNAME= # SMTP authentication username
SMTP_PASSWORD= # SMTP authentication password
SMTP_TLS=true # Enable TLS encryption for SMTP
SMTP_AUTH=login # SMTP authentication method (login, plain, etc.)
Terminal window
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)

Email address validation is handled by the Truemail library, which supports multiple validation types including regex, MX record lookup, and SMTP verification.

Terminal window
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.

Terminal window
I18N_ENABLED=true # Enable internationalization
I18N_DEFAULT_LOCALE=en # Default language locale
Terminal window
ONETIME_DEBUG=false # Enable debug mode
LOG_HTTP_REQUESTS=false # Log HTTP requests
STDOUT_SYNC=true # Sync stdout output
DIAGNOSTICS_ENABLED=false # Enable diagnostics
FRONTEND_HOST=http://localhost:5173 # Frontend dev server URL (development only)
VITE_API_BASE_URL= # Vite API base URL override

See the sentry documentation for more information on configuring Sentry.

Terminal window
SENTRY_DSN=
SENTRY_DSN_BACKEND=
SENTRY_DSN_FRONTEND=
SENTRY_LOG_ERRORS=true
SENTRY_MAX_BREADCRUMBS=50
SENTRY_SAMPLE_RATE=1.0
SENTRY_VUE_TRACK_COMPONENTS=true