Release: hardening#10
Merged
Merged
Conversation
Companion to guard-core 2.2.0 and guard-agent 2.3.0. Pipeline-first CORS in the FlaskAPIGuard extension via guard_core.sync.handlers.cors_handler. - _before_request now runs the security pipeline for every method including OPTIONS preflight. Preflights were previously short- circuited inside the extension before the pipeline ran; banned IPs could preflight freely. - Preflight handling moved BEFORE the passthrough / bypass check so cross-origin preflights to excluded paths (e.g. /health) still receive a valid CORS response. Passthrough and bypass return paths now also inject CORS headers via _attach_cors_to_blocked. - _after_request injects CORS headers via the shared guard_core.sync.handlers.cors_handler.CorsHandler module. - Removed every [[tool.mypy.overrides]] suppression block (ignore_missing_imports = true / follow_imports = 'skip' / disallow_untyped_decorators = false). Replaced with proper stubs (django-stubs) and inline-typed packages. - Removed every # type: ignore from edited files. - Stripped [tool.uv.sources] guard-core local-path block from committed pyproject.toml. - Added guard-agent to dev dependencies (was missing -- only mentioned in deptry's per_rule_ignores). Tests exercising agent integration via enable_agent=True now have an explicit declared dev dep. - Test infrastructure: added two regression tests proving cross-origin preflight + GET to excluded paths both work correctly with CORS. Full suite: 216 passed, 100% line + 100% branch coverage. Quality suite (mypy / ruff / vulture / bandit / radon / xenon / deptry) clean. 0 added suppressions. See CHANGELOG.md. BREAKING CHANGE: CORS is configured purely via SecurityConfig.cors_* fields and activates automatically inside the FlaskAPIGuard extension. There is no separate configure_cors entry point. OPTIONS preflight requests are now subject to the full security pipeline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Hardening release. Preflights previously short-circuited inside
_before_requestbefore the security pipeline ran, so banned IPs could preflight freely. Now the security pipeline executes for every request includingOPTIONS. The_after_requesthook injects CORS headers via the new sharedguard_core.sync.handlers.cors_handler.CorsHandlermodule.The branch also removes every form of suppression that had accumulated in pyproject.toml and the test suite, fixing the underlying issues at root.
Pipeline / CORS
_before_request: runs the security pipeline FIRST for every method includingOPTIONS. After the pipeline returnsNone(no block), checksis_preflight()and either builds a preflight response viacors_handler.build_preflight_responseor returnsNoneto continue._after_request: injects CORS headers into normal responses viacors_handler.build_response_headers._handle_preflightflow removed; replaced by_attach_cors_to_blockedand_build_flask_preflight_responsehelpers that delegate toCorsHandler.Suppressions removed (root-cause fixes)
[[tool.mypy.overrides]] ignore_missing_imports = true/follow_imports = "skip"/disallow_untyped_decorators = falseblocks. Replaced with proper stubs and inline-typed packages.# type: ignoremarkers from edited files. Replaced with propercast(...),MagicMock(spec=...), or typed callbacks.[tool.uv.sources] guard-core = { path = ..., editable = true }block stripped from committed pyproject.toml.guard-agentadded to dev dependencies (was missing — only mentioned in deptry config).Related Issue
N/A (audit findings).
Motivation and Context
Companion to guard-core 2.2.0 and guard-agent 2.3.0. The audit found that every adapter shipped its own preflight short-circuit ahead of the security pipeline. guard-core 2.2.0 landed the framework-agnostic
cors_handlermodule so adapters consume one source of truth.Removing the suppressions was a separate-but-related cleanup: per-module mypy overrides like
ignore_missing_imports = truehad been hiding real type mismatches in test fixtures and a few adapter call sites. The strict no-suppression rule across the release wave catches these at root rather than letting them rot.Type of change
How Has This Been Tested?
Full quality suite green:
ruff format/ruff checkmypy flaskapi_guard/ tests/vulturebandit -llradonxenondeptrypytest -W error --cov-branchSuppression scan on the diff: 0 added, all mypy override suppression blocks removed, all
# type: ignoremarkers removed.E2E tested against guard-core 2.2.0 from PyPI plus the local guard-agent 2.3.0 (release/hardening) — 210 tests pass cleanly.
Tested locally on Python 3.10. CI runs the matrix to 3.14.
Screenshots (if appropriate):
N/A — library release.
Checklist: