Skip to content
Reference

Security Architecture

The defaults and guardrails Flasgo uses to reduce common web security mistakes.

Flasgo takes a defense-in-depth approach. Instead of assuming developers will remember to add every control later, it ships with a secure baseline and makes risky features explicit.

Feature Purpose
Host allowlist Blocks unexpected or malformed host headers; entries are validated at startup
CSRF protection Uses HMAC-signed, session-bound double-submit tokens for unsafe requests
Signed sessions Prevents client-side session tampering
Security headers Adds CSP, HSTS, frame, and referrer protections
Cache controls Reduces accidental caching of sensitive responses
Static path protections Prevents traversal and symlink escape issues
Route-aware CORS Keeps cross-origin browser access disabled by default and validates exact policies and preflights
SSRF guard Validates outbound URLs and blocks private network targets unless explicitly allowed
Rate limiting Limits repeated security failures and supports route-level quotas through decorators
Input limits Bounds request bodies, multipart parts, form/query fields, JSON structure, and validation work
Security logging Records host, CSRF, and authz denials
WebSocket handshake policy Enforces host and exact-origin checks before acceptance
WebSocket protocol limits Bounds messages and message rate, validates frames, JSON, subprotocols, and close data
Request correlation Generates local request IDs and accepts only strictly validated trusted upstream IDs
Protected metrics Requires a long bearer token and uses bounded route-template labels
Protected docs Can require a registered backend for both Swagger UI and OpenAPI JSON
OpenTelemetry boundary Redacts query values, sanitizes rejected hosts, and bounds span names by route template
Response validation Rejects invalid status, header, cookie, and response data before sending

Flasgo includes pluggable authentication hooks and authorization helpers so teams can integrate their own identity model without rewriting core request handling.

Relevant public API includes:

  • register_auth_backend
  • authorize
  • bearer_token_backend
  • extract_bearer_token
  • jwt_backend and encode_jwt
  • AllowAny, IsAuthenticated, and HasScope

Routes, WebSocket upgrades, and protected docs share one authorization implementation. Missing or invalid credentials return 401, denied permissions return 403, and an authentication backend that raises returns a generic 500.

By default, signed sessions are stored client-side and protected with the application SECRET_KEY; cookie settings control HTTPS-only transport, JavaScript visibility, SameSite behavior, and lifetime.

CSRF protection uses an HMAC-signed, session-bound double-submit cookie model. Unsafe methods are expected to send the configured CSRF header, and origin checking requires the request origin or referer to match the request host or a trusted origin unless you relax that setting. Trusted origins are compared in canonical form, and bare host or suffix entries trust only the request’s own scheme. Tokens rotate with signed session changes, and publicly cacheable responses do not emit framework-managed cookies.

Flasgo 0.9.1 rejects wrong-typed boolean controls, invalid cookie names, and ambiguous security cookie/header values. Failed dispatch restores session state before error handling, and response validation runs before session persistence. See Session Changes and Failures for the precise boundaries.

In 0.10.0, unsupported ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS entries and a non-positive SESSION_COOKIE_MAX_AGE fail at startup. Host headers must be DNS names or IP literals, which stops URL delimiters or IPv6 zone IDs from smuggling another host past a suffix pattern. JWT scopes must be single RFC 6749 scope tokens, and JWT leeway must be finite. See Host and origin entries.

The SSRF guard is for application code that needs to validate user-influenced outbound URLs. By default it allows only HTTP and HTTPS schemes, rejects private networks, rejects userinfo credentials, and pins resolved IP addresses to reduce DNS rebinding risk. Async handlers use aresolve_outbound_url() for event-loop DNS with a fail-closed timeout. Malformed URLs and invalid hostnames raise SSRFViolation, and internationalized hosts are checked in their IDNA ASCII form. The private-network opt-in permits RFC 1918, unique-local, and deprecated site-local IPv6 targets, not loopback, link-local, multicast, reserved, or unspecified addresses.

CORS policies are exact-origin application or route configuration. Generated preflights do not run application code or persist framework cookies, and framework-owned docs and metrics endpoints do not inherit application CORS. CORS does not replace CSRF, authentication, or authorization.

WebSocket connections reuse host validation and run authentication and permissions before acceptance. Browser origins must be same-origin or exactly allowlisted, and a missing origin is denied by default. Sessions from the configured backend are readable, but handler changes are never persisted through the upgrade handshake.

Messages default to 64 KiB and 120 messages per minute per connection. The built-in development server also bounds concurrent work and WebSocket queues and disables per-message compression. Use a trusted edge for shared rate enforcement across multiple processes or hosts.

Request-head limits run before tracing or storage for both HTTP and WebSockets. See Handshake Security for the checks that precede WebSocket session loading.

Flasgo creates request IDs locally, sanitizes bounded structured log fields, and records security, HTTP, WebSocket, lifespan, and background-task outcomes. It ignores incoming IDs unless strict trust is enabled behind a proxy that overwrites the header.

Prometheus metrics are optional, disabled by default, and require a bounded bearer-safe ASCII token of at least 32 characters. The endpoint compares tokens in constant time, throttles failed authentication, never creates framework cookies, and labels HTTP observations by route template rather than raw attacker-controlled paths. Metrics include response sizes and send failures, standard runtime collectors, and trace exemplars under OpenMetrics when tracing is active.

The Metrics Reference covers backend outcomes, rejection reasons, internal failures, stream cleanup outcomes, and event-loop lag. These diagnostic counters continue to update when security-event logging is disabled and can overlap; they are not a replacement for audit logs.

Optional OpenTelemetry tracing uses bounded route-template span names, redacts non-empty HTTP query values, and removes rejected Host values before they reach instrumentation. The built-in docs can require an existing authentication backend, while the Swagger UI itself uses pinned assets, subresource integrity, and per-response CSP nonces.

Route policies, contracts, and resource boundaries

Section titled “Route policies, contracts, and resource boundaries”

Flasgo 0.9.0 extends this baseline with additive blueprint permissions, inspectable route policy and deployment checks, output filtering through explicit response contracts, bounded async streaming, and optional shared route quotas and server-side sessions. See the 0.9.0 feature overview for the implementation guides.

Shared storage fails with 503 when unavailable. Session updates compare the loaded value; stale updates, expiry, and revocation return 409 instead of recreating authenticated state. Keep a dedicated authenticated Redis/Valkey store with no eviction of live security state. Revocation applies at future session loads and does not continuously recheck active connections.

Function-scoped dependencies finish before response headers; request-scoped resources last through sending and close before background work. A stream failure after headers terminates delivery without a second response. Review transaction boundaries, cancellation, storage outages, and concurrent session changes in application tests.

Policy snapshots describe declared metadata and configuration; they do not prove custom authentication, middleware, or object-level authorization correct. OWASP Top 10 2025 guides security review and does not provide automatic framework compliance.

For production workloads, Flasgo expects you to:

  • Set a strong SECRET_KEY
  • Use explicit ALLOWED_HOSTS
  • Enable secure cookies over HTTPS
  • Keep request limits and security-failure logging enabled unless another trusted layer enforces the same controls
  • Keep CORS disabled or limited to the exact routes, origins, methods, and headers a browser client needs
  • Keep ENABLE_DOCS disabled unless deliberately exposed, and use DOCS_AUTH_BACKEND outside trusted local development
  • Keep WebSocket origin enforcement and message limits enabled
  • Protect metrics with both bearer authentication and network controls
  • Keep validation depth, work, and issue budgets enabled
  • Enforce global quotas at the edge when using multiple workers
  • Use a durable queue for work that must survive process failure
  • Put the app behind a reverse proxy or platform edge for TLS termination

Related docs:

Sources: