Security
Production-grade defaults built in. Harden your app using examples/todo as the reference implementation.
LIVE
Server action round-trip
Same RPC as above, plus a validation failure (422) via docs_todo_add.
Built in (no setup)
- CSRF —
X-Resuma-CSRFon actions and submits - Headers — CSP nonces, HSTS, X-Frame-Options, COOP, CORP
- Rate limiting — per-IP on actions, submits, and exec routes; disk-backed in prod (
RESUMA_RATE_BACKEND=disk, no Redis) - Origin check — blocks cross-origin POST abuse
- SSR safety — escaped HTML + sanitized JSON state + JSON-LD
- Client bundles —
script-src 'self'; TypeScript viaClientComponent
Trust boundaries
| API | Escaping | Notes |
|---|---|---|
view! text/attrs | Auto | Default for UI |
View::raw() | None | Trusted static HTML only |
with_head() | Partial | Inline <style> / <script> get CSP nonces; external src scripts use 'self' |
ClientComponent | Attrs escaped | Ids restricted to [a-zA-Z0-9_-] |
| Resumability payload | Sanitized | Blocks </script> breakouts |
Rate limiting
Per-IP sliding window on actions, submits, and exec routes. Defaults: 120 action RPC/min, 60 submits/min — tune with RESUMA_RATE_ACTIONS and RESUMA_RATE_SUBMITS. No Redis or external datastore — Resuma ships built-in backends:
| Backend | When | Storage |
|---|---|---|
memory | Local dev (default) | In-process HashMap |
disk | RESUMA_ENV=production (auto) | {RESUMA_DATA_DIR}/rate-limit/ — file locks, multi-process on same volume |
Set RESUMA_RATE_BACKEND=memory|disk to override. Mount a persistent volume at RESUMA_DATA_DIR on Fly/Docker so limits survive restarts. For multi-region or many machines without a shared volume, add edge rate limiting (nginx limit_req, Fly proxy, Cloudflare) — still no Redis in your app. Exec routes have separate limits — Exec security.
Guides
Todo exampleStart here — full backend reference (main + security + todo_store)Exec securityAPI keys, graph tokens, worker rate limitsEnvironment variablesLocal vs prod · RESUMA_ENV · Fly secrets · resuma doctorConfigure serverSecurityConfig in Rust · CSP · Fly/Docker checklistSecure #[server] actionsValidation · Result errors · action middlewareAuth middlewareFlow #[middleware] vs ResumaApp action pipelineBackend patternsPattern mapping tableAuthorization & RLSRow-level checks · Postgres RLS
Quick start (ResumaApp)
mod security;
#[tokio::main]
async fn main() -> std::io::Result<()> {
security::install();
ResumaApp::new()
.page("/", || Home::render(HomeProps::default()))
.serve(security::serve_options())
.await
}