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.
Files changed (233) hide show
  1. {guard_core-2.2.2/guard_core.egg-info → guard_core-3.0.0}/PKG-INFO +18 -1
  2. {guard_core-2.2.2 → guard_core-3.0.0}/README.md +17 -0
  3. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/cloud_handler.py +98 -1
  4. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/models.py +26 -2
  5. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/cloud_handler.py +96 -1
  6. {guard_core-2.2.2 → guard_core-3.0.0/guard_core.egg-info}/PKG-INFO +18 -1
  7. {guard_core-2.2.2 → guard_core-3.0.0}/pyproject.toml +1 -1
  8. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_pipeline_fail_secure.py +5 -5
  9. {guard_core-2.2.2 → guard_core-3.0.0}/LICENSE +0 -0
  10. {guard_core-2.2.2 → guard_core-3.0.0}/MANIFEST.in +0 -0
  11. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/__init__.py +0 -0
  12. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/__init__.py +0 -0
  13. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/behavioral/__init__.py +0 -0
  14. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/behavioral/context.py +0 -0
  15. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/behavioral/processor.py +0 -0
  16. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/bypass/__init__.py +0 -0
  17. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/bypass/context.py +0 -0
  18. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/bypass/handler.py +0 -0
  19. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/__init__.py +0 -0
  20. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/base.py +0 -0
  21. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/helpers.py +0 -0
  22. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/__init__.py +0 -0
  23. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/authentication.py +0 -0
  24. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/cloud_ip_refresh.py +0 -0
  25. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/cloud_provider.py +0 -0
  26. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/custom_request.py +0 -0
  27. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/custom_validators.py +0 -0
  28. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/emergency_mode.py +0 -0
  29. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/https_enforcement.py +0 -0
  30. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/ip_security.py +0 -0
  31. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/rate_limit.py +0 -0
  32. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/referrer.py +0 -0
  33. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/request_logging.py +0 -0
  34. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/request_size_content.py +0 -0
  35. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/required_headers.py +0 -0
  36. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/route_config.py +0 -0
  37. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/suspicious_activity.py +0 -0
  38. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/time_window.py +0 -0
  39. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/implementations/user_agent.py +0 -0
  40. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/checks/pipeline.py +0 -0
  41. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/__init__.py +0 -0
  42. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/composite_handler.py +0 -0
  43. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/enricher.py +0 -0
  44. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/event_types.py +0 -0
  45. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/logfire_handler.py +0 -0
  46. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/metrics.py +0 -0
  47. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/middleware_events.py +0 -0
  48. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/events/otel_handler.py +0 -0
  49. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/initialization/__init__.py +0 -0
  50. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/initialization/handler_initializer.py +0 -0
  51. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/responses/__init__.py +0 -0
  52. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/responses/context.py +0 -0
  53. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/responses/factory.py +0 -0
  54. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/routing/__init__.py +0 -0
  55. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/routing/context.py +0 -0
  56. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/routing/resolver.py +0 -0
  57. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/validation/__init__.py +0 -0
  58. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/validation/context.py +0 -0
  59. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/core/validation/validator.py +0 -0
  60. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/__init__.py +0 -0
  61. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/access_control.py +0 -0
  62. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/advanced.py +0 -0
  63. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/authentication.py +0 -0
  64. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/base.py +0 -0
  65. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/behavioral.py +0 -0
  66. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/content_filtering.py +0 -0
  67. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/decorators/rate_limiting.py +0 -0
  68. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/__init__.py +0 -0
  69. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/compiler.py +0 -0
  70. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/monitor.py +0 -0
  71. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/preprocessor.py +0 -0
  72. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_engine/semantic.py +0 -0
  73. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/detection_result.py +0 -0
  74. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/exceptions.py +0 -0
  75. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/__init__.py +0 -0
  76. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/behavior_handler.py +0 -0
  77. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/cloud_ip_stores.py +0 -0
  78. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/cors_handler.py +0 -0
  79. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/dynamic_rule_handler.py +0 -0
  80. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/ipban_handler.py +0 -0
  81. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/ipinfo_handler.py +0 -0
  82. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/ratelimit_handler.py +0 -0
  83. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/redis_handler.py +0 -0
  84. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/security_headers_handler.py +0 -0
  85. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/handlers/suspatterns_handler.py +0 -0
  86. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/__init__.py +0 -0
  87. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/agent_protocol.py +0 -0
  88. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/cloud_ip_store_protocol.py +0 -0
  89. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/geo_ip_protocol.py +0 -0
  90. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/middleware_protocol.py +0 -0
  91. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/redis_protocol.py +0 -0
  92. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/request_protocol.py +0 -0
  93. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/protocols/response_protocol.py +0 -0
  94. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/py.typed +0 -0
  95. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/scripts/__init__.py +0 -0
  96. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/scripts/rate_lua.py +0 -0
  97. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/__init__.py +0 -0
  98. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/__init__.py +0 -0
  99. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/behavioral/__init__.py +0 -0
  100. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/behavioral/context.py +0 -0
  101. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/behavioral/processor.py +0 -0
  102. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/bypass/__init__.py +0 -0
  103. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/bypass/context.py +0 -0
  104. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/bypass/handler.py +0 -0
  105. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/__init__.py +0 -0
  106. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/base.py +0 -0
  107. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/helpers.py +0 -0
  108. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/__init__.py +0 -0
  109. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/authentication.py +0 -0
  110. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/cloud_ip_refresh.py +0 -0
  111. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/cloud_provider.py +0 -0
  112. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/custom_request.py +0 -0
  113. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/custom_validators.py +0 -0
  114. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/emergency_mode.py +0 -0
  115. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/https_enforcement.py +0 -0
  116. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/ip_security.py +0 -0
  117. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/rate_limit.py +0 -0
  118. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/referrer.py +0 -0
  119. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/request_logging.py +0 -0
  120. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/request_size_content.py +0 -0
  121. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/required_headers.py +0 -0
  122. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/route_config.py +0 -0
  123. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/suspicious_activity.py +0 -0
  124. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/time_window.py +0 -0
  125. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/implementations/user_agent.py +0 -0
  126. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/checks/pipeline.py +0 -0
  127. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/__init__.py +0 -0
  128. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/composite_handler.py +0 -0
  129. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/enricher.py +0 -0
  130. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/event_types.py +0 -0
  131. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/logfire_handler.py +0 -0
  132. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/metrics.py +0 -0
  133. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/middleware_events.py +0 -0
  134. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/events/otel_handler.py +0 -0
  135. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/initialization/__init__.py +0 -0
  136. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/initialization/handler_initializer.py +0 -0
  137. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/responses/__init__.py +0 -0
  138. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/responses/context.py +0 -0
  139. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/responses/factory.py +0 -0
  140. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/routing/__init__.py +0 -0
  141. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/routing/context.py +0 -0
  142. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/routing/resolver.py +0 -0
  143. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/validation/__init__.py +0 -0
  144. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/validation/context.py +0 -0
  145. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/core/validation/validator.py +0 -0
  146. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/__init__.py +0 -0
  147. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/access_control.py +0 -0
  148. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/advanced.py +0 -0
  149. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/authentication.py +0 -0
  150. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/base.py +0 -0
  151. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/behavioral.py +0 -0
  152. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/content_filtering.py +0 -0
  153. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/decorators/rate_limiting.py +0 -0
  154. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/__init__.py +0 -0
  155. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/compiler.py +0 -0
  156. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/monitor.py +0 -0
  157. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/preprocessor.py +0 -0
  158. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_engine/semantic.py +0 -0
  159. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/detection_result.py +0 -0
  160. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/__init__.py +0 -0
  161. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/behavior_handler.py +0 -0
  162. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/cloud_ip_stores.py +0 -0
  163. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/cors_handler.py +0 -0
  164. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/dynamic_rule_handler.py +0 -0
  165. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/ipban_handler.py +0 -0
  166. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/ipinfo_handler.py +0 -0
  167. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/ratelimit_handler.py +0 -0
  168. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/redis_handler.py +0 -0
  169. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/security_headers_handler.py +0 -0
  170. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/handlers/suspatterns_handler.py +0 -0
  171. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/__init__.py +0 -0
  172. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/agent_protocol.py +0 -0
  173. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/cloud_ip_store_protocol.py +0 -0
  174. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/geo_ip_protocol.py +0 -0
  175. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/middleware_protocol.py +0 -0
  176. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/redis_protocol.py +0 -0
  177. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/request_protocol.py +0 -0
  178. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/protocols/response_protocol.py +0 -0
  179. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/py.typed +0 -0
  180. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/scripts/__init__.py +0 -0
  181. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/scripts/rate_lua.py +0 -0
  182. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/sync/utils.py +0 -0
  183. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core/utils.py +0 -0
  184. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/SOURCES.txt +0 -0
  185. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/dependency_links.txt +0 -0
  186. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/requires.txt +0 -0
  187. {guard_core-2.2.2 → guard_core-3.0.0}/guard_core.egg-info/top_level.txt +0 -0
  188. {guard_core-2.2.2 → guard_core-3.0.0}/setup.cfg +0 -0
  189. {guard_core-2.2.2 → guard_core-3.0.0}/setup.py +0 -0
  190. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_behavior_rule_ban_duration.py +0 -0
  191. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_check_log_muting.py +0 -0
  192. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_cloud_ip_refresh_on_demand.py +0 -0
  193. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_cloud_ip_stores.py +0 -0
  194. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_compiler_cache.py +0 -0
  195. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_composite_enricher.py +0 -0
  196. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_composite_handler.py +0 -0
  197. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_composite_handler_extra.py +0 -0
  198. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_cors_handler.py +0 -0
  199. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_categories.py +0 -0
  200. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_exclusion_integration.py +0 -0
  201. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_result.py +0 -0
  202. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_detection_result_propagation.py +0 -0
  203. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_dynamic_rule_atomicity.py +0 -0
  204. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher.py +0 -0
  205. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_behavior_correlation.py +0 -0
  206. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_end_to_end.py +0 -0
  207. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_identity.py +0 -0
  208. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_logfire_integration.py +0 -0
  209. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_otel_integration.py +0 -0
  210. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_rule_correlation.py +0 -0
  211. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_enricher_threat_score.py +0 -0
  212. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_event_bus_filtering.py +0 -0
  213. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_event_types.py +0 -0
  214. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_edge_cases.py +0 -0
  215. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer.py +0 -0
  216. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer_enricher.py +0 -0
  217. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer_factories.py +0 -0
  218. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handler_initializer_lazy_init.py +0 -0
  219. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_handlers_integration.py +0 -0
  220. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_cidr.py +0 -0
  221. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_eviction.py +0 -0
  222. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_lifecycle.py +0 -0
  223. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipban_ttl.py +0 -0
  224. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_ipinfo_lifecycle.py +0 -0
  225. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_logfire_handler.py +0 -0
  226. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_logfire_handler_metric.py +0 -0
  227. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_otel_handler.py +0 -0
  228. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_otel_handler_resource_attrs.py +0 -0
  229. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_preprocessor_attack_regions.py +0 -0
  230. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_preprocessor_encodings.py +0 -0
  231. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_suspicious_counts_per_type.py +0 -0
  232. {guard_core-2.2.2 → guard_core-3.0.0}/tests/test_telemetry_integration.py +0 -0
  233. {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: 2.2.2
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
- _ALL_PROVIDERS = set({"AWS", "GCP", "Azure"})
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=False,
275
+ default=True,
276
276
  description=(
277
277
  "Block the request when any security check raises an unexpected exception. "
278
- "False (default) logs the error and falls through (fail-open)."
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
- _ALL_PROVIDERS = set({"AWS", "GCP", "Azure"})
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: 2.2.2
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
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "guard-core"
3
- version = "2.2.2"
3
+ version = "3.0.0"
4
4
  description = "Framework-agnostic security engine for the Guard ecosystem."
5
5
  authors = [
6
6
  {name = "Renzo Franceschini", email = "rennf93@users.noreply.github.com"}
@@ -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 test_fail_secure_field_exists_with_safe_default() -> None:
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 False
12
+ assert config.fail_secure is True
13
13
 
14
14
 
15
- def test_fail_secure_can_be_enabled() -> None:
16
- config = SecurityConfig(fail_secure=True)
17
- assert config.fail_secure is True
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