コンテンツにスキップ

Features and branding configuration

このコンテンツは、現在ご利用の言語ではまだ提供されていません。

This reference reflects Onetime Secret v0.26.19 (e98a88c9).

config file: site

config: site.secret_options.default_ttl

Default Time-To-Live (TTL) for secrets in seconds
This value is used if no specific TTL is provided when creating a secret
ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueDEFAULT_TTLno valuenot annotatedetc/defaults/config.defaults.yaml:255

config: site.secret_options.ttl_options

Available TTL options for secret creation (in seconds)
These options will be presented to users when they create a new secret
Format: String of integers representing seconds
ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueTTL_OPTIONSno valuenot annotatedetc/defaults/config.defaults.yaml:259

config: site.secret_options.ttl_max_anonymous

Maximum TTL for secrets created without an account (anonymous callers).
Default: 604800 (7 days) — a sane default, not a hard limit. Self-hosted
deployments may raise or lower it; the effective ceiling is the lower of
this value and the ttl_options maximum, bounded by 365 days. When billing
is enabled the free-tier plan limit applies as well, so the anonymous
grant never exceeds what an authenticated free-tier user receives.

PLAN_TTL_ANONYMOUS is the deprecated alias, read only here — this line is
the single place the old name survives. The ceiling itself is read from
the resolved config key (site.secret_options.ttl_max_anonymous) via
WithEntitlements.configured_anonymous_max_ttl, never from the env var.
Organization.free_tier_limits does read ENV['TTL_MAX_ANONYMOUS'] directly
for its secret_lifetime fallback, and does not honour the alias.
ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueTTL_MAX_ANONYMOUS, PLAN_TTL_ANONYMOUSno valuev0.26.3etc/defaults/config.defaults.yaml:273

config: site.secret_options.passphrase.required

Require users to enter a passphrase when creating secrets
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalsePASSPHRASE_REQUIREDfalsenot annotatedetc/defaults/config.defaults.yaml:277

config: site.secret_options.passphrase.minimum_length

Minimum number of characters required for passphrases
Default to 4 chars to prevent trivially guessable passphrases while
maintaining backward compatibility with existing integrations.
ShapeValueEnvironment variablesWhen unsetSinceSource
string4PASSPHRASE_MIN_LENGTHthe value abovenot annotatedetc/defaults/config.defaults.yaml:281

config: site.secret_options.passphrase.maximum_length

Maximum number of characters allowed for passphrases
ShapeValueEnvironment variablesWhen unsetSinceSource
string128PASSPHRASE_MAX_LENGTHthe value abovenot annotatedetc/defaults/config.defaults.yaml:283

config: site.secret_options.passphrase.enforce_complexity

Enforce complexity requirements (uppercase, lowercase, numbers, symbols)
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalsePASSPHRASE_ENFORCE_COMPLEXITYfalsenot annotatedetc/defaults/config.defaults.yaml:285

config: site.secret_options.content.maximum_length

Maximum number of characters allowed in a secret's body. Enforced
server-side on secret creation and used as the single source of
truth for the client-side textarea limit.
ShapeValueEnvironment variablesWhen unsetSinceSource
string10000SECRET_MAX_LENGTHthe value abovev0.26.0etc/defaults/config.defaults.yaml:291

config: site.secret_options.generated_value_display_ttl

How long (in seconds) a generated password remains visible on the
receipt page after creation. Set to 0 to disable receipt-page display.
ShapeValueEnvironment variablesWhen unsetSinceSource
string60GENERATED_VALUE_DISPLAY_TTLthe value abovev0.24.0etc/defaults/config.defaults.yaml:294

config: site.secret_options.create_rate_limit.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueSECRET_CREATE_RATE_LIMIT_ENABLEDtruev0.26.11etc/defaults/config.defaults.yaml:310

config: site.secret_options.create_rate_limit.max_per_ip

Anonymous creations permitted per window from a single masked client IP.
The bucket is a whole /24 (office, campus NAT), and behind an
unconfigured reverse proxy it is the entire deployment — so this is
deliberately loose (10x the signup/reset caps) because secret creation is
the core product action. Raise it for dense-NAT populations; a too-tight
value here is an outage of secret creation for a whole neighborhood.
ShapeValueEnvironment variablesWhen unsetSinceSource
string500SECRET_CREATE_RATE_LIMIT_MAX_PER_IPthe value abovev0.26.11etc/defaults/config.defaults.yaml:317

config: site.secret_options.create_rate_limit.window

Counting window in seconds (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SECRET_CREATE_RATE_LIMIT_WINDOWthe value abovev0.26.11etc/defaults/config.defaults.yaml:319

config: site.secret_options.create_rate_limit.lockout

Lockout duration in seconds once the cap is hit (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SECRET_CREATE_RATE_LIMIT_LOCKOUTthe value abovev0.26.11etc/defaults/config.defaults.yaml:321

config: site.secret_options.password_generation.default_length

Default length for generated passwords
ShapeValueEnvironment variablesWhen unsetSinceSource
string12PASSWORD_GEN_LENGTHthe value abovenot annotatedetc/defaults/config.defaults.yaml:325

config: site.secret_options.password_generation.maximum_length

Server-enforced ceiling on requested generated-password length.
Rejects oversized `length` values before allocation (DoS guard);
matches the frontend Zod max so the two limits stay in lockstep.
ShapeValueEnvironment variablesWhen unsetSinceSource
string128PASSWORD_GEN_MAX_LENGTHthe value abovev0.26.0etc/defaults/config.defaults.yaml:329

config: site.secret_options.password_generation.character_sets.uppercase

Include uppercase letters (A-Z)
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valuePASSWORD_GEN_UPPERCASEtruenot annotatedetc/defaults/config.defaults.yaml:333

config: site.secret_options.password_generation.character_sets.lowercase

Include lowercase letters (a-z)
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valuePASSWORD_GEN_LOWERCASEtruenot annotatedetc/defaults/config.defaults.yaml:335

config: site.secret_options.password_generation.character_sets.numbers

Include numbers (0-9)
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valuePASSWORD_GEN_NUMBERStruenot annotatedetc/defaults/config.defaults.yaml:337

config: site.secret_options.password_generation.character_sets.symbols

Include symbols (!@#$%^&*()_+-=[]{}|;:,.<>?)
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valuePASSWORD_GEN_SYMBOLStruenot annotatedetc/defaults/config.defaults.yaml:339

config: site.secret_options.password_generation.character_sets.exclude_ambiguous

Exclude ambiguous characters (0, O, l, 1, I) to prevent confusion
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valuePASSWORD_GEN_EXCLUDE_AMBIGUOUStruenot annotatedetc/defaults/config.defaults.yaml:341

config: site.authentication.enabled

Can be disabled altogether, including API authentication.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueAUTH_ENABLEDtruenot annotatedetc/defaults/config.defaults.yaml:345

config: site.authentication.signup

Allow users to create accounts. This can be disabled if you plan
to create accounts manually or enable during setup when accounts
can be created and then disabled to prevent any new users from
creating accounts.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueAUTH_SIGNUPtruenot annotatedetc/defaults/config.defaults.yaml:350

config: site.authentication.signin

Generally if you allow registration, you allow signin. But there
are circumstances where it's helpful to turn off authentication
temporarily.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueAUTH_SIGNINtruenot annotatedetc/defaults/config.defaults.yaml:354

config: site.authentication.autoverify

By default, new accounts need to verify their email address before
they can sign in. This is a security measure to prevent spamming
and abuse of the system. If you're running a private instance or
an instance for your team or company, you can disable this feature
to make it easier for users to sign in.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalseAUTH_AUTOVERIFYfalsenot annotatedetc/defaults/config.defaults.yaml:360

config: site.authentication.required

When enabled, the homepage secret form is not available unless
the user is logged in. Similar to a disabled homepage, but still
shows the header with logo and navigation links. This allows for
a more restrictive mode where only authenticated users can create
secrets while maintaining site navigation and branding.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueAUTH_REQUIREDfalsenot annotatedetc/defaults/config.defaults.yaml:366

config: site.authentication.allowed_signup_domains

Colonel (admin) accounts are managed via the CLI:
  bin/ots customers role promote user@example.com
  bin/ots customers role demote user@example.com
  bin/ots customers role list
Restrict account creation to specific email domains while allowing
secret-sharing with any email address. When set, only email addresses
from the listed domains can create accounts. This is useful for
organizations that want to limit signups to their own domains while
still allowing secrets to be shared with anyone.
Format: List of domain names (e.g., example.com, company.org)
If empty or not set, signups are allowed from any domain (default).
Environment variable: ALLOWED_SIGNUP_DOMAIN (comma-separated list)
ShapeValueEnvironment variablesWhen unsetSinceSource
list[]ALLOWED_SIGNUP_DOMAINthe value abovenot annotatedetc/defaults/config.defaults.yaml:379

config: site.authentication.reset_request_rate_limit.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueRESET_REQUEST_RATE_LIMIT_ENABLEDtruev0.26.3etc/defaults/config.defaults.yaml:390

config: site.authentication.reset_request_rate_limit.max_per_ip

Requests permitted per window from a single client IP.
ShapeValueEnvironment variablesWhen unsetSinceSource
string10RESET_REQUEST_RATE_LIMIT_MAX_PER_IPthe value abovev0.26.3etc/defaults/config.defaults.yaml:392

config: site.authentication.reset_request_rate_limit.max_per_email

Higher backstop cap per submitted login (catches IP rotation).
ShapeValueEnvironment variablesWhen unsetSinceSource
string30RESET_REQUEST_RATE_LIMIT_MAX_PER_EMAILthe value abovev0.26.3etc/defaults/config.defaults.yaml:394

config: site.authentication.reset_request_rate_limit.window

Counting window in seconds (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600RESET_REQUEST_RATE_LIMIT_WINDOWthe value abovev0.26.3etc/defaults/config.defaults.yaml:396

config: site.authentication.reset_request_rate_limit.lockout

Lockout duration in seconds once a tier's cap is hit (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600RESET_REQUEST_RATE_LIMIT_LOCKOUTthe value abovev0.26.3etc/defaults/config.defaults.yaml:398

config: site.authentication.email_login_request_rate_limit.enabled

Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueEMAIL_LOGIN_REQUEST_RATE_LIMIT_ENABLEDtruenot annotatedetc/defaults/config.defaults.yaml:412

config: site.authentication.email_login_request_rate_limit.max_per_ip

Requests permitted per window from a single masked client IP. Looser
than the reset-request cap: a magic link is a sign-in method, and a
whole /24 (an office NAT) shares this bucket.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string30EMAIL_LOGIN_REQUEST_RATE_LIMIT_MAX_PER_IPthe value abovenot annotatedetc/defaults/config.defaults.yaml:416

config: site.authentication.email_login_request_rate_limit.max_per_email

Backstop cap per submitted login (catches IP rotation). Keep
max_per_email >= 2 * max_per_ip AND lockout >= window: a single IP
timing its requests around its own window boundary lands up to
2 * max_per_ip - 2 requests in one login's window, and with a shorter
lockout it is free again inside that window, so one source could lock
a victim out of magic-link sign-in from every IP. The defaults
(30/90, 3600/3600) satisfy both. Rodauth's resend window already caps
the mail an account receives.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string90EMAIL_LOGIN_REQUEST_RATE_LIMIT_MAX_PER_EMAILthe value abovenot annotatedetc/defaults/config.defaults.yaml:425

config: site.authentication.email_login_request_rate_limit.window

Counting window in seconds (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600EMAIL_LOGIN_REQUEST_RATE_LIMIT_WINDOWthe value abovenot annotatedetc/defaults/config.defaults.yaml:427

config: site.authentication.email_login_request_rate_limit.lockout

Lockout duration in seconds once a tier's cap is hit (1 hour). Keep it
>= window (see max_per_email).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600EMAIL_LOGIN_REQUEST_RATE_LIMIT_LOCKOUTthe value abovenot annotatedetc/defaults/config.defaults.yaml:430

config: site.authentication.create_account_rate_limit.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueCREATE_ACCOUNT_RATE_LIMIT_ENABLEDtruev0.26.3etc/defaults/config.defaults.yaml:446

config: site.authentication.create_account_rate_limit.max_per_ip

Signups permitted per window from a single masked client IP. The bucket
is a whole /24 (office, campus NAT), and behind an unconfigured reverse
proxy it is the entire deployment — so this is deliberately loose
relative to the one signup a person needs. Raise it for dense-NAT
populations; a too-tight value here is a signup-funnel outage.
ShapeValueEnvironment variablesWhen unsetSinceSource
string10CREATE_ACCOUNT_RATE_LIMIT_MAX_PER_IPthe value abovev0.26.3etc/defaults/config.defaults.yaml:452

config: site.authentication.create_account_rate_limit.window

Counting window in seconds (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600CREATE_ACCOUNT_RATE_LIMIT_WINDOWthe value abovev0.26.3etc/defaults/config.defaults.yaml:454

config: site.authentication.create_account_rate_limit.lockout

Lockout duration in seconds once the cap is hit (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600CREATE_ACCOUNT_RATE_LIMIT_LOCKOUTthe value abovev0.26.3etc/defaults/config.defaults.yaml:456

config file: brand

config: brand.primary_color

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_PRIMARY_COLORno valuev0.26.0etc/defaults/config.defaults.yaml:1080

config: brand.product_name

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_PRODUCT_NAMEno valuev0.26.0etc/defaults/config.defaults.yaml:1081

config: brand.product_domain

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_PRODUCT_DOMAINno valuev0.26.0etc/defaults/config.defaults.yaml:1082

config: brand.support_email

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_SUPPORT_EMAILno valuev0.26.0etc/defaults/config.defaults.yaml:1083

config: brand.corner_style

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_CORNER_STYLEno valuev0.26.0etc/defaults/config.defaults.yaml:1084

config: brand.font_family

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_FONT_FAMILYno valuev0.26.0etc/defaults/config.defaults.yaml:1085

config: brand.button_text_light

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_BUTTON_TEXT_LIGHTno valuev0.26.0etc/defaults/config.defaults.yaml:1086

config: brand.logo_url

Masthead/email logo. An absolute http(s) URL works everywhere; a brand pack
can instead carry its own brand-logo.svg / brand-logo.png and set this to the
served path (e.g. "/brand-logo.svg", #3774). A root-relative value renders in
the web UI but is omitted from emails (which need an absolute URL).
ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_LOGO_URLno valuev0.26.0etc/defaults/config.defaults.yaml:1091

config: brand.logo_dark_url

Dark-theme variant of the masthead logo, shown when the app's dark mode is
active. Web UI only (emails always use logo_url). A pack can carry it as
brand-logo-dark.svg / brand-logo-dark.png and set this to the served path.
ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_LOGO_DARK_URLno valuev0.26.3etc/defaults/config.defaults.yaml:1095

config: brand.logo_alt

Accessible name for the brand logo. Unset falls back to an i18n string
derived from the product name.
ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_LOGO_ALTno valuev0.26.0etc/defaults/config.defaults.yaml:1098

config: brand.favicon_url

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_FAVICON_URLno valuev0.26.0etc/defaults/config.defaults.yaml:1099

config: brand.apple_touch_icon_url

URL overrides for the mobile/social variety pack served in the HTML head.
When unset, neutral bundled defaults (public/web) are used; replacing the
files via the brand directory is the alternative to these URL overrides.
ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_APPLE_TOUCH_ICON_URLno valuev0.26.0etc/defaults/config.defaults.yaml:1103

config: brand.og_image_url

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_OG_IMAGE_URLno valuev0.26.0etc/defaults/config.defaults.yaml:1104

config: brand.totp_issuer

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_TOTP_ISSUERno valuev0.26.0etc/defaults/config.defaults.yaml:1105

config: brand.signature_name

ShapeValueEnvironment variablesWhen unsetSinceSource
JSON stringno valueBRAND_SIGNATURE_NAMEno valuev0.26.0etc/defaults/config.defaults.yaml:1106

config file: features

config: features.regions.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalseREGIONS_ENABLEDfalsev0.24.0etc/defaults/config.defaults.yaml:1110

config: features.regions.current_jurisdiction

ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueJURISDICTIONno valuev0.24.0etc/defaults/config.defaults.yaml:1111

config: features.regions.jurisdictions

Available jurisdictions for regional deployment

Environment Variable Format:
  JURISDICTIONS=ID:domain,ID:domain,...
  where ID is the jurisdiction identifier (e.g., EU, CA, US)
  and domain is the hostname for that jurisdiction

Examples:
  JURISDICTIONS=EU:eu.example.com,CA:ca.example.com
  JURISDICTIONS=US:us.onetimesecret.com,EU:eu.onetimesecret.com,APAC:apac.onetimesecret.com
ShapeValueEnvironment variablesWhen unsetSinceSource
string""JURISDICTIONSthe value abovev0.25.5etc/defaults/config.defaults.yaml:1123

config: features.incoming.enabled

Enable or disable the incoming secrets feature.

This flag governs the CANONICAL domain only. Per-domain incoming on
custom domains is gated by the org's incoming_secrets entitlement plus a
ready IncomingConfig, NOT by this flag (see the canonical/custom split in
RecipientResolver / CustomDomain::HomepageConfig#incoming_available?). To
emergency-disable incoming on custom domains, revoke the incoming_secrets
entitlement or set ORGS_INCOMING_SECRETS_ENABLED=false.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalseINCOMING_ENABLEDfalsenot annotatedetc/defaults/config.defaults.yaml:1136

config: features.incoming.memo_max_length

Maximum character length for the memo/subject field
ShapeValueEnvironment variablesWhen unsetSinceSource
string50INCOMING_MEMO_MAX_LENGTHthe value abovenot annotatedetc/defaults/config.defaults.yaml:1138

config: features.incoming.default_ttl

Default TTL for incoming secrets in seconds (7 days = 604800)
ShapeValueEnvironment variablesWhen unsetSinceSource
string604800INCOMING_DEFAULT_TTLthe value abovenot annotatedetc/defaults/config.defaults.yaml:1140

config: features.incoming.default_passphrase

Optional default passphrase for all incoming secrets (nil = no passphrase)
ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueINCOMING_DEFAULT_PASSPHRASEno valuenot annotatedetc/defaults/config.defaults.yaml:1142

config: features.incoming.rate_limit.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueINCOMING_RATE_LIMIT_ENABLEDtruev0.26.0etc/defaults/config.defaults.yaml:1149

config: features.incoming.rate_limit.max_per_ip

Submissions permitted per window from a single client IP.
ShapeValueEnvironment variablesWhen unsetSinceSource
string10INCOMING_RATE_LIMIT_MAX_PER_IPthe value abovev0.26.0etc/defaults/config.defaults.yaml:1151

config: features.incoming.rate_limit.max_per_recipient

Higher backstop cap per recipient hash (catches IP-rotating spam).
ShapeValueEnvironment variablesWhen unsetSinceSource
string30INCOMING_RATE_LIMIT_MAX_PER_RECIPIENTthe value abovev0.26.0etc/defaults/config.defaults.yaml:1153

config: features.incoming.rate_limit.window

Counting window in seconds (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600INCOMING_RATE_LIMIT_WINDOWthe value abovev0.26.0etc/defaults/config.defaults.yaml:1155

config: features.incoming.rate_limit.lockout

Lockout duration in seconds once a tier's cap is hit (1 hour).
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600INCOMING_RATE_LIMIT_LOCKOUTthe value abovev0.26.0etc/defaults/config.defaults.yaml:1157

config: features.incoming.recipients[0]

ShapeValueEnvironment variablesWhen unsetSinceSource
listno valueINCOMING_RECIPIENT_1no valuenot annotatedetc/defaults/config.defaults.yaml:1172

config: features.incoming.recipients[1]

ShapeValueEnvironment variablesWhen unsetSinceSource
listno valueINCOMING_RECIPIENT_2no valuenot annotatedetc/defaults/config.defaults.yaml:1173

config: features.incoming.recipients[2]

ShapeValueEnvironment variablesWhen unsetSinceSource
listno valueINCOMING_RECIPIENT_3no valuenot annotatedetc/defaults/config.defaults.yaml:1174

config: features.incoming.recipients[3]

ShapeValueEnvironment variablesWhen unsetSinceSource
listno valueINCOMING_RECIPIENT_4no valuenot annotatedetc/defaults/config.defaults.yaml:1175

config: features.domains.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalseDOMAINS_ENABLEDfalsev0.24.0etc/defaults/config.defaults.yaml:1177

config: features.domains.require_verified

When true, secret creation rejects an unverified custom share_domain
with a form error, under every validation strategy. When false
(default), creation still requires the domain to be served (see
serve_unverified below). Canonical domains are unaffected.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalseDOMAINS_REQUIRE_VERIFIEDfalsev0.25.2etc/defaults/config.defaults.yaml:1182

config: features.domains.serve_unverified

Under a validation_strategy that checks ownership (approximated,
caddy_on_demand), a registered custom domain is served only once its
ownership is verified, by its TXT record or an operator override.
Until then its host answers 404 for every path, and the domain is not
offered for links. Under passthrough, registration by the owning
organization is enough. A domain record with no organization is never
served.

When true, every registered custom domain that has an organization
is served whatever its ownership state, and a warning is logged at
boot. Only the value true enables it.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanfalseDOMAINS_SERVE_UNVERIFIEDfalsenot annotatedetc/defaults/config.defaults.yaml:1194

config: features.domains.default

The default domain used for link URLs. When not set or empty,
site.host is used.
ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueDEFAULT_DOMAINno valuev0.24.0etc/defaults/config.defaults.yaml:1197
LINK_DOMAINS — comma-separated hosts offered in the link-domain
picker. For installs whose canonical host is an internal platform
address (e.g. ge-abcd123.eu.otshosted.com) that must keep serving
the app but must never be offered to customers as a link domain.

Three-way semantics — all deliberate:
  unset          -> the picker offers the canonical domain
                    (every pre-existing install is unchanged)
  set            -> the picker offers exactly these hosts; the
                    canonical domain appears only if listed
  set-but-empty  -> boot error naming LINK_DOMAINS
                    (Onetime::Config.validate_link_domains!)

A set list that names only UNPARSEABLE hosts is the same boot
error: there is no safe fallback for it. Offering the canonical
domain instead would contradict the request (hiding that host is
the whole point), and offering nothing leaves the picker empty, so
the typo has to fail loud. A list that mixes good and bad entries
boots — the bad one is dropped and logged.

This is NOT a UI-only setting: every entry joins the canonical
host set, so requests to these hosts are classified :canonical and
serve the app instead of being rejected as :invalid.

The `&.` chain is load-bearing — it is what keeps unset (nil) and
set-but-empty ([]) distinguishable through ERB+YAML. Do NOT copy
the `|| nil` idiom used by `default:` above; it collapses the two.
`link_domains` is also deliberately absent from Config::DEFAULTS —
deep_merge restores the default for any nil in loaded config,
which would make set-but-empty undetectable.
ShapeValueEnvironment variablesWhen unsetSinceSource
listno valueLINK_DOMAINSno valuev0.26.5etc/defaults/config.defaults.yaml:1229

config: features.domains.validation_strategy

Domain validation and certificate management strategy
Options:
  - passthrough: No validation or cert management
  - approximated: Use approximated.app API for SSL certs and validation (requires cluster config)
  - caddy_on_demand: Use Caddy's on-demand TLS (requires internal ACME endpoint).
    Ownership is checked with our own DNS lookup of the domain's TXT
    challenge record; Caddy issuing a certificate does not verify a domain.
    Resolving and SSL status come from our own A/AAAA lookup and a TLS
    handshake to the domain on port 443, so the application host needs
    outbound DNS and outbound TCP 443.
ShapeValueEnvironment variablesWhen unsetSinceSource
stringpassthroughDOMAINS_VALIDATION_STRATEGYthe value abovev0.24.0etc/defaults/config.defaults.yaml:1241

config: features.domains.approximated.api_key

ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueAPPROXIMATED_API_KEYno valuev0.24.0etc/defaults/config.defaults.yaml:1245

config: features.domains.approximated.proxy_ip

ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueAPPROXIMATED_PROXY_IPno valuev0.24.0etc/defaults/config.defaults.yaml:1246

config: features.domains.approximated.proxy_host

ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueAPPROXIMATED_PROXY_HOSTno valuev0.24.0etc/defaults/config.defaults.yaml:1247

config: features.domains.approximated.proxy_name

ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueAPPROXIMATED_PROXY_NAMEno valuev0.24.0etc/defaults/config.defaults.yaml:1248

config: features.domains.approximated.vhost_target

ShapeValueEnvironment variablesWhen unsetSinceSource
stringno valueAPPROXIMATED_VHOST_TARGETno valuev0.24.0etc/defaults/config.defaults.yaml:1249

config: features.domains.acme.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueACME_ENDPOINT_ENABLEDfalsev0.24.0etc/defaults/config.defaults.yaml:1264

config: features.domains.acme.listen_address

IP address to bind to in standalone mode (should always be localhost)
ShapeValueEnvironment variablesWhen unsetSinceSource
string127.0.0.1ACME_LISTEN_ADDRESSthe value abovev0.24.0etc/defaults/config.defaults.yaml:1266

config: features.domains.acme.port

Port for standalone mode (Caddy's ask directive points here)
ShapeValueEnvironment variablesWhen unsetSinceSource
string12020ACME_PORTthe value abovev0.24.0etc/defaults/config.defaults.yaml:1268

config: features.organizations.enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueENABLE_ORGSfalsev0.25.0etc/defaults/config.defaults.yaml:1274

config: features.organizations.sso_enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueORGS_SSO_ENABLEDfalsev0.25.0etc/defaults/config.defaults.yaml:1275

config: features.organizations.custom_mail_enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueORGS_CUSTOM_MAIL_ENABLEDfalsev0.25.0etc/defaults/config.defaults.yaml:1276

config: features.organizations.incoming_secrets_enabled

ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueORGS_INCOMING_SECRETS_ENABLEDfalsev0.25.0etc/defaults/config.defaults.yaml:1277

config: features.organizations.homepage_network_rules_ui_enabled

Lets organizations with the homepage_network_rules entitlement edit
their custom domains' homepage network rules (allowed/denied CIDRs).
Default OFF. Turning it off stops edits only: rules already stored
stay enforced, the same as after a plan downgrade, so the switch never
opens a homepage a tenant restricted.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueORGS_HOMEPAGE_NETWORK_RULES_UI_ENABLEDfalsenot annotatedetc/defaults/config.defaults.yaml:1283

config: features.organizations.base_domain_signup_enabled

Lets organizations with the base_domain_signup entitlement admit their
custom domain's own base domain to its sign-up allowlist automatically
(secrets.acme.com admits @acme.com). Also checked when a sign-up is
validated, so turning it off stops a saved setting from admitting
anyone.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueORGS_BASE_DOMAIN_SIGNUP_ENABLEDfalsenot annotatedetc/defaults/config.defaults.yaml:1289

config: features.organizations.audit_logs_enabled

Gates exposure (UI + list API) of the organization secret-activity
trail; pairs with the `audit_logs` entitlement. Defaults ON, unlike
the sibling flags above, because the trail ships working out of the
box — this is an opt-out exclusion (ORGS_AUDIT_LOGS_ENABLED=false),
not an opt-in feature. Does not stop event collection.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueORGS_AUDIT_LOGS_ENABLEDtruev0.26.4etc/defaults/config.defaults.yaml:1295

config: features.organizations.sso_diagnostics_rate_limit.enabled

Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueSSO_DIAGNOSTICS_RATE_LIMIT_ENABLEDtruenot annotatedetc/defaults/config.defaults.yaml:1304

config: features.organizations.sso_diagnostics_rate_limit.max_per_customer

Runs permitted per window for one customer, across all their domains.
A run is deterministic (the same stored record gets the same verdict
until the record or the IdP changes), so ten covers several full
edit-save-check cycles.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string10SSO_DIAGNOSTICS_RATE_LIMIT_MAX_PER_CUSTOMERthe value abovenot annotatedetc/defaults/config.defaults.yaml:1309

config: features.organizations.sso_diagnostics_rate_limit.window

Counting window in seconds (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SSO_DIAGNOSTICS_RATE_LIMIT_WINDOWthe value abovenot annotatedetc/defaults/config.defaults.yaml:1311

config: features.organizations.sso_diagnostics_rate_limit.lockout

Lockout duration in seconds once the cap is hit (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SSO_DIAGNOSTICS_RATE_LIMIT_LOCKOUTthe value abovenot annotatedetc/defaults/config.defaults.yaml:1313

config: features.organizations.sso_metadata_fetch_rate_limit.enabled

Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueSSO_METADATA_FETCH_RATE_LIMIT_ENABLEDtruenot annotatedetc/defaults/config.defaults.yaml:1322

config: features.organizations.sso_metadata_fetch_rate_limit.max_per_customer

Fetches permitted per window for one customer, across all their
domains. Enough for an admin iterating on a metadata URL.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string30SSO_METADATA_FETCH_RATE_LIMIT_MAX_PER_CUSTOMERthe value abovenot annotatedetc/defaults/config.defaults.yaml:1325

config: features.organizations.sso_metadata_fetch_rate_limit.window

Counting window in seconds (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SSO_METADATA_FETCH_RATE_LIMIT_WINDOWthe value abovenot annotatedetc/defaults/config.defaults.yaml:1327

config: features.organizations.sso_metadata_fetch_rate_limit.lockout

Lockout duration in seconds once the cap is hit (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SSO_METADATA_FETCH_RATE_LIMIT_LOCKOUTthe value abovenot annotatedetc/defaults/config.defaults.yaml:1329

config: features.organizations.sender_test_email_rate_limit.enabled

Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueSENDER_TEST_EMAIL_RATE_LIMIT_ENABLEDtruenot annotatedetc/defaults/config.defaults.yaml:1338

config: features.organizations.sender_test_email_rate_limit.max_per_customer

Test sends permitted per window for one customer, across all their
domains.
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string10SENDER_TEST_EMAIL_RATE_LIMIT_MAX_PER_CUSTOMERthe value abovenot annotatedetc/defaults/config.defaults.yaml:1341

config: features.organizations.sender_test_email_rate_limit.window

Counting window in seconds (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SENDER_TEST_EMAIL_RATE_LIMIT_WINDOWthe value abovenot annotatedetc/defaults/config.defaults.yaml:1343

config: features.organizations.sender_test_email_rate_limit.lockout

Lockout duration in seconds once the cap is hit (1 hour).
Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
string3600SENDER_TEST_EMAIL_RATE_LIMIT_LOCKOUTthe value abovenot annotatedetc/defaults/config.defaults.yaml:1345

config: features.secret_activity.collect

When false, event recording pauses; existing events stay readable.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueSECRET_ACTIVITY_COLLECTtruev0.26.4etc/defaults/config.defaults.yaml:1353

config: features.secret_activity.max_events

Newest events retained per organization (floor: 100). Lowering this
deletes (not hides) each org's oldest events on its next write.
ShapeValueEnvironment variablesWhen unsetSinceSource
string10000SECRET_ACTIVITY_MAX_EVENTSthe value abovev0.26.4etc/defaults/config.defaults.yaml:1356

config: features.secret_activity.geo_country_enabled

Country-level geo capture on Secret Activity events (#3989). A distinct
axis from `collect`: gates ONLY the net_country attribute, pending
counsel review of org-tier geo exposure (ADR-021 Decision 4 open
question; ADR-022 does not yet cover this attribute). Defaults OFF
(opt-in) — the inverse polarity of the sibling flags — because this is
the not-yet-reviewed surface, not an already-approved one.
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueSECRET_ACTIVITY_GEO_COUNTRY_ENABLEDfalsev0.26.5etc/defaults/config.defaults.yaml:1363

config: features.markdown.enabled

Since unreleased
ShapeValueEnvironment variablesWhen unsetSinceSource
booleanno valueMARKDOWN_ENABLEDfalsenot annotatedetc/defaults/config.defaults.yaml:1372