v7.8.0
Lockstep release tracking guard-core 3.14.0: missing-client rejection, forwarded-header joining, clean Redis-down responses, and WebSocket protection (v7.8.0)
Special thanks to @RomanPszonka for the reports and advisories behind this release and the support throughout. Thank you for making the Guard Core ecosystem better!
- Compatibility (dependency floor, breaking for anyone pinned below 3.14.0) -
guard-corechanges from an unconstrained dependency toguard-core>=3.14.0inpyproject.toml.pip install --upgrade fastapi-guardalone could previously leave an older guard-core in place; against guard-core 3.12.0 that is anImportErroratimport guardtime (check_ip_access/check_rate_limit_by_ip/is_ip_allowed, added in 3.13.0). No upper bound; the floor moves with each lockstep release (fg #120). - Security (GHSA-8xvm-856x-7hwp) -
StarletteGuardRequest.headersnow joins repeated field lines (RFC 7230 5.2) before guard-core resolves the client fromX-Forwarded-For; previously only the first line was visible, letting a client's own forged line hide the real proxy-appended one and rotate past rate limiting. - Compatibility (GHSA-634g-4wr8-xwxv) - A request with no client address is now rejected by default (
fail_secure=True) instead of skipping the entire security pipeline; this is guard-core 3.14.0's own fix, fastapi-guard's test suite and docs are brought in line with it here. New"unix"trusted_proxiestoken for Unix-socket and serverless deployments. - Fixed (#76) -
SecurityMiddlewareno longer crashes with an unhandled 500 (or fails app startup) when Redis is unreachable at initialization.dispatchnow catchesGuardRedisErrorand returns a clean 503 withRetry-After: 5, retrying on the next request; the lifespan warmer logs and continues instead of crashing boot. - Security (GHSA-63qv-gh36-52qf) - New
guard_websocketdependency (Depends(guard_websocket)) for@app.websocketroutes:SecurityMiddlewarenever runs for WebSocket scopes (BaseHTTPMiddlewareskips non-HTTP), so a banned or blacklisted IP, or one over its rate limit, previously reachedaccept()unchecked. The example app's "WebSocket protection" claim is now true. A Redis failure during the handshake now followsredis_fail_openandfail_securethe same way the HTTP pipeline does, instead of leaking an unhandledGuardRedisError; a fail-secure refusal closes the connection with code 1013. - Added (guard-core #81 item 3) -
add_status_routenow acceptsdependencies=[...](FastAPI apps only), so the opt-in/_guard/statusroute can be gated behind an existing auth dependency instead of relying solely on proxy-level restriction. - Compatibility (lockstep) - fastapi-guard 7.8.0 tracks guard-core 3.14.0. guard-core 3.14.0 is not yet published to PyPI as of this release commit; CI resolves
guard-core>=3.14.0fresh from PyPI (uv.lockis gitignored) and will fail until it is. This commit is held locally, matching the pattern set by earlier lockstep releases, until guard-core 3.14.0 ships. See guard-core 3.14.0's release notes for the full engine-side list: bounded in-memory rate-limit and behavior-tracker stores, float anomaly statistics, a per-request scan value cap, the AzureCloud tag fix, GeoIP last-known-good on refresh failure, telemetry secret redaction, ban-address canonicalization, and new SSRF detection forms.
What's Changed
Full Changelog: 7.7.0...7.8.0