ESC
Type to search...
S
Soli Docs

Production security defaults

What production already does, what you still have to set, and what the hardening program will fail closed. The long-term goal is that soli new + soli serve is safe on the public internet without a checklist.

Already on by default (production)

Control What it does
Auto-escaped templates<%= %> HTML-escapes, including non-String values
CSRF Origin/Referer gateCross-site state-changing requests without a matching origin fail
Security headersStandard preset in production (nosniff, frame options, HSTS)
SSRF on HTTP.*Loopback and private ranges refused; exceptions are literal host:port in SOLI_HTTP_ALLOW_HOSTS
Request body cap8 MiB (SOLI_MAX_BODY_SIZE); 413 when exceeded
Attachment typesDefault allowlist excludes text/html, SVG, XML; blob route sends nosniff + disposition
SQL TLSPostgres/MySQL via rustls; default prefer
Panic containmentA panicking handler is a 500; the worker stays up
Log redactionCredential-looking params, binds, locals, and HTTP URLs are redacted
Jobs dashboard404 in production unless jobs credentials are set
Production boot gateAPP_ENV=production (or prod) refuses to start without SOLI_APP_HOSTS (at least one hostname) and SOLI_SESSION_SECRET of 32+ characters. --dev and non-production env skip the gate

You still set (today)

Not implied by a bare soli serve. Required for a public host:

  • SOLI_APP_HOSTS — required at production boot. CSRF origin checks use this list, not a forgeable Host header.
  • SOLI_SESSION_SECRET (32+ chars) — required at production boot; sealed cookies and the cookie session driver derive keys from it.
  • SOLI_CSRF_TOKENS=require — tokens are always verified when present; this makes a missing token a 403 for browser form posts. soli new writes this into .env. Existing apps stay optional until they set it.
  • permit(...) / attr_accessibleModel.create(params) is not blocked unless you whitelist.
  • sslmode=require (or verify-full) — default prefer still allows cleartext if the server offers none.
  • SOLI_TRUST_PROXY=1 — only behind a proxy that strips inbound X-Forwarded-* then sets its own.
  • Reverse-proxy TLSsoli serve is HTTP.

Target (hardening program)

Not shipped as defaults yet — do not assume they already fail closed:

  • Stricter CSP that matches vendored htmx + Alpine
  • DATABASE_URL examples using sslmode=require

Edge knobs: Server Hardening. Headers: Security Headers. Forms: Forms & CSRF.