raxe 0.4.6__py3-none-any.whl
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.
- raxe/__init__.py +101 -0
- raxe/application/__init__.py +48 -0
- raxe/application/ab_testing.py +170 -0
- raxe/application/analytics/__init__.py +30 -0
- raxe/application/analytics/achievement_service.py +444 -0
- raxe/application/analytics/repositories.py +172 -0
- raxe/application/analytics/retention_service.py +267 -0
- raxe/application/analytics/statistics_service.py +419 -0
- raxe/application/analytics/streak_service.py +283 -0
- raxe/application/apply_policy.py +291 -0
- raxe/application/eager_l2.py +503 -0
- raxe/application/preloader.py +353 -0
- raxe/application/scan_merger.py +321 -0
- raxe/application/scan_pipeline.py +1059 -0
- raxe/application/scan_pipeline_async.py +403 -0
- raxe/application/session_tracker.py +458 -0
- raxe/application/telemetry_manager.py +357 -0
- raxe/application/telemetry_orchestrator.py +1210 -0
- raxe/async_sdk/__init__.py +34 -0
- raxe/async_sdk/cache.py +286 -0
- raxe/async_sdk/client.py +556 -0
- raxe/async_sdk/wrappers/__init__.py +23 -0
- raxe/async_sdk/wrappers/openai.py +238 -0
- raxe/cli/__init__.py +21 -0
- raxe/cli/auth.py +1047 -0
- raxe/cli/branding.py +235 -0
- raxe/cli/config.py +334 -0
- raxe/cli/custom_rules.py +458 -0
- raxe/cli/doctor.py +686 -0
- raxe/cli/error_handler.py +665 -0
- raxe/cli/event.py +648 -0
- raxe/cli/exit_codes.py +57 -0
- raxe/cli/expiry_warning.py +302 -0
- raxe/cli/export.py +183 -0
- raxe/cli/history.py +247 -0
- raxe/cli/l2_formatter.py +872 -0
- raxe/cli/main.py +1137 -0
- raxe/cli/models.py +590 -0
- raxe/cli/output.py +403 -0
- raxe/cli/privacy.py +84 -0
- raxe/cli/profiler.py +262 -0
- raxe/cli/progress.py +379 -0
- raxe/cli/progress_context.py +101 -0
- raxe/cli/repl.py +394 -0
- raxe/cli/rules.py +542 -0
- raxe/cli/setup_wizard.py +721 -0
- raxe/cli/stats.py +292 -0
- raxe/cli/suppress.py +501 -0
- raxe/cli/telemetry.py +1384 -0
- raxe/cli/test.py +130 -0
- raxe/cli/tune.py +315 -0
- raxe/cli/validate.py +218 -0
- raxe/domain/__init__.py +30 -0
- raxe/domain/analytics/__init__.py +97 -0
- raxe/domain/analytics/achievements.py +306 -0
- raxe/domain/analytics/models.py +120 -0
- raxe/domain/analytics/retention.py +168 -0
- raxe/domain/analytics/statistics.py +207 -0
- raxe/domain/analytics/streaks.py +173 -0
- raxe/domain/engine/__init__.py +15 -0
- raxe/domain/engine/executor.py +396 -0
- raxe/domain/engine/matcher.py +212 -0
- raxe/domain/inline_suppression.py +176 -0
- raxe/domain/ml/__init__.py +133 -0
- raxe/domain/ml/embedding_cache.py +309 -0
- raxe/domain/ml/gemma_detector.py +921 -0
- raxe/domain/ml/gemma_models.py +346 -0
- raxe/domain/ml/l2_config.py +428 -0
- raxe/domain/ml/l2_output_schema.py +443 -0
- raxe/domain/ml/manifest_loader.py +309 -0
- raxe/domain/ml/manifest_schema.py +345 -0
- raxe/domain/ml/model_metadata.py +263 -0
- raxe/domain/ml/model_registry.py +786 -0
- raxe/domain/ml/protocol.py +282 -0
- raxe/domain/ml/scoring_models.py +419 -0
- raxe/domain/ml/stub_detector.py +397 -0
- raxe/domain/ml/threat_scorer.py +757 -0
- raxe/domain/ml/tokenizer_registry.py +372 -0
- raxe/domain/ml/voting/__init__.py +89 -0
- raxe/domain/ml/voting/config.py +595 -0
- raxe/domain/ml/voting/engine.py +465 -0
- raxe/domain/ml/voting/head_voters.py +378 -0
- raxe/domain/ml/voting/models.py +222 -0
- raxe/domain/models.py +82 -0
- raxe/domain/packs/__init__.py +17 -0
- raxe/domain/packs/models.py +304 -0
- raxe/domain/policies/__init__.py +20 -0
- raxe/domain/policies/evaluator.py +212 -0
- raxe/domain/policies/models.py +223 -0
- raxe/domain/rules/__init__.py +32 -0
- raxe/domain/rules/custom.py +286 -0
- raxe/domain/rules/models.py +273 -0
- raxe/domain/rules/schema.py +166 -0
- raxe/domain/rules/validator.py +556 -0
- raxe/domain/suppression.py +801 -0
- raxe/domain/suppression_factory.py +174 -0
- raxe/domain/telemetry/__init__.py +116 -0
- raxe/domain/telemetry/backpressure.py +424 -0
- raxe/domain/telemetry/event_creator.py +362 -0
- raxe/domain/telemetry/events.py +1282 -0
- raxe/domain/telemetry/priority.py +263 -0
- raxe/domain/telemetry/scan_telemetry_builder.py +670 -0
- raxe/infrastructure/__init__.py +25 -0
- raxe/infrastructure/analytics/__init__.py +18 -0
- raxe/infrastructure/analytics/aggregator.py +484 -0
- raxe/infrastructure/analytics/aggregator_optimized.py +184 -0
- raxe/infrastructure/analytics/engine.py +748 -0
- raxe/infrastructure/analytics/repository.py +409 -0
- raxe/infrastructure/analytics/streaks.py +467 -0
- raxe/infrastructure/analytics/views.py +178 -0
- raxe/infrastructure/cloud/__init__.py +9 -0
- raxe/infrastructure/config/__init__.py +56 -0
- raxe/infrastructure/config/endpoints.py +641 -0
- raxe/infrastructure/config/scan_config.py +352 -0
- raxe/infrastructure/config/yaml_config.py +459 -0
- raxe/infrastructure/database/__init__.py +10 -0
- raxe/infrastructure/database/connection.py +200 -0
- raxe/infrastructure/database/models.py +325 -0
- raxe/infrastructure/database/scan_history.py +764 -0
- raxe/infrastructure/ml/__init__.py +0 -0
- raxe/infrastructure/ml/download_progress.py +438 -0
- raxe/infrastructure/ml/model_downloader.py +457 -0
- raxe/infrastructure/models/__init__.py +16 -0
- raxe/infrastructure/models/discovery.py +461 -0
- raxe/infrastructure/packs/__init__.py +13 -0
- raxe/infrastructure/packs/loader.py +407 -0
- raxe/infrastructure/packs/registry.py +381 -0
- raxe/infrastructure/policies/__init__.py +16 -0
- raxe/infrastructure/policies/api_client.py +256 -0
- raxe/infrastructure/policies/validator.py +227 -0
- raxe/infrastructure/policies/yaml_loader.py +250 -0
- raxe/infrastructure/rules/__init__.py +18 -0
- raxe/infrastructure/rules/custom_loader.py +224 -0
- raxe/infrastructure/rules/versioning.py +222 -0
- raxe/infrastructure/rules/yaml_loader.py +286 -0
- raxe/infrastructure/security/__init__.py +31 -0
- raxe/infrastructure/security/auth.py +145 -0
- raxe/infrastructure/security/policy_validator.py +124 -0
- raxe/infrastructure/security/signatures.py +171 -0
- raxe/infrastructure/suppression/__init__.py +36 -0
- raxe/infrastructure/suppression/composite_repository.py +154 -0
- raxe/infrastructure/suppression/sqlite_repository.py +231 -0
- raxe/infrastructure/suppression/yaml_composite_repository.py +156 -0
- raxe/infrastructure/suppression/yaml_repository.py +510 -0
- raxe/infrastructure/telemetry/__init__.py +79 -0
- raxe/infrastructure/telemetry/acquisition.py +179 -0
- raxe/infrastructure/telemetry/config.py +254 -0
- raxe/infrastructure/telemetry/credential_store.py +947 -0
- raxe/infrastructure/telemetry/dual_queue.py +1123 -0
- raxe/infrastructure/telemetry/flush_helper.py +343 -0
- raxe/infrastructure/telemetry/flush_scheduler.py +776 -0
- raxe/infrastructure/telemetry/health_client.py +394 -0
- raxe/infrastructure/telemetry/hook.py +347 -0
- raxe/infrastructure/telemetry/queue.py +520 -0
- raxe/infrastructure/telemetry/sender.py +476 -0
- raxe/infrastructure/tracking/__init__.py +13 -0
- raxe/infrastructure/tracking/usage.py +389 -0
- raxe/integrations/__init__.py +55 -0
- raxe/integrations/availability.py +143 -0
- raxe/integrations/registry.py +122 -0
- raxe/integrations/utils.py +135 -0
- raxe/mcp/__init__.py +62 -0
- raxe/mcp/cli.py +97 -0
- raxe/mcp/server.py +409 -0
- raxe/monitoring/__init__.py +51 -0
- raxe/monitoring/metrics.py +372 -0
- raxe/monitoring/profiler.py +388 -0
- raxe/monitoring/server.py +136 -0
- raxe/packs/core/v1.0.0/pack.yaml +1394 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-001@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-006@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-014@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-017@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-022@1.0.0.yaml +67 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-023@1.0.0.yaml +91 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-024@1.0.0.yaml +80 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-025@1.0.0.yaml +81 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-026@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-027@1.0.0.yaml +77 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-028@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-029@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-030@1.0.0.yaml +55 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-033@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-034@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-035@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-046@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-047@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-048@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-049@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-050@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-068@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-078@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-2001@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-2004@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-201@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-202@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-203@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3007@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3016@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3026@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3027@1.0.0.yaml +64 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3028@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3029@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3030@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3031@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3032@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3033@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-3034@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-79@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-80@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-81@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-82@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-83@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-84@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-85@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-86@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-87@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-88@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-89@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-90@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-91@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-92@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-93@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-94@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-95@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-96@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-97@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/PI/pi-98@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-007@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-015@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-016@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-017@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-021@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-022@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-023@1.0.0.yaml +78 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-024@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-025@1.0.0.yaml +93 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-026@1.0.0.yaml +81 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-027@1.0.0.yaml +82 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-028@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-033@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-036@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-037@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-052@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-054@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-056@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-065@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-075@1.0.0.yaml +45 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-079@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1080@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1090@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1104@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1105@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-1112@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-201@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-202@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-203@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-204@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-205@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-206@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-207@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-208@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-209@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-210@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-211@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-212@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-213@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-214@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-215@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-216@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-217@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-218@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-219@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-220@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-221@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-222@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-223@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-224@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-225@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-226@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-227@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-228@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-229@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-230@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-231@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-232@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-233@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-234@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-235@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-236@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-237@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/cmd/cmd-238@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-013@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-019@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-020@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-024@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-029@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-038@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-044@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-067@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-069@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-100@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-101@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-102@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-103@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-104@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-105@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-106@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-107@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-108@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-109@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-110@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-111@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-112@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-113@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-114@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-115@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-116@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-117@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-118@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-119@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-120@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-201@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-203@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3004@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3006@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-3011@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-5016@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-6001@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-6002@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-70@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-71@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-72@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-73@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-74@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-75@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-76@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-77@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-78@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-79@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-80@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-81@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-82@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-83@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-84@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-85@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-86@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-87@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-88@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-89@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-90@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-91@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-92@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-93@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-94@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-95@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-96@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-97@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-98@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/enc/enc-99@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-001@1.0.0.yaml +73 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-002@1.0.0.yaml +71 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-003@1.0.0.yaml +65 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-004@1.0.0.yaml +73 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-101@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-102@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-103@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-104@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-105@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-106@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-107@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-108@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-109@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-110@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-111@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-112@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-113@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-114@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-115@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-116@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-117@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-118@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-119@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-120@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-121@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-122@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-123@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-124@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-125@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-126@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-127@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-128@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-129@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-130@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-131@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-132@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-133@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-134@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-135@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-136@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-137@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-138@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-139@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-140@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-141@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-142@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-143@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-144@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-145@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-146@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-147@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-148@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-149@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-150@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-151@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-152@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-153@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-154@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-155@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-156@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-157@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-158@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-159@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-160@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/hc/hc-161@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-001@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-009@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-020@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-021@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-022@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-028@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-033@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-034@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-036@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-039@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-056@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-066@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-076@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-098@1.0.0.yaml +46 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-103@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-104@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-105@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-110@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-111@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-112@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-113@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-114@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-115@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-116@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-117@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-118@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-119@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-120@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-121@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-122@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-123@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-124@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-125@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-126@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-127@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-128@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-129@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-130@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-131@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-132@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-133@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-134@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-135@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-136@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-137@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-138@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-139@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-140@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-141@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-142@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-143@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-144@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-145@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-146@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-147@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-148@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-149@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-150@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-151@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-152@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-153@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-154@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-155@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-156@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-157@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-158@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-159@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-160@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-161@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-162@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-201@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-203@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-204@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-205@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-206@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/jb/jb-207@1.0.0.yaml +49 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-001@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-009@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-012@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-017@1.0.0.yaml +48 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-022@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-025@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-027@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-028@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-034@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-037@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-040@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-041@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-044@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-050@1.0.0.yaml +57 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-051@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-052@1.0.0.yaml +52 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-053@1.0.0.yaml +56 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-054@1.0.0.yaml +53 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-055@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-056@1.0.0.yaml +51 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-058@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2015@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2025@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2026@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2035@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2037@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-2042@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3001@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3002@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3003@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3004@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3005@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3006@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3007@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3008@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3009@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3010@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3011@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3012@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3013@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3014@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3015@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3016@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3017@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3018@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3019@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3020@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3021@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3022@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3023@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3024@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3025@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3026@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3027@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3028@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3029@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3030@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3031@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3032@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3033@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3034@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3035@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3036@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3037@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3038@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3039@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3040@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3041@1.0.0.yaml +39 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3042@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3043@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3044@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3045@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3046@1.0.0.yaml +37 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3047@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3048@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3049@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3050@1.0.0.yaml +44 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3051@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3052@1.0.0.yaml +36 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3053@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3054@1.0.0.yaml +35 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3055@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3056@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3057@1.0.0.yaml +40 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3058@1.0.0.yaml +43 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3059@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3060@1.0.0.yaml +42 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3061@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3062@1.0.0.yaml +50 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3063@1.0.0.yaml +54 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3064@1.0.0.yaml +78 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3065@1.0.0.yaml +84 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3066@1.0.0.yaml +84 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3067@1.0.0.yaml +88 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3068@1.0.0.yaml +94 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3069@1.0.0.yaml +90 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3070@1.0.0.yaml +99 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3071@1.0.0.yaml +91 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3072@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3073@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3074@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3075@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3076@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3077@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3078@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3079@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3080@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3081@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3082@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3083@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3084@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/pii/pii-3085@1.0.0.yaml +38 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-016@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-028@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-042@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-044@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-045@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-050@1.0.0.yaml +47 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-201@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-202@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3001@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3006@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3009@1.0.0.yaml +41 -0
- raxe/packs/core/v1.0.0/rules/rag/rag-3012@1.0.0.yaml +41 -0
- raxe/plugins/__init__.py +98 -0
- raxe/plugins/custom_rules.py +380 -0
- raxe/plugins/loader.py +389 -0
- raxe/plugins/manager.py +538 -0
- raxe/plugins/protocol.py +428 -0
- raxe/py.typed +0 -0
- raxe/sdk/__init__.py +77 -0
- raxe/sdk/agent_scanner.py +1918 -0
- raxe/sdk/client.py +1603 -0
- raxe/sdk/decorator.py +175 -0
- raxe/sdk/exceptions.py +859 -0
- raxe/sdk/integrations/__init__.py +277 -0
- raxe/sdk/integrations/agent_scanner.py +71 -0
- raxe/sdk/integrations/autogen.py +872 -0
- raxe/sdk/integrations/crewai.py +1368 -0
- raxe/sdk/integrations/dspy.py +845 -0
- raxe/sdk/integrations/extractors.py +363 -0
- raxe/sdk/integrations/huggingface.py +395 -0
- raxe/sdk/integrations/langchain.py +948 -0
- raxe/sdk/integrations/litellm.py +484 -0
- raxe/sdk/integrations/llamaindex.py +1049 -0
- raxe/sdk/integrations/portkey.py +831 -0
- raxe/sdk/suppression_context.py +215 -0
- raxe/sdk/wrappers/__init__.py +163 -0
- raxe/sdk/wrappers/anthropic.py +310 -0
- raxe/sdk/wrappers/openai.py +221 -0
- raxe/sdk/wrappers/vertexai.py +484 -0
- raxe/utils/__init__.py +12 -0
- raxe/utils/error_sanitizer.py +135 -0
- raxe/utils/logging.py +241 -0
- raxe/utils/performance.py +414 -0
- raxe/utils/profiler.py +339 -0
- raxe/utils/validators.py +170 -0
- raxe-0.4.6.dist-info/METADATA +471 -0
- raxe-0.4.6.dist-info/RECORD +668 -0
- raxe-0.4.6.dist-info/WHEEL +5 -0
- raxe-0.4.6.dist-info/entry_points.txt +2 -0
- raxe-0.4.6.dist-info/licenses/LICENSE +56 -0
- raxe-0.4.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
"""Rule execution engine.
|
|
2
|
+
|
|
3
|
+
Pure domain layer - executes rules against text to produce detections.
|
|
4
|
+
All functions are stateless and side-effect free.
|
|
5
|
+
|
|
6
|
+
Performance targets:
|
|
7
|
+
- <5ms P95 for 10KB text with 15 L1 rules
|
|
8
|
+
- <1ms average for typical prompts
|
|
9
|
+
"""
|
|
10
|
+
import time
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from datetime import datetime, timezone
|
|
13
|
+
|
|
14
|
+
from raxe.domain.engine.matcher import Match, PatternMatcher
|
|
15
|
+
from raxe.domain.rules.models import Rule, Severity
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class Detection:
|
|
20
|
+
"""A detected threat from a rule match.
|
|
21
|
+
|
|
22
|
+
Immutable value object representing a security threat.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
rule_id: ID of rule that matched
|
|
26
|
+
rule_version: Version of rule that matched
|
|
27
|
+
severity: Threat severity level
|
|
28
|
+
confidence: Detection confidence (0.0-1.0)
|
|
29
|
+
matches: List of pattern matches that triggered detection
|
|
30
|
+
detected_at: ISO timestamp when detected
|
|
31
|
+
detection_layer: Layer that produced this detection (L1, L2, or PLUGIN)
|
|
32
|
+
layer_latency_ms: Time taken by this layer to produce detection
|
|
33
|
+
category: Category of threat (e.g., prompt_injection, jailbreak)
|
|
34
|
+
message: Human-readable message describing the detection
|
|
35
|
+
explanation: Optional explanation of why this was detected
|
|
36
|
+
risk_explanation: Explanation of why this pattern is dangerous
|
|
37
|
+
remediation_advice: How to fix or mitigate this threat
|
|
38
|
+
docs_url: Link to documentation for learning more
|
|
39
|
+
is_flagged: True if detection was matched by a FLAG suppression
|
|
40
|
+
suppression_reason: Reason for suppression (if flagged or logged)
|
|
41
|
+
"""
|
|
42
|
+
rule_id: str
|
|
43
|
+
rule_version: str
|
|
44
|
+
severity: Severity
|
|
45
|
+
confidence: float
|
|
46
|
+
matches: list[Match]
|
|
47
|
+
detected_at: str
|
|
48
|
+
detection_layer: str = "L1" # Default to L1 for backward compatibility
|
|
49
|
+
layer_latency_ms: float = 0.0
|
|
50
|
+
category: str = "unknown"
|
|
51
|
+
message: str = ""
|
|
52
|
+
explanation: str | None = None
|
|
53
|
+
risk_explanation: str = ""
|
|
54
|
+
remediation_advice: str = ""
|
|
55
|
+
docs_url: str = ""
|
|
56
|
+
is_flagged: bool = False
|
|
57
|
+
suppression_reason: str | None = None
|
|
58
|
+
|
|
59
|
+
def __post_init__(self) -> None:
|
|
60
|
+
"""Validate detection after construction."""
|
|
61
|
+
if not (0.0 <= self.confidence <= 1.0):
|
|
62
|
+
raise ValueError(f"Confidence must be 0-1, got {self.confidence}")
|
|
63
|
+
if not self.matches:
|
|
64
|
+
raise ValueError("Detection must have at least one match")
|
|
65
|
+
if self.detection_layer not in ("L1", "L2", "PLUGIN"):
|
|
66
|
+
raise ValueError(f"detection_layer must be L1, L2, or PLUGIN, got {self.detection_layer}")
|
|
67
|
+
if self.layer_latency_ms < 0:
|
|
68
|
+
raise ValueError(f"layer_latency_ms cannot be negative: {self.layer_latency_ms}")
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def match_count(self) -> int:
|
|
72
|
+
"""Number of pattern matches."""
|
|
73
|
+
return len(self.matches)
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def threat_summary(self) -> str:
|
|
77
|
+
"""Human-readable summary of threat.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Summary string like "CRITICAL: pi-001 (confidence: 0.95, matches: 2)"
|
|
81
|
+
"""
|
|
82
|
+
return (
|
|
83
|
+
f"{self.severity.value.upper()}: {self.rule_id} "
|
|
84
|
+
f"(confidence: {self.confidence:.2f}, matches: {self.match_count})"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def versioned_rule_id(self) -> str:
|
|
89
|
+
"""Full versioned rule identifier.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
String like "pi-001@1.0.0"
|
|
93
|
+
"""
|
|
94
|
+
return f"{self.rule_id}@{self.rule_version}"
|
|
95
|
+
|
|
96
|
+
def to_dict(self) -> dict[str, object]:
|
|
97
|
+
"""Convert to dictionary for serialization.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Dictionary representation of detection
|
|
101
|
+
"""
|
|
102
|
+
return {
|
|
103
|
+
"rule_id": self.rule_id,
|
|
104
|
+
"rule_version": self.rule_version,
|
|
105
|
+
"severity": self.severity.value,
|
|
106
|
+
"confidence": self.confidence,
|
|
107
|
+
"match_count": self.match_count,
|
|
108
|
+
"detected_at": self.detected_at,
|
|
109
|
+
"threat_summary": self.threat_summary,
|
|
110
|
+
"detection_layer": self.detection_layer,
|
|
111
|
+
"layer_latency_ms": self.layer_latency_ms,
|
|
112
|
+
"category": self.category,
|
|
113
|
+
"message": self.message,
|
|
114
|
+
"explanation": self.explanation,
|
|
115
|
+
"risk_explanation": self.risk_explanation,
|
|
116
|
+
"remediation_advice": self.remediation_advice,
|
|
117
|
+
"docs_url": self.docs_url,
|
|
118
|
+
"is_flagged": self.is_flagged,
|
|
119
|
+
"suppression_reason": self.suppression_reason,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
def with_flag(self, reason: str) -> "Detection":
|
|
123
|
+
"""Create a copy of this detection with is_flagged=True.
|
|
124
|
+
|
|
125
|
+
Used by suppression system when FLAG action is matched.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
reason: The reason for flagging this detection
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
New Detection instance with is_flagged=True
|
|
132
|
+
"""
|
|
133
|
+
# Since Detection is frozen, we must create a new instance
|
|
134
|
+
return Detection(
|
|
135
|
+
rule_id=self.rule_id,
|
|
136
|
+
rule_version=self.rule_version,
|
|
137
|
+
severity=self.severity,
|
|
138
|
+
confidence=self.confidence,
|
|
139
|
+
matches=self.matches,
|
|
140
|
+
detected_at=self.detected_at,
|
|
141
|
+
detection_layer=self.detection_layer,
|
|
142
|
+
layer_latency_ms=self.layer_latency_ms,
|
|
143
|
+
category=self.category,
|
|
144
|
+
message=self.message,
|
|
145
|
+
explanation=self.explanation,
|
|
146
|
+
risk_explanation=self.risk_explanation,
|
|
147
|
+
remediation_advice=self.remediation_advice,
|
|
148
|
+
docs_url=self.docs_url,
|
|
149
|
+
is_flagged=True,
|
|
150
|
+
suppression_reason=reason,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@dataclass(frozen=True)
|
|
155
|
+
class ScanResult:
|
|
156
|
+
"""Result of scanning text against rules.
|
|
157
|
+
|
|
158
|
+
Aggregates all detections with metadata about the scan.
|
|
159
|
+
|
|
160
|
+
Attributes:
|
|
161
|
+
detections: List of detected threats (may be empty)
|
|
162
|
+
scanned_at: ISO timestamp when scan started
|
|
163
|
+
text_length: Length of scanned text in characters
|
|
164
|
+
rules_checked: Number of rules evaluated
|
|
165
|
+
scan_duration_ms: Time taken to scan in milliseconds
|
|
166
|
+
"""
|
|
167
|
+
detections: list[Detection]
|
|
168
|
+
scanned_at: str
|
|
169
|
+
text_length: int
|
|
170
|
+
rules_checked: int
|
|
171
|
+
scan_duration_ms: float
|
|
172
|
+
|
|
173
|
+
def __post_init__(self) -> None:
|
|
174
|
+
"""Validate scan result."""
|
|
175
|
+
if self.text_length < 0:
|
|
176
|
+
raise ValueError(f"text_length cannot be negative: {self.text_length}")
|
|
177
|
+
if self.rules_checked < 0:
|
|
178
|
+
raise ValueError(f"rules_checked cannot be negative: {self.rules_checked}")
|
|
179
|
+
if self.scan_duration_ms < 0:
|
|
180
|
+
raise ValueError(f"scan_duration_ms cannot be negative: {self.scan_duration_ms}")
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def has_detections(self) -> bool:
|
|
184
|
+
"""True if any threats detected."""
|
|
185
|
+
return len(self.detections) > 0
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def highest_severity(self) -> Severity | None:
|
|
189
|
+
"""Highest severity across all detections.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Highest severity or None if no detections
|
|
193
|
+
"""
|
|
194
|
+
if not self.detections:
|
|
195
|
+
return None
|
|
196
|
+
|
|
197
|
+
# Severity order (lower number = more severe)
|
|
198
|
+
severity_order = {
|
|
199
|
+
Severity.CRITICAL: 0,
|
|
200
|
+
Severity.HIGH: 1,
|
|
201
|
+
Severity.MEDIUM: 2,
|
|
202
|
+
Severity.LOW: 3,
|
|
203
|
+
Severity.INFO: 4,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return min(
|
|
207
|
+
(d.severity for d in self.detections),
|
|
208
|
+
key=lambda s: severity_order[s],
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def total_matches(self) -> int:
|
|
213
|
+
"""Total pattern matches across all detections."""
|
|
214
|
+
return sum(d.match_count for d in self.detections)
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def detection_count(self) -> int:
|
|
218
|
+
"""Number of detections (rules that matched)."""
|
|
219
|
+
return len(self.detections)
|
|
220
|
+
|
|
221
|
+
def to_dict(self) -> dict[str, object]:
|
|
222
|
+
"""Convert to dictionary for serialization.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
Dictionary representation of scan result
|
|
226
|
+
"""
|
|
227
|
+
return {
|
|
228
|
+
"has_detections": self.has_detections,
|
|
229
|
+
"detection_count": self.detection_count,
|
|
230
|
+
"highest_severity": self.highest_severity.value if self.highest_severity else None,
|
|
231
|
+
"total_matches": self.total_matches,
|
|
232
|
+
"text_length": self.text_length,
|
|
233
|
+
"rules_checked": self.rules_checked,
|
|
234
|
+
"scan_duration_ms": self.scan_duration_ms,
|
|
235
|
+
"scanned_at": self.scanned_at,
|
|
236
|
+
"detections": [d.to_dict() for d in self.detections],
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class RuleExecutor:
|
|
241
|
+
"""Execute rules against text to detect threats.
|
|
242
|
+
|
|
243
|
+
Pure domain logic - stateless and side-effect free.
|
|
244
|
+
Uses PatternMatcher for actual pattern matching.
|
|
245
|
+
|
|
246
|
+
Thread-safe for concurrent scans.
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
def __init__(self) -> None:
|
|
250
|
+
"""Initialize with pattern matcher."""
|
|
251
|
+
self.matcher = PatternMatcher()
|
|
252
|
+
|
|
253
|
+
def execute_rule(self, text: str, rule: Rule) -> Detection | None:
|
|
254
|
+
"""Execute a single rule against text.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
text: Text to scan
|
|
258
|
+
rule: Rule to apply
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Detection if rule matched, None otherwise
|
|
262
|
+
|
|
263
|
+
Note:
|
|
264
|
+
Implements OR logic: if any pattern matches, rule matches.
|
|
265
|
+
"""
|
|
266
|
+
# Match all patterns in rule (OR logic)
|
|
267
|
+
matches = self.matcher.match_all_patterns(text, rule.patterns)
|
|
268
|
+
|
|
269
|
+
if not matches:
|
|
270
|
+
return None
|
|
271
|
+
|
|
272
|
+
# Calculate confidence based on match quality
|
|
273
|
+
confidence = self._calculate_confidence(rule, matches)
|
|
274
|
+
|
|
275
|
+
# Derive category from rule family
|
|
276
|
+
category = rule.family.value.lower() if hasattr(rule.family, 'value') else str(rule.family).lower()
|
|
277
|
+
|
|
278
|
+
# Create message from rule
|
|
279
|
+
message = f"{rule.name}: {rule.description[:100]}" # Truncate long descriptions
|
|
280
|
+
|
|
281
|
+
# Create detection with explainability fields from rule
|
|
282
|
+
return Detection(
|
|
283
|
+
rule_id=rule.rule_id,
|
|
284
|
+
rule_version=rule.version,
|
|
285
|
+
severity=rule.severity,
|
|
286
|
+
confidence=confidence,
|
|
287
|
+
matches=matches,
|
|
288
|
+
detected_at=datetime.now(timezone.utc).isoformat(),
|
|
289
|
+
detection_layer="L1", # Executor always produces L1 detections
|
|
290
|
+
layer_latency_ms=0.0, # Will be set by caller if needed
|
|
291
|
+
category=category,
|
|
292
|
+
message=message,
|
|
293
|
+
explanation=None,
|
|
294
|
+
risk_explanation=rule.risk_explanation,
|
|
295
|
+
remediation_advice=rule.remediation_advice,
|
|
296
|
+
docs_url=rule.docs_url,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def execute_rules(
|
|
300
|
+
self,
|
|
301
|
+
text: str,
|
|
302
|
+
rules: list[Rule],
|
|
303
|
+
) -> ScanResult:
|
|
304
|
+
"""Execute all rules against text.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
text: Text to scan
|
|
308
|
+
rules: Rules to apply
|
|
309
|
+
|
|
310
|
+
Returns:
|
|
311
|
+
ScanResult with all detections and metadata
|
|
312
|
+
|
|
313
|
+
Note:
|
|
314
|
+
Continues scanning even if individual rules fail.
|
|
315
|
+
Failed rules are skipped (caller should log).
|
|
316
|
+
"""
|
|
317
|
+
start_time = time.perf_counter()
|
|
318
|
+
scan_started_at = datetime.now(timezone.utc).isoformat()
|
|
319
|
+
|
|
320
|
+
detections: list[Detection] = []
|
|
321
|
+
|
|
322
|
+
for rule in rules:
|
|
323
|
+
try:
|
|
324
|
+
detection = self.execute_rule(text, rule)
|
|
325
|
+
if detection:
|
|
326
|
+
detections.append(detection)
|
|
327
|
+
except Exception: # noqa: S112
|
|
328
|
+
# Rule failed - skip it and continue
|
|
329
|
+
# Note: Broad except is intentional - domain layer can't log
|
|
330
|
+
# Caller in application layer should log failures
|
|
331
|
+
continue
|
|
332
|
+
|
|
333
|
+
duration_ms = (time.perf_counter() - start_time) * 1000
|
|
334
|
+
|
|
335
|
+
return ScanResult(
|
|
336
|
+
detections=detections,
|
|
337
|
+
scanned_at=scan_started_at,
|
|
338
|
+
text_length=len(text),
|
|
339
|
+
rules_checked=len(rules),
|
|
340
|
+
scan_duration_ms=duration_ms,
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
def _calculate_confidence(
|
|
344
|
+
self,
|
|
345
|
+
rule: Rule,
|
|
346
|
+
matches: list[Match],
|
|
347
|
+
) -> float:
|
|
348
|
+
"""Calculate detection confidence.
|
|
349
|
+
|
|
350
|
+
Combines rule's base confidence with match quality factors:
|
|
351
|
+
- Number of matches (more = higher confidence)
|
|
352
|
+
- Match length (longer = higher confidence)
|
|
353
|
+
- Pattern diversity (multiple patterns = higher confidence)
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
rule: The rule that matched
|
|
357
|
+
matches: Pattern matches
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
Confidence score 0.0-1.0 (capped at rule's base confidence)
|
|
361
|
+
"""
|
|
362
|
+
base_confidence = rule.confidence
|
|
363
|
+
|
|
364
|
+
# Quality factors
|
|
365
|
+
# More matches increases confidence (up to 3 matches = 100% of factor)
|
|
366
|
+
match_count_factor = min(len(matches) / 3.0, 1.0)
|
|
367
|
+
|
|
368
|
+
# Multiple different patterns matching is stronger signal
|
|
369
|
+
unique_patterns = len({m.pattern_index for m in matches})
|
|
370
|
+
pattern_diversity_factor = min(unique_patterns / len(rule.patterns), 1.0)
|
|
371
|
+
|
|
372
|
+
# Average match length (longer matches = higher confidence)
|
|
373
|
+
avg_match_length = sum(m.match_length for m in matches) / len(matches)
|
|
374
|
+
length_factor = min(avg_match_length / 20.0, 1.0) # 20+ chars = 100%
|
|
375
|
+
|
|
376
|
+
# Combined quality (weighted average)
|
|
377
|
+
quality = (
|
|
378
|
+
0.4 * match_count_factor +
|
|
379
|
+
0.4 * pattern_diversity_factor +
|
|
380
|
+
0.2 * length_factor
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
# Final confidence: base * (0.7 + 0.3 * quality)
|
|
384
|
+
# This means:
|
|
385
|
+
# - Minimum 70% of base confidence (at least one match)
|
|
386
|
+
# - Maximum 100% of base confidence (perfect quality)
|
|
387
|
+
combined = base_confidence * (0.7 + 0.3 * quality)
|
|
388
|
+
|
|
389
|
+
return min(combined, 1.0)
|
|
390
|
+
|
|
391
|
+
def clear_cache(self) -> None:
|
|
392
|
+
"""Clear pattern matcher cache.
|
|
393
|
+
|
|
394
|
+
Useful for testing or when rules change.
|
|
395
|
+
"""
|
|
396
|
+
self.matcher.clear_cache()
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""Pattern matching engine for threat detection.
|
|
2
|
+
|
|
3
|
+
Pure domain layer - NO I/O operations.
|
|
4
|
+
All functions are stateless and side-effect free.
|
|
5
|
+
|
|
6
|
+
Performance targets:
|
|
7
|
+
- <1ms per pattern match
|
|
8
|
+
- Pattern compilation cached for reuse
|
|
9
|
+
- Timeout protection per pattern (enforced via regex module)
|
|
10
|
+
"""
|
|
11
|
+
import regex
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from regex import Pattern as RePattern
|
|
14
|
+
|
|
15
|
+
from raxe.domain.rules.models import Pattern
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class Match:
|
|
20
|
+
"""A single pattern match in text.
|
|
21
|
+
|
|
22
|
+
Immutable value object representing where and what matched.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
pattern_index: Which pattern in the rule matched (0-based)
|
|
26
|
+
start: Start position in text
|
|
27
|
+
end: End position in text
|
|
28
|
+
matched_text: The actual matched text
|
|
29
|
+
groups: Captured groups from regex
|
|
30
|
+
context_before: Up to 50 chars before match
|
|
31
|
+
context_after: Up to 50 chars after match
|
|
32
|
+
"""
|
|
33
|
+
pattern_index: int
|
|
34
|
+
start: int
|
|
35
|
+
end: int
|
|
36
|
+
matched_text: str
|
|
37
|
+
groups: tuple[str, ...]
|
|
38
|
+
context_before: str
|
|
39
|
+
context_after: str
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def match_length(self) -> int:
|
|
43
|
+
"""Length of matched text."""
|
|
44
|
+
return self.end - self.start
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def full_context(self) -> str:
|
|
48
|
+
"""Full context around match."""
|
|
49
|
+
return f"{self.context_before}[{self.matched_text}]{self.context_after}"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class PatternMatcher:
|
|
53
|
+
"""Stateless pattern matching with timeout support.
|
|
54
|
+
|
|
55
|
+
Pure domain logic - no I/O, no side effects.
|
|
56
|
+
Caches compiled patterns for performance.
|
|
57
|
+
|
|
58
|
+
Thread-safe for read operations (cache is write-once per pattern).
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(self) -> None:
|
|
62
|
+
"""Initialize matcher with empty pattern cache."""
|
|
63
|
+
self._compiled_cache: dict[str, RePattern[str]] = {}
|
|
64
|
+
|
|
65
|
+
def compile_pattern(self, pattern: Pattern) -> RePattern[str]:
|
|
66
|
+
"""Compile regex pattern with flags.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
pattern: Pattern object from rule
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Compiled regex pattern
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
ValueError: If pattern is invalid or flags are unknown
|
|
76
|
+
|
|
77
|
+
Note:
|
|
78
|
+
Caches compiled patterns for performance.
|
|
79
|
+
Cache key includes pattern string and flags.
|
|
80
|
+
"""
|
|
81
|
+
# Create cache key from pattern and flags
|
|
82
|
+
cache_key = f"{pattern.pattern}:{':'.join(sorted(pattern.flags))}"
|
|
83
|
+
|
|
84
|
+
if cache_key in self._compiled_cache:
|
|
85
|
+
return self._compiled_cache[cache_key]
|
|
86
|
+
|
|
87
|
+
# Convert string flags to regex module flags
|
|
88
|
+
flags = 0
|
|
89
|
+
for flag in pattern.flags:
|
|
90
|
+
flag_upper = flag.upper()
|
|
91
|
+
if flag_upper == "IGNORECASE":
|
|
92
|
+
flags |= regex.IGNORECASE
|
|
93
|
+
elif flag_upper == "MULTILINE":
|
|
94
|
+
flags |= regex.MULTILINE
|
|
95
|
+
elif flag_upper == "DOTALL":
|
|
96
|
+
flags |= regex.DOTALL
|
|
97
|
+
elif flag_upper == "VERBOSE":
|
|
98
|
+
flags |= regex.VERBOSE
|
|
99
|
+
elif flag_upper == "ASCII":
|
|
100
|
+
flags |= regex.ASCII
|
|
101
|
+
else:
|
|
102
|
+
raise ValueError(f"Unknown regex flag: {flag}")
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
compiled = regex.compile(pattern.pattern, flags)
|
|
106
|
+
except regex.error as e:
|
|
107
|
+
raise ValueError(f"Invalid regex pattern '{pattern.pattern}': {e}") from e
|
|
108
|
+
|
|
109
|
+
# Cache for future use
|
|
110
|
+
self._compiled_cache[cache_key] = compiled
|
|
111
|
+
return compiled
|
|
112
|
+
|
|
113
|
+
def match_pattern(
|
|
114
|
+
self,
|
|
115
|
+
text: str,
|
|
116
|
+
pattern: Pattern,
|
|
117
|
+
pattern_index: int = 0,
|
|
118
|
+
timeout_seconds: float | None = None,
|
|
119
|
+
) -> list[Match]:
|
|
120
|
+
"""Match a single pattern against text with timeout.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
text: Text to search
|
|
124
|
+
pattern: Pattern to match
|
|
125
|
+
pattern_index: Index of this pattern in rule (for Match objects)
|
|
126
|
+
timeout_seconds: Override pattern timeout (default: pattern.timeout or 5.0s)
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
List of Match objects (empty if no matches)
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
ValueError: If pattern compilation fails or matching times out
|
|
133
|
+
"""
|
|
134
|
+
# Use provided timeout, pattern timeout, or default of 5.0 seconds
|
|
135
|
+
timeout = timeout_seconds if timeout_seconds is not None else (pattern.timeout or 5.0)
|
|
136
|
+
compiled = self.compile_pattern(pattern)
|
|
137
|
+
|
|
138
|
+
matches: list[Match] = []
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
# regex module provides native timeout support via timeout parameter
|
|
142
|
+
for match_obj in compiled.finditer(text, timeout=timeout):
|
|
143
|
+
start = match_obj.start()
|
|
144
|
+
end = match_obj.end()
|
|
145
|
+
|
|
146
|
+
# Extract context (50 chars before and after)
|
|
147
|
+
context_before = text[max(0, start - 50):start]
|
|
148
|
+
context_after = text[end:min(len(text), end + 50)]
|
|
149
|
+
|
|
150
|
+
matches.append(Match(
|
|
151
|
+
pattern_index=pattern_index,
|
|
152
|
+
start=start,
|
|
153
|
+
end=end,
|
|
154
|
+
matched_text=text[start:end],
|
|
155
|
+
groups=match_obj.groups(),
|
|
156
|
+
context_before=context_before,
|
|
157
|
+
context_after=context_after,
|
|
158
|
+
))
|
|
159
|
+
except TimeoutError as e:
|
|
160
|
+
raise ValueError(
|
|
161
|
+
f"Pattern matching timed out after {timeout}s (possible ReDoS): {e}"
|
|
162
|
+
) from e
|
|
163
|
+
except regex.error as e:
|
|
164
|
+
raise ValueError(f"Pattern matching failed: {e}") from e
|
|
165
|
+
|
|
166
|
+
return matches
|
|
167
|
+
|
|
168
|
+
def match_all_patterns(
|
|
169
|
+
self,
|
|
170
|
+
text: str,
|
|
171
|
+
patterns: list[Pattern],
|
|
172
|
+
) -> list[Match]:
|
|
173
|
+
"""Match all patterns from a rule against text.
|
|
174
|
+
|
|
175
|
+
This implements OR logic: any pattern matching means the rule matches.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
text: Text to search
|
|
179
|
+
patterns: List of patterns to match
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
All matches from all patterns (may be empty)
|
|
183
|
+
|
|
184
|
+
Note:
|
|
185
|
+
Continues matching even if a pattern fails, logging failures
|
|
186
|
+
for later analysis (though we can't log in pure domain - caller handles).
|
|
187
|
+
"""
|
|
188
|
+
all_matches: list[Match] = []
|
|
189
|
+
|
|
190
|
+
for idx, pattern in enumerate(patterns):
|
|
191
|
+
try:
|
|
192
|
+
matches = self.match_pattern(text, pattern, pattern_index=idx)
|
|
193
|
+
all_matches.extend(matches)
|
|
194
|
+
except ValueError:
|
|
195
|
+
# Pattern failed - skip it and continue with others
|
|
196
|
+
# Caller should log this for debugging
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
return all_matches
|
|
200
|
+
|
|
201
|
+
def clear_cache(self) -> None:
|
|
202
|
+
"""Clear compiled pattern cache.
|
|
203
|
+
|
|
204
|
+
Useful for testing or when patterns change.
|
|
205
|
+
Not typically needed in production.
|
|
206
|
+
"""
|
|
207
|
+
self._compiled_cache.clear()
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def cache_size(self) -> int:
|
|
211
|
+
"""Number of compiled patterns in cache."""
|
|
212
|
+
return len(self._compiled_cache)
|