Skip to content

v0.9.0 — Self-host production hardening (auth, CSRF, rate limit)

Choose a tag to compare

@MuhammadHasbiAshshiddieqy MuhammadHasbiAshshiddieqy released this 01 Jul 16:27

Added — Self-host production hardening (opt-in auth, CSRF, rate limiting)

Answers the valid P0 findings from a production-readiness audit (no auth/HTTPS/CSRF/rate-limit = blockers for exposing OpenCLAWN to the internet). Everything defaults off (OPENCLAWN_AUTH_TOKEN unset) — the old no-login behavior still works for localhost/VPN use. No new dependencies: auth uses stdlib hmac/secrets instead of Starlette's SessionMiddleware (which needs itsdangerous), and rate limiting is in-memory (single-process is enough for single-user, per the project's design).

  • security/auth.py — single-user shared-secret login, HMAC-signed session cookie (7-day expiry, constant-time verification), CSRF token generation.
  • security/rate_limit.py — sliding-window limiter for /chat/stream and /converse/stream (default 20 req/60s), independent of whether auth is enabled.
  • web/main.py — auth+CSRF+rate-limit middleware, /login + /logout routes, custom 404/500 exception handlers (no leaked stack traces), startup health check (logs Ollama/API-key/auth status without blocking boot), /health now reports ollama/cloud_keys/auth_enabled.
  • New login.html/404.html/500.html templates + a Sign out button in the sidebar (shown only when auth is enabled).
  • Caddyfile.example for a TLS reverse proxy, plus a docker-compose.yml healthcheck (stdlib urllib, not curl — avoids adding a package to the slim image).
  • Documentation (README, docs/security.md, docs/web.md, docs/infra.md, docs/tests.md) updated to match — README's old "Authentication: Not included" claim was stale now that it's available as opt-in.

Bug found and fixed via test-first development: the rate limiter was fully bypassed whenever auth was disabled, because the auth middleware's early-return also skipped the independent rate-limit check. Fixed, with a regression test.


Tests: 550 passing (32 new), ruff clean.