Configuration
TOML, with every value overridable by environment variable. Defaults live in config/default.toml; the container image ships config/oss.toml.
The Environment Form
Prefix SENTIO, a double underscore between levels, uppercased:
SENTIO__DATABASE__URL="postgres://sentio:secret@db.internal:5432/sentio"
SENTIO__SERVER__HOSTNAME="mail.example.com"
SENTIO__STORAGE__SECRET_KEY="..."
SENTIO__SPAM__RSPAMD__URL="http://127.0.0.1:11333" # [spam.rspamd] urlEnvironment overrides win over the file. That is the mechanism for keeping secrets out of config: leave them unset in TOML and inject them at runtime, so the file is safe to commit and the credentials live wherever you keep credentials.
Sections
| Section | Controls |
|---|---|
[server] | Hostname, listener addresses, worker counts, session limits |
[tls] | Certificate paths, minimum version, SNI, optional ACME |
[database] | PostgreSQL URL and pool sizing |
[kv] / [redis] | KV backend selection and connection |
[nats] | JetStream URL, prefetch, stream retention |
[storage] | S3 endpoint, credentials, bucket, path-style addressing |
[scanning] | ClamAV host, size limits |
[spam] | Backend choice, score thresholds |
[abuse] | Rate limits, DNSBLs, greylisting, reputation thresholds |
[delivery] | Retry schedule, connection pooling, optional smart-host relay |
[auth] | DKIM, SPF, DMARC and ARC behaviour |
[llm] | Provider, model, and when classification runs |
[deliverability] | One-click unsubscribe, BATV, the addresses a domain must accept |
[tracking] | Open and click tracking |
[webhooks] | Event dispatch behaviour |
[observability] | Log format and level, metrics, tracing |
Several of these have nested tables of their own - [spam.rspamd], [spam.builtin], [abuse.greylist], [delivery.relay], [delivery.rate_limits], [tls.acme], [auth.fbl], [server.inbound_limits], [server.inbound_timeouts], [scanning.per_tenant_defaults] - and each nests in the environment form the same way, so [spam.rspamd] url is SENTIO__SPAM__RSPAMD__URL.
Three That Decide How It Behaves
server.hostname is what Sentio announces in SMTP and what receivers will check against your PTR record. It is not cosmetic; see Deliverability.
[delivery.relay] bypasses MX resolution and sends everything through a smart host. That is the escape hatch when outbound port 25 is blocked, and it is also how the test stack keeps mail off the internet.
[spam] thresholds decide where the review band sits, and therefore how much traffic reaches the LLM tier at all. Clear ham and clear spam never get there by design.
Observability
Structured JSON logs with per-component levels, Prometheus metrics, OpenTelemetry traces spanning submission through delivery, and a per-message trace ID. Captured error events are readable over the API with a summary endpoint.
/health/live and /health/ready are the probes. The metrics endpoint is unauthenticated, which is why the compose stack deliberately does not publish it: expose it on an interface your monitoring can reach and nothing else can.