Release Notes¶
v4.0.0 (2026-04-29)¶
Fail-secure by default (upstream), agent-stats surface, version reporting (v4.0.0)¶
- Breaking (upstream) —
SecurityConfig.fail_securenow defaults toTrue(inherited fromguard-core >= 3.0.0). When any security check raises an unhandled exception, the request is now blocked with HTTP 500 instead of logging and falling through. Bugs in checks that previously slipped past as silent fail-open responses now surface immediately. Restore the old behavior on deployments that depend on it viaSecurityConfig(fail_secure=False). Recommended migration: keep the new default, surface any check exceptions in your monitoring, and fix them — the previous default could mask serious bugs. The flaskapi-guard major bump tracks this upstream change so deployments see a clear signal. - Added —
FlaskAPIGuard.agent_statsread-only@propertyreturning the agent's telemetry buffer state. Returns{"enabled": False}when no agent is wired; otherwise returns{"enabled": True, **agent_handler.get_stats()}exposingevents_dropped,metrics_dropped,circuit_breaker_state, and other agent counters. No caching — fresh on each call. Access the property on the extension instance returned byFlaskAPIGuard(app, config=...)or viaapp.extensions["flaskapi_guard"]["guard"].agent_stats. Lets app teams build Flask health endpoints that surface agent-side drops and circuit-breaker trips without scraping the agent directly. - Added —
from flaskapi_guard import __version__— package version is now exported viaimportlib.metadata.version("flaskapi_guard")with a"0.0.0+unknown"fallback if the package is not installed (development from source). Pairs withguard-core >= 3.0.0'sSecurityConfig.agent_guard_versionso application code can wire the flaskapi-guard version through to the agent for SaaS-side telemetry attribution:SecurityConfig(agent_guard_version=__version__). - Fixed (latent) —
FlaskAPIGuard.refresh_cloud_ip_rangeswas callingcloud_handler.refresh(...)directly. When Redis was enabled, that method raisesRuntimeError("Use refresh_async() when Redis is enabled")— the cloud-IP refresh check would surface as an exception inside the security pipeline. Under the oldfail_secure=Falsedefault the exception was logged and the request fell through, so the bug stayed invisible. Under the newfail_secure=Truedefault it would block every request with HTTP 500 in any deployment that combinesenable_redis=Truewithblock_cloud_providers. Switched tocloud_handler.refresh_async(...)which dispatches Redis-aware vs non-Redis paths internally (matches djangoapi-guard's v3.0.0 fix and tornadoapi-guard's existing dispatch). Same fix shape; pre-existing bug. - Compatibility —
FlaskAPIGuard.agent_statsis purely additive; no existing API was changed.__version__was previously absent; reading it before this release returnedNonevia missing-attribute fallback in some integrations.
v3.0.0 (2026-04-26)¶
Pipeline-first CORS via guard_core.cors_handler (v3.0.0)¶
- Breaking — Preflight
OPTIONSrequests are now subject to the security pipeline (previously short-circuited inside the extension). Banned IPs and rate-limited clients can no longer preflight freely. - Breaking — CORS is now configured exclusively via
SecurityConfig.cors_*fields. The extension wires_before_request/_after_requestautomatically; no separateconfigure_corsentry point. - Fixed — Cross-origin preflight requests to passthrough paths (e.g.
exclude_paths=["/health"]) now receive a valid CORS response. Preflight handling runs ahead of the passthrough/bypass short-circuit so the browser permission check works for excluded paths. - Fixed — Cross-origin GETs to passthrough/bypass paths now carry CORS headers on their responses, matching the previous outer-CORSMiddleware semantics.
- Internal — Both lifecycle hooks delegate to the new shared
guard_core.sync.handlers.cors_handler.CorsHandler. Removed all[[tool.mypy.overrides]] ignore_missing_imports = true/follow_imports = "skip"blocks; replaced with proper inline-typed packages anddjango-stubs. Stripped[tool.uv.sources] guard-corelocal-path block from committed pyproject.toml. Addedguard-agentto dev dependencies (was previously declared only in deptry's per-rule-ignores). - Requires —
guard-core>=2.2.0.
v2.2.0 (2026-04-25)¶
guard-core 2.0.0 protocol-shape adjustment (v2.2.0)¶
- Requires — guard-core 2.0.0 or newer. guard-core's major bump migrates
suspicious_request_countsto a per-category nested dict, replacesdetect_penetration_attempt/detect_penetration_patterns2-tuple returns withDetectionResult, and migrates the cloud-IP cache namespace. - Updated —
FlaskAPIGuard.suspicious_request_countsis now typeddict[str, dict[str, int]]to match guard-core's per-category counter shape. - User-visible impact — User code that didn't reach into those internals continues to work unchanged.
v2.1.1 (2026-04-25)¶
Integration fixes for OTel + enrichment pipeline (v2.1.1)¶
- Fixed — After composite construction,
self.agent_handleris rebound from the bareguard-agentclient to the composite. Downstream callers that receiveextension.agent_handler(most notablyguard_core.utils.extract_client_ip → send_agent_event) now route through the composite, so enrichment and OTel see every event. - Fixed —
BehavioralContextnow receiveshandler_initializer.behavior_tracker, matching the guard-core 1.2.1 wiring. This closes the architectural gap soguard.behavior.recent_event_countpopulates end-to-end whenenable_enrichment=True. - Added —
tests/test_extension_lifecycle.py— regression tests pinning the agent_handler rebind and behavior_tracker threading. - Requires —
guard-core>=1.2.1for the matching OTLP endpoint normalization andBehaviorTrackerwiring fixes. Install the latest withuv add flaskapi-guard guard-coreorpip install -U flaskapi-guard guard-core. - User-visible impact — Users with
enable_otel=True,enable_logfire=True, orenable_enrichment=Truepreviously saw silent drops on a portion of events because callers usingextension.agent_handlerdirectly bypassed the composite handler. After this release every downstream caller routes through the composite, so all events flow through telemetry and enrichment as configured.
v2.1.0 (2026-04-24)¶
Telemetry pipeline wiring fix (v2.1.0)¶
Adopts guard-core 1.1.0 and fixes an extension wiring bug that prevented OpenTelemetry, Logfire, and event/metric/check-log muting from seeing anything emitted by the request-path security pipeline.
- Fixed —
FlaskAPIGuard.init_app()previously constructedSecurityEventBus(agent_handler, ...)andMetricsCollector(agent_handler, ...)in_init_core_components()using the bareguard_agenthandler (orNone)._initialize_handlers()then calledHandlerInitializer.initialize_agent_integrations()which built aCompositeAgentHandlerthat no code path ever reached, because the event bus / metrics collector were already frozen on the bare handler. As a result, every event emitted through the request pipeline (SecurityEventBus.send_middleware_event) and every request metric bypassed OTel, Logfire, and the configuredmuted_event_types/muted_metric_typesfilter. This release splits construction into_init_core_components()(handler_initializer only),_init_route_resolver(), and_build_event_bus_and_contexts()— the last of which consultshandler_initializer.composite_handlerand usesbuild_event_bus()/build_metrics_collector()when the composite is available._initialize_handlers()now re-invokes_build_event_bus_and_contexts()afterinitialize_agent_integrations()so the dependent contexts (ResponseContext,ValidationContext,BypassContext,BehavioralContext) bind to the post-init event bus. - Added —
tests/test_extension/test_extension_wiring.py— four regression tests that pinext.event_bus.agent_handlerandext.metrics_collector.agent_handlertoCompositeAgentHandlerafterinit_appwhen OTel or Logfire is enabled, and confirm all dependent contexts reference the post-init event bus. - Dependencies —
guard-core>=1.1.0,<2.0.0. - User-visible impact — Users already setting
enable_otel=Trueorenable_logfire=TrueonSecurityConfigwere previously getting handler-path events only (ip_banned, rate_limited fromip_ban_manager/rate_limit_handler, etc.) — but never pipeline-path events (penetration_attempt,authentication_failed,user_agent_blocked,https_enforced, etc.) or request metrics (guard.request.duration,guard.request.count,guard.error.count). After this release, every event and every metric flows through the composite, which means OTel spans, Logfire logs, and all mute fields (muted_event_types,muted_metric_types,muted_check_logs) work as documented. NoSecurityConfigchanges required; existing configurations produce strictly more telemetry, not less. - Tests —
tests/test_extension/test_security_extension.py::test_request_without_clientupdated: whenextract_client_ipreturns"unknown",is_ip_allowedraisesValueErroron the unparseable IP and theip_securitycheck correctly returns 403. The test now pins that deterministic-403 contract rather than the stale pre-1.1.0 200.
v2.0.0 (2026-03-26)¶
Major Release (v2.0.0)¶
- Guard-Core migration: FlaskAPI Guard is now a thin adapter over guard-core, the framework-agnostic security engine. All security logic (17 checks, 8 handlers, detection engine) lives in guard-core; this package provides only the Flask integration layer.
- Production/Stable status: Development status upgraded from Alpha to Production/Stable.
- Zero breaking changes to public API: All existing imports (
from flaskapi_guard import SecurityConfig,from flaskapi_guard import FlaskAPIGuard, etc.) continue to work exactly as before. - Shared engine across frameworks: The same security engine now powers fastapi-guard and djangoapi-guard, ensuring consistent security behavior across all three frameworks.
v1.1.1 (2026-03-16)¶
Bug Fixes (v1.1.1)¶
- Per-endpoint rate limit check: Fixed rate limit check to properly evaluate endpoint-specific rate limits. Previously, the rate limit check was only evaluating global rate limits.
v1.1.0 (2026-03-14)¶
New Features (v1.1.0)¶
- Configurable cloud IP refresh interval: New
cloud_ip_refresh_intervalconfig field (default: 3600s, valid range: 60-86400s) allows tuning how often cloud provider IP ranges are refreshed. The interval is propagated to Redis TTL for cache consistency. - Change detection logging for cloud IP refreshes: When cloud IP ranges are refreshed, additions and removals are logged per provider (e.g.,
+12 added, -3 removed), providing visibility into IP range mutations. - Context-aware detection engine: Suspicious pattern rules are now tagged with applicable input contexts (
query_param,url_path,header,request_body). Patterns are only evaluated against relevant input sources, reducing false positives. - Structured JSON logging: New
log_format="json"config option outputs logs as structured JSON ({"timestamp": "...", "level": "...", "logger": "...", "message": "..."}), enabling integration with log aggregation systems (ELK, Datadog, CloudWatch). - Per-provider
last_updatedtimestamps:CloudManagernow tracks when each provider's IP ranges were last refreshed viacloud_handler.last_updated["AWS"], returningdatetime | None.
v1.0.0 (2026-03-13)¶
Initial Release (v1.0.0)¶
- Initial release of Flask API Guard
- IP whitelisting/blacklisting with CIDR support
- Rate limiting (global and per-endpoint)
- Automatic IP banning
- Penetration attempt detection
- User agent filtering
- Content type filtering
- Request size limiting
- Time-based access control
- Behavioral analysis and monitoring
- Custom authentication schemes
- Honeypot detection
- Redis integration for distributed environments
- Security headers management
- CORS configuration
- Emergency mode