guard-core 2.2.2__tar.gz → 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {guard_core-2.2.2/guard_core.egg-info → guard_core-3.0.0}/PKG-INFO +18 -1
- {guard_core-2.2.2 → guard_core-3.0.0}/README.md +17 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/cloud_handler.py +98 -1
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/models.py +26 -2
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/cloud_handler.py +96 -1
- {guard_core-2.2.2 → guard_core-3.0.0/guard_core.egg-info}/PKG-INFO +18 -1
- {guard_core-2.2.2 → guard_core-3.0.0}/pyproject.toml +1 -1
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_pipeline_fail_secure.py +5 -5
- {guard_core-2.2.2 → guard_core-3.0.0}/LICENSE +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/MANIFEST.in +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/behavioral/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/behavioral/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/behavioral/processor.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/bypass/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/bypass/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/bypass/handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/base.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/helpers.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/authentication.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/cloud_ip_refresh.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/cloud_provider.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/custom_request.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/custom_validators.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/emergency_mode.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/https_enforcement.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/ip_security.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/rate_limit.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/referrer.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/request_logging.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/request_size_content.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/required_headers.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/route_config.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/suspicious_activity.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/time_window.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/user_agent.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/pipeline.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/composite_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/enricher.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/event_types.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/logfire_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/metrics.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/middleware_events.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/otel_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/initialization/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/initialization/handler_initializer.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/responses/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/responses/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/responses/factory.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/routing/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/routing/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/routing/resolver.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/validation/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/validation/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/validation/validator.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/access_control.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/advanced.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/authentication.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/base.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/behavioral.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/content_filtering.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/rate_limiting.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/compiler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/monitor.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/preprocessor.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/semantic.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_result.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/exceptions.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/behavior_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/cloud_ip_stores.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/cors_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/dynamic_rule_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/ipban_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/ipinfo_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/ratelimit_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/redis_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/security_headers_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/suspatterns_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/agent_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/cloud_ip_store_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/geo_ip_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/middleware_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/redis_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/request_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/response_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/py.typed +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/scripts/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/scripts/rate_lua.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/behavioral/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/behavioral/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/behavioral/processor.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/bypass/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/bypass/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/bypass/handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/base.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/helpers.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/authentication.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/cloud_ip_refresh.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/cloud_provider.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/custom_request.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/custom_validators.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/emergency_mode.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/https_enforcement.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/ip_security.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/rate_limit.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/referrer.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/request_logging.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/request_size_content.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/required_headers.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/route_config.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/suspicious_activity.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/time_window.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/user_agent.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/pipeline.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/composite_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/enricher.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/event_types.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/logfire_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/metrics.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/middleware_events.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/otel_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/initialization/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/initialization/handler_initializer.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/responses/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/responses/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/responses/factory.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/routing/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/routing/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/routing/resolver.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/validation/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/validation/context.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/validation/validator.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/access_control.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/advanced.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/authentication.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/base.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/behavioral.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/content_filtering.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/rate_limiting.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/compiler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/monitor.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/preprocessor.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/semantic.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_result.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/behavior_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/cloud_ip_stores.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/cors_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/dynamic_rule_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/ipban_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/ipinfo_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/ratelimit_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/redis_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/security_headers_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/suspatterns_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/agent_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/cloud_ip_store_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/geo_ip_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/middleware_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/redis_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/request_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/response_protocol.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/py.typed +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/scripts/__init__.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/scripts/rate_lua.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/utils.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/utils.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/SOURCES.txt +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/dependency_links.txt +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/requires.txt +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/top_level.txt +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/setup.cfg +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/setup.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_behavior_rule_ban_duration.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_check_log_muting.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_cloud_ip_refresh_on_demand.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_cloud_ip_stores.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_compiler_cache.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_composite_enricher.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_composite_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_composite_handler_extra.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_cors_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_categories.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_exclusion_integration.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_result.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_result_propagation.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_dynamic_rule_atomicity.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_behavior_correlation.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_end_to_end.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_identity.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_logfire_integration.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_otel_integration.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_rule_correlation.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_threat_score.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_event_bus_filtering.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_event_types.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_edge_cases.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer_enricher.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer_factories.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer_lazy_init.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handlers_integration.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_cidr.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_eviction.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_lifecycle.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_ttl.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipinfo_lifecycle.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_logfire_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_logfire_handler_metric.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_otel_handler.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_otel_handler_resource_attrs.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_preprocessor_attack_regions.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_preprocessor_encodings.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_suspicious_counts_per_type.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_telemetry_integration.py +0 -0
- {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_threat_ban_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guard-core
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Framework-agnostic security engine for the Guard ecosystem.
|
|
5
5
|
Author-email: Renzo Franceschini <rennf93@users.noreply.github.com>
|
|
6
6
|
License: MIT
|
|
@@ -308,6 +308,23 @@ See the [SecurityConfig Reference](https://rennf93.github.io/guard-core/latest/c
|
|
|
308
308
|
|
|
309
309
|
___
|
|
310
310
|
|
|
311
|
+
Migration: fail_secure default flipped
|
|
312
|
+
--------------------------------------
|
|
313
|
+
|
|
314
|
+
`SecurityConfig.fail_secure` now defaults to `True`. When a security check raises an unexpected exception, the request is blocked with HTTP 500 instead of falling through.
|
|
315
|
+
|
|
316
|
+
**Why**: the old fail-open default silently masked check bugs. The new default surfaces them so they can be fixed instead of leaking past the security layer.
|
|
317
|
+
|
|
318
|
+
**Migration**: to restore the previous fail-open behavior, opt in explicitly:
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
config = SecurityConfig(fail_secure=False)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Recommended path: keep the new default and fix any check exceptions that surface. The old default could mask genuine bugs.
|
|
325
|
+
|
|
326
|
+
___
|
|
327
|
+
|
|
311
328
|
Detection Engine
|
|
312
329
|
----------------
|
|
313
330
|
|
|
@@ -250,6 +250,23 @@ See the [SecurityConfig Reference](https://rennf93.github.io/guard-core/latest/c
|
|
|
250
250
|
|
|
251
251
|
___
|
|
252
252
|
|
|
253
|
+
Migration: fail_secure default flipped
|
|
254
|
+
--------------------------------------
|
|
255
|
+
|
|
256
|
+
`SecurityConfig.fail_secure` now defaults to `True`. When a security check raises an unexpected exception, the request is blocked with HTTP 500 instead of falling through.
|
|
257
|
+
|
|
258
|
+
**Why**: the old fail-open default silently masked check bugs. The new default surfaces them so they can be fixed instead of leaking past the security layer.
|
|
259
|
+
|
|
260
|
+
**Migration**: to restore the previous fail-open behavior, opt in explicitly:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
config = SecurityConfig(fail_secure=False)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Recommended path: keep the new default and fix any check exceptions that surface. The old default could mask genuine bugs.
|
|
267
|
+
|
|
268
|
+
___
|
|
269
|
+
|
|
253
270
|
Detection Engine
|
|
254
271
|
----------------
|
|
255
272
|
|
|
@@ -94,7 +94,92 @@ async def fetch_azure_ip_ranges() -> set[ipaddress.IPv4Network | ipaddress.IPv6N
|
|
|
94
94
|
return set()
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
async def fetch_digitalocean_ip_ranges() -> set[
|
|
98
|
+
ipaddress.IPv4Network | ipaddress.IPv6Network
|
|
99
|
+
]:
|
|
100
|
+
try:
|
|
101
|
+
async with aiohttp.ClientSession() as session:
|
|
102
|
+
response = await session.get(
|
|
103
|
+
"https://www.digitalocean.com/geo/google.csv",
|
|
104
|
+
timeout=aiohttp.ClientTimeout(total=10),
|
|
105
|
+
)
|
|
106
|
+
response.raise_for_status()
|
|
107
|
+
body = await response.text()
|
|
108
|
+
|
|
109
|
+
networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set()
|
|
110
|
+
for raw_line in body.splitlines():
|
|
111
|
+
line = raw_line.strip()
|
|
112
|
+
if not line or line.startswith("#"):
|
|
113
|
+
continue
|
|
114
|
+
prefix = line.split(",", 1)[0].strip()
|
|
115
|
+
if not prefix:
|
|
116
|
+
continue
|
|
117
|
+
try:
|
|
118
|
+
networks.add(ipaddress.ip_network(prefix))
|
|
119
|
+
except ValueError:
|
|
120
|
+
continue
|
|
121
|
+
return networks
|
|
122
|
+
except Exception as e:
|
|
123
|
+
logging.error(f"Failed to fetch DigitalOcean IP ranges: {str(e)}")
|
|
124
|
+
return set()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
async def fetch_linode_ip_ranges() -> set[
|
|
128
|
+
ipaddress.IPv4Network | ipaddress.IPv6Network
|
|
129
|
+
]:
|
|
130
|
+
try:
|
|
131
|
+
async with aiohttp.ClientSession() as session:
|
|
132
|
+
response = await session.get(
|
|
133
|
+
"https://geoip.linode.com/",
|
|
134
|
+
timeout=aiohttp.ClientTimeout(total=10),
|
|
135
|
+
)
|
|
136
|
+
response.raise_for_status()
|
|
137
|
+
body = await response.text()
|
|
138
|
+
|
|
139
|
+
networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set()
|
|
140
|
+
for raw_line in body.splitlines():
|
|
141
|
+
line = raw_line.strip()
|
|
142
|
+
if not line or line.startswith("#"):
|
|
143
|
+
continue
|
|
144
|
+
prefix = line.split(",", 1)[0].strip()
|
|
145
|
+
if not prefix:
|
|
146
|
+
continue
|
|
147
|
+
try:
|
|
148
|
+
networks.add(ipaddress.ip_network(prefix))
|
|
149
|
+
except ValueError:
|
|
150
|
+
continue
|
|
151
|
+
return networks
|
|
152
|
+
except Exception as e:
|
|
153
|
+
logging.error(f"Failed to fetch Linode IP ranges: {str(e)}")
|
|
154
|
+
return set()
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
async def fetch_vultr_ip_ranges() -> set[ipaddress.IPv4Network | ipaddress.IPv6Network]:
|
|
158
|
+
try:
|
|
159
|
+
async with aiohttp.ClientSession() as session:
|
|
160
|
+
response = await session.get(
|
|
161
|
+
"https://geofeed.constant.com/?json",
|
|
162
|
+
timeout=aiohttp.ClientTimeout(total=10),
|
|
163
|
+
)
|
|
164
|
+
response.raise_for_status()
|
|
165
|
+
data = await response.json(content_type=None)
|
|
166
|
+
|
|
167
|
+
networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set()
|
|
168
|
+
for entry in data.get("subnets", []):
|
|
169
|
+
prefix = entry.get("ip_prefix")
|
|
170
|
+
if not prefix:
|
|
171
|
+
continue
|
|
172
|
+
try:
|
|
173
|
+
networks.add(ipaddress.ip_network(prefix))
|
|
174
|
+
except ValueError:
|
|
175
|
+
continue
|
|
176
|
+
return networks
|
|
177
|
+
except Exception as e:
|
|
178
|
+
logging.error(f"Failed to fetch Vultr IP ranges: {str(e)}")
|
|
179
|
+
return set()
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
_ALL_PROVIDERS = set({"AWS", "GCP", "Azure", "DigitalOcean", "Linode", "Vultr"})
|
|
98
183
|
|
|
99
184
|
|
|
100
185
|
class CloudManager:
|
|
@@ -113,6 +198,9 @@ class CloudManager:
|
|
|
113
198
|
"AWS": set(),
|
|
114
199
|
"GCP": set(),
|
|
115
200
|
"Azure": set(),
|
|
201
|
+
"DigitalOcean": set(),
|
|
202
|
+
"Linode": set(),
|
|
203
|
+
"Vultr": set(),
|
|
116
204
|
}
|
|
117
205
|
cls._instance.last_updated = {provider: None for provider in _ALL_PROVIDERS}
|
|
118
206
|
cls._instance.redis_handler = None
|
|
@@ -146,6 +234,9 @@ class CloudManager:
|
|
|
146
234
|
"AWS": fetch_aws_ip_ranges,
|
|
147
235
|
"GCP": fetch_gcp_ip_ranges,
|
|
148
236
|
"Azure": fetch_azure_ip_ranges,
|
|
237
|
+
"DigitalOcean": fetch_digitalocean_ip_ranges,
|
|
238
|
+
"Linode": fetch_linode_ip_ranges,
|
|
239
|
+
"Vultr": fetch_vultr_ip_ranges,
|
|
149
240
|
}[provider]()
|
|
150
241
|
if ranges:
|
|
151
242
|
old_ranges = self.ip_ranges.get(provider, set())
|
|
@@ -195,6 +286,9 @@ class CloudManager:
|
|
|
195
286
|
"AWS": fetch_aws_ip_ranges,
|
|
196
287
|
"GCP": fetch_gcp_ip_ranges,
|
|
197
288
|
"Azure": fetch_azure_ip_ranges,
|
|
289
|
+
"DigitalOcean": fetch_digitalocean_ip_ranges,
|
|
290
|
+
"Linode": fetch_linode_ip_ranges,
|
|
291
|
+
"Vultr": fetch_vultr_ip_ranges,
|
|
198
292
|
}[provider]
|
|
199
293
|
|
|
200
294
|
ranges = await fetch_func()
|
|
@@ -233,6 +327,9 @@ class CloudManager:
|
|
|
233
327
|
"AWS": fetch_aws_ip_ranges,
|
|
234
328
|
"GCP": fetch_gcp_ip_ranges,
|
|
235
329
|
"Azure": fetch_azure_ip_ranges,
|
|
330
|
+
"DigitalOcean": fetch_digitalocean_ip_ranges,
|
|
331
|
+
"Linode": fetch_linode_ip_ranges,
|
|
332
|
+
"Vultr": fetch_vultr_ip_ranges,
|
|
236
333
|
}[provider]
|
|
237
334
|
ranges = await fetch_func()
|
|
238
335
|
if ranges:
|
|
@@ -272,10 +272,12 @@ class SecurityConfig(BaseModel):
|
|
|
272
272
|
)
|
|
273
273
|
|
|
274
274
|
fail_secure: bool = Field(
|
|
275
|
-
default=
|
|
275
|
+
default=True,
|
|
276
276
|
description=(
|
|
277
277
|
"Block the request when any security check raises an unexpected exception. "
|
|
278
|
-
"
|
|
278
|
+
"True (default) returns HTTP 500 so check bugs surface; "
|
|
279
|
+
"False logs and falls through (fail-open) - "
|
|
280
|
+
"opt-in only for staging diagnostics."
|
|
279
281
|
),
|
|
280
282
|
)
|
|
281
283
|
|
|
@@ -332,6 +334,26 @@ class SecurityConfig(BaseModel):
|
|
|
332
334
|
default=3, description="Number of retry attempts for failed requests"
|
|
333
335
|
)
|
|
334
336
|
|
|
337
|
+
agent_project_encryption_key: str | None = Field(
|
|
338
|
+
default=None,
|
|
339
|
+
description=(
|
|
340
|
+
"Per-project AES-256-GCM key used to encrypt the telemetry payload "
|
|
341
|
+
"between the agent and the SaaS. When set, the agent posts to "
|
|
342
|
+
"/api/v1/events/encrypted instead of /api/v1/events. Required for "
|
|
343
|
+
"API keys that have encryption enforced server-side."
|
|
344
|
+
),
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
agent_guard_version: str | None = Field(
|
|
348
|
+
default=None,
|
|
349
|
+
description=(
|
|
350
|
+
"Framework wrapper version (e.g. fastapi-guard's __version__) "
|
|
351
|
+
"propagated to the agent so the SaaS can attribute telemetry to "
|
|
352
|
+
"the wrapper version, not just the agent version. Set this to "
|
|
353
|
+
"your framework integration's __version__ at construction time."
|
|
354
|
+
),
|
|
355
|
+
)
|
|
356
|
+
|
|
335
357
|
enable_dynamic_rules: bool = Field(
|
|
336
358
|
default=False, description="Enable dynamic rule updates from SaaS platform"
|
|
337
359
|
)
|
|
@@ -656,6 +678,8 @@ class SecurityConfig(BaseModel):
|
|
|
656
678
|
enable_metrics=self.agent_enable_metrics,
|
|
657
679
|
timeout=self.agent_timeout,
|
|
658
680
|
retry_attempts=self.agent_retry_attempts,
|
|
681
|
+
project_encryption_key=self.agent_project_encryption_key,
|
|
682
|
+
guard_version=self.agent_guard_version,
|
|
659
683
|
)
|
|
660
684
|
except ImportError:
|
|
661
685
|
return None
|
|
@@ -92,7 +92,90 @@ def fetch_azure_ip_ranges() -> set[ipaddress.IPv4Network | ipaddress.IPv6Network
|
|
|
92
92
|
return set()
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
def fetch_digitalocean_ip_ranges() -> set[
|
|
96
|
+
ipaddress.IPv4Network | ipaddress.IPv6Network
|
|
97
|
+
]:
|
|
98
|
+
try:
|
|
99
|
+
with requests.Session() as session:
|
|
100
|
+
response = session.get(
|
|
101
|
+
"https://www.digitalocean.com/geo/google.csv",
|
|
102
|
+
timeout=10,
|
|
103
|
+
)
|
|
104
|
+
response.raise_for_status()
|
|
105
|
+
body = response.text
|
|
106
|
+
|
|
107
|
+
networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set()
|
|
108
|
+
for raw_line in body.splitlines():
|
|
109
|
+
line = raw_line.strip()
|
|
110
|
+
if not line or line.startswith("#"):
|
|
111
|
+
continue
|
|
112
|
+
prefix = line.split(",", 1)[0].strip()
|
|
113
|
+
if not prefix:
|
|
114
|
+
continue
|
|
115
|
+
try:
|
|
116
|
+
networks.add(ipaddress.ip_network(prefix))
|
|
117
|
+
except ValueError:
|
|
118
|
+
continue
|
|
119
|
+
return networks
|
|
120
|
+
except Exception as e:
|
|
121
|
+
logging.error(f"Failed to fetch DigitalOcean IP ranges: {str(e)}")
|
|
122
|
+
return set()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def fetch_linode_ip_ranges() -> set[ipaddress.IPv4Network | ipaddress.IPv6Network]:
|
|
126
|
+
try:
|
|
127
|
+
with requests.Session() as session:
|
|
128
|
+
response = session.get(
|
|
129
|
+
"https://geoip.linode.com/",
|
|
130
|
+
timeout=10,
|
|
131
|
+
)
|
|
132
|
+
response.raise_for_status()
|
|
133
|
+
body = response.text
|
|
134
|
+
|
|
135
|
+
networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set()
|
|
136
|
+
for raw_line in body.splitlines():
|
|
137
|
+
line = raw_line.strip()
|
|
138
|
+
if not line or line.startswith("#"):
|
|
139
|
+
continue
|
|
140
|
+
prefix = line.split(",", 1)[0].strip()
|
|
141
|
+
if not prefix:
|
|
142
|
+
continue
|
|
143
|
+
try:
|
|
144
|
+
networks.add(ipaddress.ip_network(prefix))
|
|
145
|
+
except ValueError:
|
|
146
|
+
continue
|
|
147
|
+
return networks
|
|
148
|
+
except Exception as e:
|
|
149
|
+
logging.error(f"Failed to fetch Linode IP ranges: {str(e)}")
|
|
150
|
+
return set()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def fetch_vultr_ip_ranges() -> set[ipaddress.IPv4Network | ipaddress.IPv6Network]:
|
|
154
|
+
try:
|
|
155
|
+
with requests.Session() as session:
|
|
156
|
+
response = session.get(
|
|
157
|
+
"https://geofeed.constant.com/?json",
|
|
158
|
+
timeout=10,
|
|
159
|
+
)
|
|
160
|
+
response.raise_for_status()
|
|
161
|
+
data = response.json()
|
|
162
|
+
|
|
163
|
+
networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set()
|
|
164
|
+
for entry in data.get("subnets", []):
|
|
165
|
+
prefix = entry.get("ip_prefix")
|
|
166
|
+
if not prefix:
|
|
167
|
+
continue
|
|
168
|
+
try:
|
|
169
|
+
networks.add(ipaddress.ip_network(prefix))
|
|
170
|
+
except ValueError:
|
|
171
|
+
continue
|
|
172
|
+
return networks
|
|
173
|
+
except Exception as e:
|
|
174
|
+
logging.error(f"Failed to fetch Vultr IP ranges: {str(e)}")
|
|
175
|
+
return set()
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
_ALL_PROVIDERS = set({"AWS", "GCP", "Azure", "DigitalOcean", "Linode", "Vultr"})
|
|
96
179
|
|
|
97
180
|
|
|
98
181
|
class CloudManager:
|
|
@@ -111,6 +194,9 @@ class CloudManager:
|
|
|
111
194
|
"AWS": set(),
|
|
112
195
|
"GCP": set(),
|
|
113
196
|
"Azure": set(),
|
|
197
|
+
"DigitalOcean": set(),
|
|
198
|
+
"Linode": set(),
|
|
199
|
+
"Vultr": set(),
|
|
114
200
|
}
|
|
115
201
|
cls._instance.last_updated = {provider: None for provider in _ALL_PROVIDERS}
|
|
116
202
|
cls._instance.redis_handler = None
|
|
@@ -144,6 +230,9 @@ class CloudManager:
|
|
|
144
230
|
"AWS": fetch_aws_ip_ranges,
|
|
145
231
|
"GCP": fetch_gcp_ip_ranges,
|
|
146
232
|
"Azure": fetch_azure_ip_ranges,
|
|
233
|
+
"DigitalOcean": fetch_digitalocean_ip_ranges,
|
|
234
|
+
"Linode": fetch_linode_ip_ranges,
|
|
235
|
+
"Vultr": fetch_vultr_ip_ranges,
|
|
147
236
|
}[provider]()
|
|
148
237
|
if ranges:
|
|
149
238
|
old_ranges = self.ip_ranges.get(provider, set())
|
|
@@ -193,6 +282,9 @@ class CloudManager:
|
|
|
193
282
|
"AWS": fetch_aws_ip_ranges,
|
|
194
283
|
"GCP": fetch_gcp_ip_ranges,
|
|
195
284
|
"Azure": fetch_azure_ip_ranges,
|
|
285
|
+
"DigitalOcean": fetch_digitalocean_ip_ranges,
|
|
286
|
+
"Linode": fetch_linode_ip_ranges,
|
|
287
|
+
"Vultr": fetch_vultr_ip_ranges,
|
|
196
288
|
}[provider]
|
|
197
289
|
|
|
198
290
|
ranges = fetch_func()
|
|
@@ -231,6 +323,9 @@ class CloudManager:
|
|
|
231
323
|
"AWS": fetch_aws_ip_ranges,
|
|
232
324
|
"GCP": fetch_gcp_ip_ranges,
|
|
233
325
|
"Azure": fetch_azure_ip_ranges,
|
|
326
|
+
"DigitalOcean": fetch_digitalocean_ip_ranges,
|
|
327
|
+
"Linode": fetch_linode_ip_ranges,
|
|
328
|
+
"Vultr": fetch_vultr_ip_ranges,
|
|
234
329
|
}[provider]
|
|
235
330
|
ranges = fetch_func()
|
|
236
331
|
if ranges:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guard-core
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Framework-agnostic security engine for the Guard ecosystem.
|
|
5
5
|
Author-email: Renzo Franceschini <rennf93@users.noreply.github.com>
|
|
6
6
|
License: MIT
|
|
@@ -308,6 +308,23 @@ See the [SecurityConfig Reference](https://rennf93.github.io/guard-core/latest/c
|
|
|
308
308
|
|
|
309
309
|
___
|
|
310
310
|
|
|
311
|
+
Migration: fail_secure default flipped
|
|
312
|
+
--------------------------------------
|
|
313
|
+
|
|
314
|
+
`SecurityConfig.fail_secure` now defaults to `True`. When a security check raises an unexpected exception, the request is blocked with HTTP 500 instead of falling through.
|
|
315
|
+
|
|
316
|
+
**Why**: the old fail-open default silently masked check bugs. The new default surfaces them so they can be fixed instead of leaking past the security layer.
|
|
317
|
+
|
|
318
|
+
**Migration**: to restore the previous fail-open behavior, opt in explicitly:
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
config = SecurityConfig(fail_secure=False)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Recommended path: keep the new default and fix any check exceptions that surface. The old default could mask genuine bugs.
|
|
325
|
+
|
|
326
|
+
___
|
|
327
|
+
|
|
311
328
|
Detection Engine
|
|
312
329
|
----------------
|
|
313
330
|
|
|
@@ -6,15 +6,15 @@ from guard_core.core.checks.pipeline import SecurityCheckPipeline
|
|
|
6
6
|
from guard_core.models import SecurityConfig
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def
|
|
9
|
+
def test_default_security_config_is_fail_secure() -> None:
|
|
10
10
|
config = SecurityConfig()
|
|
11
11
|
assert hasattr(config, "fail_secure")
|
|
12
|
-
assert config.fail_secure is
|
|
12
|
+
assert config.fail_secure is True
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def
|
|
16
|
-
config = SecurityConfig(fail_secure=
|
|
17
|
-
assert config.fail_secure is
|
|
15
|
+
def test_fail_secure_can_be_disabled() -> None:
|
|
16
|
+
config = SecurityConfig(fail_secure=False)
|
|
17
|
+
assert config.fail_secure is False
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
@pytest.mark.asyncio
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/authentication.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/cloud_ip_refresh.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/cloud_provider.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/custom_request.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/custom_validators.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/emergency_mode.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/https_enforcement.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/request_logging.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/request_size_content.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/required_headers.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/route_config.py
RENAMED
|
File without changes
|
{guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/suspicious_activity.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|