Release Notes¶
v1.2.1 (2026-10-08)¶
Guard-Core org migration¶
Metadata release: PyPI project URLs, the docs canonical domain, and all repository links moved to the Guard-Core org. No code changes.
v1.0.0 (2026-09-24)¶
First stable release: full pipeline parity, CORS through the engine, guard-core 4.0.x tracking (v1.0.0)¶
This is the first tagged, stable release of tornadoapi-guard. PyPI 0.0.1 (2026-04-05) was a scaffolding pre-release; the v1.0.0 draft entries below were never published and are superseded by this entry, which summarizes the full delta since 0.0.1.
- Parity with the other adapters -
SecurityMiddlewarewas rebuilt around guard-core's own components instead of a thin partial wrapper: theSecurityCheckPipelineruns the full check chain, withHandlerInitializer,RouteConfigResolver/RoutingContext,RequestValidator/ValidationContext,ErrorResponseFactory/ResponseContext,BehavioralProcessor/BehavioralContext,SecurityEventBus/MetricsCollector, the cloud handler,RateLimitManager, the security headers manager, and per-route decorators throughBaseSecurityDecorator/RouteConfig. The request/response adapters (tornadoapi_guard/adapters.py) were reworked to feed the pipeline the same shape the FastAPI and Flask adapters produce. - Pipeline-first CORS -
SecurityHandler.prepare()runs the security pipeline before any CORS short-circuit, and preflight handling is delegated toguard_core.sync.handlers.cors_handler.CorsHandler(withis_preflight), so banned IPs and rate-limited clients can no longer preflight freely. - Compatibility - The
guard-coredependency moves from unconstrained to>=4.0.0(no upper bound) inpyproject.toml; master's previous>=1.0.1,<2.0.0cap excluded the current 4.0.x engine line. This release tracks guard-core 4.0.4. - Added (tests) - New suites covering the middleware pipeline end to end and in unit form, wiring, lifecycle, CORS through the pipeline, the Tornado handler, the adapters, and the public re-exports.
- Added (examples) -
examples/simple_appdemonstrating middleware and handler integration. - Packaging (dev) -
guard-agentis added to thedevextra, matching the other adapters: the middleware lifecycle test constructs the middleware withenable_agent=True, and CI installs onlyuv sync --extra dev, so without it the suite fails withAgentPackageNotInstalledError. - Documentation - Added
AGENTS.md/CLAUDE.mdagent guidance, the tornadoapi-guard package skill, and corrected the decorator docs to list valid bypass tokens and remove invalid examples.
v1.0.0 (2026-04-30)¶
Initial public release — fail-secure by default (upstream), agent-stats surface, version reporting (v1.0.0)¶
- Upstream behavior —
SecurityConfig.fail_securedefaults toTrue(inherited fromguard-core >= 3.0.0). When any security check raises an unhandled exception, the request is blocked with HTTP 500 instead of logging and falling through. Restore the old behavior on deployments that depend on it viaSecurityConfig(fail_secure=False). Recommended posture: keep the new default, surface any check exceptions in your monitoring, and fix them — the alternative could mask serious bugs. - Added —
SecurityMiddleware.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 tornadoapi_guard import __version__— package version is exported viaimportlib.metadata.version("tornadoapi_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 tornadoapi-guard version through to the agent for SaaS-side telemetry attribution:SecurityConfig(agent_guard_version=__version__). - Public API —
SecurityMiddleware.agent_statsand__version__are part of the public surface from this first release.
v1.0.0 (2026-04-25)¶
guard-core 2.0.0 protocol alignment (v1.0.0)¶
Changed¶
SecurityMiddleware.suspicious_request_countsis nowdict[str, dict[str, int]]to match the per-category counter shape introduced in guard-core 2.0.0. The middleware annotation is the only call site touched in the adapter; behaviour is delegated to guard-core which now stores counts grouped by detection category instead of a flat per-IP integer.
Requires¶
guard-core>=2.0.0. Adapter middleware updated to match the newsuspicious_request_counts: dict[str, dict[str, int]]protocol shape. tornadoapi-guard does not calldetect_penetration_attempt/detect_penetration_patternsdirectly so the newDetectionResultreturn type does not require code changes here. User code that didn't reach into the protocol internals is unaffected.
Compat notes¶
- No public API changes on
SecurityMiddleware. Users that readmiddleware.suspicious_request_countsdirectly will see the new nested mapping shape and should update their introspection accordingly.
v1.0.0 (2026-04-25, OTel hot-path)¶
Integration fixes for OTel + enrichment pipeline (v1.0.0)¶
Fixed¶
SecurityMiddleware.initialize()is now invoked on the first request via a_ensure_initialized()asyncio-lock guard insiderun_pre_processing(). Previously the method existed but was never called, soHandlerInitializer.initialize_agent_integrations()never ran and the composite handler stayedNone. Without this fix, no OTel span or Logfire log was ever emitted regardless of config.- 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. 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.
Requires¶
guard-core>=1.2.1for the matching OTLP endpoint normalization andBehaviorTrackerwiring fixes. Install the latest withuv add tornadoapi-guard guard-coreorpip install -U tornadoapi-guard guard-core.
Compat notes¶
- No public API changes.
SecurityMiddleware.__init__signature unchanged.
v1.0.0 (2026-04-24)¶
Telemetry pipeline wiring fix (v1.0.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 —
SecurityMiddleware.__init__previously constructedSecurityEventBus(agent_handler, ...)andMetricsCollector(agent_handler, ...)directly, using the bareguard_agenthandler (orNone).middleware.initialize()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 extracts event-bus construction into_build_event_bus_and_contexts(), which consultshandler_initializer.composite_handlerand usesbuild_event_bus()/build_metrics_collector()when the composite is available.initialize()re-invokes_build_event_bus_and_contexts()afterinitialize_agent_integrations()so the dependent contexts (ResponseContext,ValidationContext,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_handlertoCompositeAgentHandleraftermiddleware.initialize()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.
v1.0.0 (2026-04-16)¶
Initial Release (v1.0.0)¶
- Tornado adapter layer:
TornadoGuardRequest,TornadoGuardResponse,TornadoResponseFactorymapping Tornado'sRequestHandlerto guard-core's protocol interface. - SecurityHandler: Base handler subclass integrating guard-core's security pipeline via
prepare()/on_finish()hooks. - SecurityMiddleware: Full security check pipeline (17 checks) with config via
Application.settings["security_middleware"]. - Public API re-exports: All guard-core exports available through
tornadoapi_guardfor a clean import surface. - Example application: Comprehensive Tornado app demonstrating IP filtering, rate limiting, behavioral analysis, security headers, decorators, and WebSocket support.
- Full documentation: MkDocs site with API reference, configuration guides, decorator usage, and security tutorials.
- CI/CD: GitHub Actions workflows for CI, CodeQL, container release, docs deployment, scheduled linting, and PyPI release.
- Development tooling: Pre-commit hooks, Makefile targets, Docker Compose setup, Python 3.10-3.14 support.