Runtime configuration for mailglass, validated at boot via NimbleOptions.
Only this module may call Application.compile_env*. Every other module
reads configuration through Application.get_env/2 (enforced by the
LINT-08 Credo check in Phase 6).
The brand theme (D-19) is cached in :persistent_term after validation so
the render hot path reads it in O(1) without re-parsing the Application env
on every message.
Options
:feedback_id- Optional Feedback-ID prefix (RFC 8058/Deliverability). When set, auto-populates as{sender_id}:{mailable}:{tenant_id}:{stream}. The default value isnil.:repo- The adopter's Ecto.Repo module. Required from Phase 2+ onwards. The default value isnil.:adapter(term/0) - Adapter module or{module, opts}tuple. Default: the Fake adapter. The default value is{Mailglass.Adapters.Fake, []}.:theme(keyword/0) - Brand theme tokens. SeeMailglass.Components.Theme. The default value is[].:colors(map/0) - Brand color map. Keys::ink,:glass,:ice,:mist,:paper,:slate. The default value is%{ink: "#0D1B2A", glass: "#277B96", ice: "#A6EAF2", mist: "#EAF6FB", paper: "#F8FBFD", slate: "#5C6B7A"}.:fonts(map/0) - Font-stack map. Keys::body,:display,:mono. The default value is%{display: "'Inter Tight', 'Inter', sans-serif", body: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", mono: "'IBM Plex Mono', ui-monospace, monospace"}.
:telemetry(keyword/0) - Telemetry options. The default value is[].:default_logger(boolean/0) - Attach the default logger handler at boot. Default:false. The default value isfalse.
:renderer(keyword/0) - Renderer options. The default value is[].:css_inliner- CSS inlining backend. Default::premailex. The default value is:premailex.:plaintext(boolean/0) - Auto-generate a plaintext body alongside the HTML body. Default:true. The default value istrue.
:tenancy- Module implementingMailglass.Tenancy. Default:nil(single-tenant mode). The default value isnil.:suppression_store- Module implementingMailglass.SuppressionStore. Default:Mailglass.SuppressionStore.Ecto. The default value isMailglass.SuppressionStore.Ecto.:async_adapter- Async delivery adapter fordeliver_later/2.:oban(default, durable) or:task_supervisor(non-durable fallback). Use:task_supervisorto silence the boot warning when Oban is deliberately not in deps. The default value is:oban.:rate_limit(keyword/0) - Rate-limiter configuration (SEND-02). The default value is[].:tracking(keyword/0) - Open/click tracking configuration (TRACK-03). When any mailable enables opens or clicks,:hostis REQUIRED or boot raises%ConfigError{type: :tracking_host_missing}. The default value is[].:endpoint- Phoenix.Token endpoint/secret override for open/click tracking. When nil,Mailglass.Tracking.endpoint/0falls back to:adapter_endpoint. The default value isnil.:host- Tracking subdomain (e.g.track.example.com). Must be separate from the adopter's main app host. The default value isnil.:scheme- URL scheme.httponly for dev. The default value is"https".:salts(list ofString.t/0) - Phoenix.Token salts. Head signs; all verify (rotation support). The default value is[].:max_age(pos_integer/0) - Token max age in seconds. Default: 2 years. The default value is63072000.
:compliance(keyword/0) - RFC 8058 unsubscribe configuration. Phase 11 reads this subtree throughMailglass.Configaccessors only so router/controller/token code avoids new direct compile-env lookups. The default value is[].:endpoint- Phoenix.Token endpoint/secret override for unsubscribe signing. When nil,Mailglass.Config.compliance_endpoint/0falls back to the tracking endpoint chain. The default value isnil.:host- Canonical host used for unsubscribe URLs (for exampleunsubscribe.example.com). The default value isnil.:scheme- Unsubscribe URL scheme.httpis intended for local development only. The default value is"https".:mount_path(String.t/0) - Absolute path prefix used when generating unsubscribe URLs. The default value is"/mailglass/unsubscribe".:previous_secrets(list ofString.t/0) - Raw priorsecret_key_basevalues accepted during unsubscribe token verification after endpoint-secret rotation. The default value is[].:redirect- Optional GET unsubscribe redirect escape hatch (for example/settings/unsubscribe). The default value isnil.:max_age(pos_integer/0) - Unsubscribe token max age in seconds. Default: 2 years. The default value is63072000.:lifecycle(atom/0) - Module implementingMailglass.Lifecyclefor transaction-local unsubscribe side effects. The default value isMailglass.Lifecycle.Noop.
:clock- Module implementingutc_now/0. Default:Mailglass.Clock.System. Tests useMailglass.Clock.Frozen-backed per-process freezing without overriding this key. The default value isnil.:postmark(keyword/0) - Postmark webhook configuration (HOOK-03). The default value is[].:enabled(boolean/0) - Enable the Postmark webhook route. Default:true. The default value istrue.:basic_auth- Basic Auth{user, password}tuple. Required for signature verification; omit only if the provider is disabled. The default value isnil.:ip_allowlist(list ofString.t/0) - Opt-in list of CIDR strings (e.g.["50.31.156.0/24"]). Off by default per D-04 — Postmark's origin IPs can change. The default value is[].
:sendgrid(keyword/0) - SendGrid webhook configuration (HOOK-04). The default value is[].:enabled(boolean/0) - Enable the SendGrid webhook route. Default:true. The default value istrue.:public_key- Base64-encoded SubjectPublicKeyInfo DER (NOT PEM — SendGrid's dashboard ships raw DER without-----BEGIN PUBLIC KEY-----framing). Required for signature verification; omit only if the provider is disabled. The default value isnil.:timestamp_tolerance_seconds(pos_integer/0) - Replay tolerance window in seconds. Default:300(Stripe / Svix / Standard Webhooks consensus). The default value is300.
:mailgun(keyword/0) - Mailgun webhook configuration. The default value is[].:enabled(boolean/0) - Enable the Mailgun webhook route when explicitly mounted. The default value istrue.:signing_key- Mailgun webhook signing key used for HMAC verification. Required for signature verification; omit only if the provider is disabled. The default value isnil.:timestamp_tolerance_seconds(pos_integer/0) - Maximum accepted age for the Mailgun signature timestamp in seconds. Default:28_800. The default value is28800.:future_skew_seconds(pos_integer/0) - Maximum accepted future skew for the Mailgun signature timestamp in seconds. Default:300. The default value is300.:replay_cache_ttl_seconds(pos_integer/0) - Replay cache retention window for Mailgun tokens in seconds. Default:28_800. The default value is28800.
:webhook_retention(keyword/0) - Retention policy formailglass_webhook_eventsrows (HOOK-06). The default value is[].:succeeded_days- Days to retain:succeededwebhook_events before the Pruner deletes them. Set to:infinityto disable. Default: 14. The default value is14.:dead_days- Days to retain:dead(terminal-after-retries) webhook_events before the Pruner deletes them. Set to:infinityto disable. Default: 90. The default value is90.:failed_days- Days to retain:failed(investigatable) webhook_events. Default::infinity(never prune). The default value is:infinity.
Boot sequence
# lib/mailglass/application.ex
def start(_type, _args) do
Mailglass.Config.validate_at_boot!()
# ...
endRaises NimbleOptions.ValidationError on invalid configuration. Raising at
boot is intentional — a misconfigured mailer should never limp into
production serving half-rendered mail.
Summary
Functions
Returns the validated compliance subtree with defaults applied.
Resolves the current unsubscribe signing endpoint.
Returns the cached brand theme keyword list.
Validates and returns a keyword list of options.
Reads the :mailglass Application env, validates it against the schema,
and caches the brand theme in :persistent_term.
Functions
@spec compliance() :: keyword()
Returns the validated compliance subtree with defaults applied.
Resolves the current unsubscribe signing endpoint.
Falls back to Mailglass.Tracking.endpoint/0 so unsubscribe tokens reuse the
same endpoint-secret chain unless adopters opt into a compliance-specific
override.
@spec compliance_host() :: String.t() | nil
@spec compliance_lifecycle() :: module()
@spec compliance_max_age() :: pos_integer()
@spec compliance_mount_path() :: String.t()
@spec compliance_previous_secrets() :: [String.t()]
@spec compliance_redirect() :: String.t() | nil
@spec compliance_scheme() :: String.t()
@spec get_theme() :: keyword()
Returns the cached brand theme keyword list.
Requires validate_at_boot!/0 to have been called first. Returns an empty
list if the cache is unset (the caller is responsible for ensuring the boot
sequence has completed).
Validates and returns a keyword list of options.
Fills in defaults, raises NimbleOptions.ValidationError on unknown keys
or invalid values. Used primarily by validate_at_boot!/0; callers rarely
invoke this directly.
Examples
iex> config = Mailglass.Config.new!([])
iex> Keyword.fetch!(config, :adapter)
{Mailglass.Adapters.Fake, []}
@spec validate_at_boot!() :: :ok
Reads the :mailglass Application env, validates it against the schema,
and caches the brand theme in :persistent_term.
Called from Mailglass.Application.start/2. Raises
NimbleOptions.ValidationError if the Application env is invalid.
When [telemetry: [default_logger: true]] is configured, the default
logger handler is attached here.