corvix.web.middleware¶
Token-based authentication middleware for the Corvix web app.
When CORVIX_SECRET_TOKEN (or CORVIX_SECRET_TOKEN_FILE) is set:
/api/*routes (except/api/health) require anAuthorization: Bearer <token>orX-Corvix-Token: <token>header, or a validcorvix_sessioncookie (so the browser SPA works after logging in via the web UI without needing to inject headers).UI routes (
/,/dashboards/*) require acorvix_sessioncookie; requests without a valid cookie are redirected to/login./api/health,/assets/*,/login, and/logoutare always public.
When the environment variable is not set, the middleware is a no-op and the app behaves exactly as before (backward compatible).
HTTPS detection¶
The corvix_session cookie is marked Secure only when the request
arrives over HTTPS. The scheme is read from request.url.scheme, which
reflects the real protocol when uvicorn is started with --proxy-headers
(trusting X-Forwarded-Proto from a reverse proxy). Without that flag,
direct HTTPS connections are still detected correctly via the connection
scheme. Do not rely on raw X-Forwarded-Proto header inspection from
application code: untrusted clients can spoof it.
Attributes¶
Classes¶
Optional token-based authentication middleware. |
Functions¶
|
Return a signed, time-limited session cookie value. |
|
Return True when value is a valid, unexpired session token. |
|
Parse a raw |
|
Return the configured secret token, or an empty string if not set. |
|
Return True when path should never require authentication. |
|
Send a minimal JSON 401 Unauthorized response via ASGI. |
|
Send a 302 redirect response via ASGI. |
|
Extract and normalise HTTP headers from an ASGI scope. |
|
Return True when the request carries valid API credentials. |
|
Return True when the request carries a valid |
Module Contents¶
- corvix.web.middleware._make_session_cookie(secret: str) str[source][source]¶
Return a signed, time-limited session cookie value.
Format:
{expiry_unix_timestamp}:{hmac_sha256_hex}The HMAC covers both the fixed context string and the expiry timestamp so that the expiry cannot be extended without knowing the secret.
- corvix.web.middleware._verify_session_cookie(secret: str, value: str) bool[source][source]¶
Return True when value is a valid, unexpired session token.
Validates the HMAC signature and rejects tokens whose expiry timestamp is in the past. Uses
hmac.compare_digest()to prevent timing attacks.
- corvix.web.middleware._parse_cookies(cookie_header: str) dict[str, str][source][source]¶
Parse a raw
Cookieheader value into a name→value dict.Uses
http.cookies.SimpleCookiefrom the standard library to handle quoted values and other edge cases correctly.
- corvix.web.middleware._get_secret() str[source][source]¶
Return the configured secret token, or an empty string if not set.
Results are cached for
_SECRET_CACHE_TTLseconds so that deployments usingCORVIX_SECRET_TOKEN_FILEdo not incur a synchronous disk read on every request. A configuration change takes effect within one TTL window.When both
CORVIX_SECRET_TOKENandCORVIX_SECRET_TOKEN_FILEare set simultaneously, logs a warning once per process and returns an empty string (auth disabled) to avoid flooding logs under load.
- corvix.web.middleware._is_public(path: str) bool[source][source]¶
Return True when path should never require authentication.
- async corvix.web.middleware._send_json_401(send: litestar.types.asgi_types.Send) None[source][source]¶
Send a minimal JSON 401 Unauthorized response via ASGI.
- async corvix.web.middleware._send_redirect(send: litestar.types.asgi_types.Send, location: bytes) None[source][source]¶
Send a 302 redirect response via ASGI.
- corvix.web.middleware._parse_request_headers(scope: litestar.types.asgi_types.Scope) dict[bytes, bytes][source][source]¶
Extract and normalise HTTP headers from an ASGI scope.
RFC 7230 §3.2.4: header field values are ISO-8859-1 (latin-1); using latin-1 decoding (rather than strict UTF-8) means malformed byte sequences never raise
UnicodeDecodeErrorand produce a clean 401/redirect instead of a 500.RFC 6265 §5.4: a request may carry multiple
Cookieheaders; they must be treated as if joined by"; ". A plain dict comprehension would silently drop all but the last occurrence, so Cookie header bytes are accumulated separately and joined before being stored.
- corvix.web.middleware._check_api_auth(raw_headers: dict[bytes, bytes], secret: str) bool[source][source]¶
Return True when the request carries valid API credentials.
Checks
Authorization: BearerandX-Corvix-Tokenheaders first (programmatic clients, curl, etc.). Falls back to thecorvix_sessioncookie so browser SPAs work after logging in via the web UI without needing to inject custom headers into everyfetch()call.
- corvix.web.middleware._check_ui_auth(raw_headers: dict[bytes, bytes], secret: str) bool[source][source]¶
Return True when the request carries a valid
corvix_sessioncookie.
- class corvix.web.middleware.TokenAuthMiddleware[source][source]¶
Bases:
litestar.middleware.base.ASGIMiddlewareOptional token-based authentication middleware.
Reads the secret from
CORVIX_SECRET_TOKEN(orCORVIX_SECRET_TOKEN_FILE) with a 60-second TTL cache so that config changes take effect without a restart while avoiding per-request file I/O. When the variable is absent the middleware is a transparent pass-through.