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 djapi-guard major bump tracks this upstream change so deployments see a clear signal. - Added —
DjangoAPIGuard.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. Lets app teams build health endpoints that surface agent-side drops and circuit-breaker trips without scraping the agent directly. - Added —
from djangoapi_guard import __version__— package version is now exported viaimportlib.metadata.version("djapi-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 djapi-guard version through to the agent for SaaS-side telemetry attribution:SecurityConfig(agent_guard_version=__version__). - Compatibility —
DjangoAPIGuard.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 the middleware short-circuited preflights ahead of_execute_security_pipeline(theif config.enable_cors and request.method == "OPTIONS"block at line 227), allowing banned IPs and rate-limited clients to preflight freely. - 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.
- Fixed (latent) —
middleware.pywas importingBaseSecurityDecoratorandRouteConfigfromguard_core.decorators.base(the async path) when it should have been usingguard_core.sync.decorators.base. Sync/async protocol mismatches cascaded from there. Surfaced after removing the[[tool.mypy.overrides]] follow_imports = "skip"block. - Fixed (latent) —
cloud_handler.refresh(ttl=...)was being called with attlkwarg the method does not accept; correct call isrefresh_async(). - Fixed (latent) — 4 tests passed
agent_model="..."toSecurityConfig; that field does not exist on the model. - Internal — CORS preflight handling moved to the shared
guard_core.sync.handlers.cors_handler.CorsHandlermodule. Removed all six[[tool.mypy.overrides]]suppression blocks (redis.*,guard_agent.*,guard_core.*,django.*,examples.*,example_app.*/advanced_app.*). Installeddjango-stubsas dev dep;redis7.x,guard-core2.2.0,guard-agent2.2.0 all shippy.typed. Stripped[tool.uv.sources] guard-corelocal-path block from committed pyproject.toml. Addedreset_ratelimit_singletonautouse fixture totests/conftest.pyso test runs no longer accumulate rate-limit state across tests. - Requires —
guard-core>=2.2.0(declared as unconstrainedguard-corein pyproject; documented here for upgrade guidance).
v2.2.0 (2026-04-25)¶
guard-core 2.0.0 compatibility (v2.2.0)¶
- Compat — Requires guard-core 2.0.0 or newer. Adapter middleware updated to match the new
suspicious_request_counts: dict[str, dict[str, int]]protocol shape andDetectionResultreturn type. User code that didn't reach into those internals is unaffected. - Changed —
DjangoAPIGuard.suspicious_request_countsis nowdict[str, dict[str, int]]to mirror the per-IP, per-category counters introduced by guard-core 2.0.0. - Tests —
tests/test_middleware.pymocks fordetect_penetration_patternsanddetect_penetration_attemptnow returnDetectionResult(is_threat=..., trigger_info=...)instead of the legacy(bool, str)tuple.
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 receivemiddleware.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_middleware_lifecycle.py— regression tests pinning the agent_handler rebind and behavior_tracker threading, plus coverage for unbuilt-pipeline and early-decorator-handler paths. - Requires —
guard-core>=1.2.1for the matching OTLP endpoint normalization andBehaviorTrackerwiring fixes. Install the latest withuv add djapi-guard guard-coreorpip install -U djapi-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 usingmiddleware.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 a middleware wiring bug that prevented OpenTelemetry, Logfire, and event/metric/check-log muting from seeing anything emitted by the request-path security pipeline.
- Fixed —
DjangoAPIGuard.__init__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_middleware_wiring.py— four regression tests that pinmw.event_bus.agent_handlerandmw.metrics_collector.agent_handlertoCompositeAgentHandlerafter instantiation when 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_middleware.py— the two coverage tests that pinned the old_init_routing_and_validationguards (test_init_routing_event_bus_none,test_init_routing_response_factory_none) are replaced withtest_build_event_bus_handler_initializer_noneandtest_build_event_bus_route_resolver_nonecovering the new guards in_build_event_bus_and_contexts.
v2.0.0 (2026-03-26)¶
Major Release (v2.0.0)¶
- Guard-Core migration: DjangoAPI 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 Django integration layer.
- Production/Stable status: Development status upgraded from Alpha to Production/Stable.
- Zero breaking changes to public API: All existing imports (
from djangoapi_guard import SecurityConfig,from djangoapi_guard import DjangoAPIGuard, etc.) continue to work exactly as before. - Shared engine across frameworks: The same security engine now powers fastapi-guard and flaskapi-guard, ensuring consistent security behavior across all three frameworks.
v1.0.1 (2026-03-16)¶
Bug Fixes (v1.0.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.0.0 (2026-03-15)¶
Initial Release (v1.0.0)¶
- Initial release of DjangoAPI 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