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,831 @@
|
|
|
1
|
+
"""Portkey AI Gateway Integration.
|
|
2
|
+
|
|
3
|
+
This module provides RAXE integration with Portkey AI Gateway for:
|
|
4
|
+
1. Webhook-based guardrails (RAXE as a Portkey custom guardrail)
|
|
5
|
+
2. Client-side scanning (wrapping Portkey SDK calls)
|
|
6
|
+
|
|
7
|
+
Portkey is an AI gateway that routes requests to 200+ LLMs with built-in
|
|
8
|
+
guardrails, caching, and observability. RAXE can integrate as:
|
|
9
|
+
|
|
10
|
+
- **Webhook Guardrail**: Portkey calls RAXE endpoint for input/output scanning
|
|
11
|
+
- **Client Wrapper**: RAXE scans locally before/after Portkey calls
|
|
12
|
+
|
|
13
|
+
Default behavior is LOG-ONLY (safe to add to production without breaking flows).
|
|
14
|
+
Enable blocking with `block_on_threats=True` for strict mode.
|
|
15
|
+
|
|
16
|
+
Usage (Webhook):
|
|
17
|
+
from raxe.sdk.integrations.portkey import RaxePortkeyWebhook
|
|
18
|
+
|
|
19
|
+
# Create webhook handler
|
|
20
|
+
webhook = RaxePortkeyWebhook()
|
|
21
|
+
|
|
22
|
+
# FastAPI integration
|
|
23
|
+
@app.post("/raxe/guardrail")
|
|
24
|
+
async def guardrail(request: Request):
|
|
25
|
+
data = await request.json()
|
|
26
|
+
return webhook.handle_request(data)
|
|
27
|
+
|
|
28
|
+
Usage (Client Wrapper):
|
|
29
|
+
from portkey_ai import Portkey
|
|
30
|
+
from raxe.sdk.integrations.portkey import RaxePortkeyGuard
|
|
31
|
+
|
|
32
|
+
# Create guard
|
|
33
|
+
guard = RaxePortkeyGuard(block_on_threats=True)
|
|
34
|
+
|
|
35
|
+
# Wrap Portkey client
|
|
36
|
+
client = guard.wrap_client(Portkey(api_key="..."))
|
|
37
|
+
|
|
38
|
+
# Calls are automatically scanned
|
|
39
|
+
response = client.chat.completions.create(
|
|
40
|
+
messages=[{"role": "user", "content": "Hello"}],
|
|
41
|
+
model="gpt-4"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
For Portkey configuration, add RAXE as a webhook guardrail:
|
|
45
|
+
{
|
|
46
|
+
"beforeRequestHooks": [{
|
|
47
|
+
"id": "raxe-guardrail",
|
|
48
|
+
"type": "guardrail",
|
|
49
|
+
"checks": [{
|
|
50
|
+
"id": "default.webhook",
|
|
51
|
+
"parameters": {
|
|
52
|
+
"webhookURL": "https://your-endpoint/raxe/guardrail",
|
|
53
|
+
"headers": {"Authorization": "Bearer YOUR_KEY"}
|
|
54
|
+
}
|
|
55
|
+
}],
|
|
56
|
+
"deny": true
|
|
57
|
+
}]
|
|
58
|
+
}
|
|
59
|
+
"""
|
|
60
|
+
from __future__ import annotations
|
|
61
|
+
|
|
62
|
+
import logging
|
|
63
|
+
import time
|
|
64
|
+
from dataclasses import dataclass, field
|
|
65
|
+
from typing import TYPE_CHECKING, Any, Callable, TypeVar
|
|
66
|
+
|
|
67
|
+
from raxe.sdk.agent_scanner import (
|
|
68
|
+
AgentScannerConfig,
|
|
69
|
+
ThreatDetectedError,
|
|
70
|
+
create_agent_scanner,
|
|
71
|
+
)
|
|
72
|
+
from raxe.sdk.exceptions import SecurityException
|
|
73
|
+
|
|
74
|
+
if TYPE_CHECKING:
|
|
75
|
+
from raxe.sdk.client import Raxe
|
|
76
|
+
|
|
77
|
+
logger = logging.getLogger(__name__)
|
|
78
|
+
|
|
79
|
+
T = TypeVar("T")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# =============================================================================
|
|
83
|
+
# Configuration
|
|
84
|
+
# =============================================================================
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass
|
|
88
|
+
class PortkeyGuardConfig:
|
|
89
|
+
"""Configuration for Portkey guardrail integration.
|
|
90
|
+
|
|
91
|
+
Attributes:
|
|
92
|
+
block_on_threats: Whether to block (return false verdict) on threats.
|
|
93
|
+
Default is False (log-only mode, always returns true verdict).
|
|
94
|
+
block_severity_threshold: Minimum severity to trigger blocking.
|
|
95
|
+
Options: "LOW", "MEDIUM", "HIGH", "CRITICAL"
|
|
96
|
+
scan_inputs: Scan input messages (beforeRequest)
|
|
97
|
+
scan_outputs: Scan output responses (afterRequest)
|
|
98
|
+
include_scan_details: Include detailed scan info in response data
|
|
99
|
+
fail_open: Return true verdict on errors (Portkey default behavior)
|
|
100
|
+
|
|
101
|
+
Example:
|
|
102
|
+
# Log-only mode (default)
|
|
103
|
+
config = PortkeyGuardConfig()
|
|
104
|
+
|
|
105
|
+
# Blocking mode
|
|
106
|
+
config = PortkeyGuardConfig(
|
|
107
|
+
block_on_threats=True,
|
|
108
|
+
block_severity_threshold="HIGH",
|
|
109
|
+
)
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
block_on_threats: bool = False
|
|
113
|
+
block_severity_threshold: str = "HIGH"
|
|
114
|
+
scan_inputs: bool = True
|
|
115
|
+
scan_outputs: bool = True
|
|
116
|
+
include_scan_details: bool = True
|
|
117
|
+
fail_open: bool = True # Match Portkey's timeout behavior
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# =============================================================================
|
|
121
|
+
# Webhook Handler
|
|
122
|
+
# =============================================================================
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class RaxePortkeyWebhook:
|
|
126
|
+
"""Webhook handler for Portkey guardrail integration.
|
|
127
|
+
|
|
128
|
+
Handles incoming guardrail requests from Portkey and returns
|
|
129
|
+
verdicts in Portkey's expected format.
|
|
130
|
+
|
|
131
|
+
Portkey sends requests with:
|
|
132
|
+
- eventType: "beforeRequest" or "afterRequest"
|
|
133
|
+
- request: The LLM request (for beforeRequest)
|
|
134
|
+
- response: The LLM response (for afterRequest)
|
|
135
|
+
- metadata: Optional metadata from x-portkey-metadata header
|
|
136
|
+
|
|
137
|
+
RAXE returns:
|
|
138
|
+
- verdict: true (pass) or false (fail/block)
|
|
139
|
+
- data: Scan details including reason, severity, detections
|
|
140
|
+
|
|
141
|
+
Attributes:
|
|
142
|
+
raxe: Raxe client for scanning
|
|
143
|
+
config: Guardrail configuration
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
webhook = RaxePortkeyWebhook()
|
|
147
|
+
|
|
148
|
+
# Handle incoming request
|
|
149
|
+
result = webhook.handle_request({
|
|
150
|
+
"request": {"messages": [...]},
|
|
151
|
+
"eventType": "beforeRequest"
|
|
152
|
+
})
|
|
153
|
+
# Returns: {"verdict": true, "data": {...}}
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
def __init__(
|
|
157
|
+
self,
|
|
158
|
+
raxe: "Raxe | None" = None,
|
|
159
|
+
config: PortkeyGuardConfig | None = None,
|
|
160
|
+
) -> None:
|
|
161
|
+
"""Initialize webhook handler.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
raxe: Raxe client for scanning. Created if not provided.
|
|
165
|
+
config: Guardrail configuration. Uses defaults if not provided.
|
|
166
|
+
"""
|
|
167
|
+
if raxe is None:
|
|
168
|
+
from raxe.sdk.client import Raxe
|
|
169
|
+
|
|
170
|
+
raxe = Raxe()
|
|
171
|
+
|
|
172
|
+
self.raxe = raxe
|
|
173
|
+
self.config = config or PortkeyGuardConfig()
|
|
174
|
+
|
|
175
|
+
# Statistics
|
|
176
|
+
self._stats = {
|
|
177
|
+
"total_requests": 0,
|
|
178
|
+
"before_requests": 0,
|
|
179
|
+
"after_requests": 0,
|
|
180
|
+
"threats_detected": 0,
|
|
181
|
+
"verdicts_false": 0,
|
|
182
|
+
"errors": 0,
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
def handle_request(self, data: dict[str, Any]) -> dict[str, Any]:
|
|
186
|
+
"""Handle incoming Portkey guardrail request.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
data: Request data from Portkey containing:
|
|
190
|
+
- eventType: "beforeRequest" or "afterRequest"
|
|
191
|
+
- request: LLM request (for beforeRequest)
|
|
192
|
+
- response: LLM response (for afterRequest)
|
|
193
|
+
- metadata: Optional metadata
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Portkey-compatible verdict response:
|
|
197
|
+
{
|
|
198
|
+
"verdict": true/false,
|
|
199
|
+
"data": {
|
|
200
|
+
"reason": "...",
|
|
201
|
+
"severity": "...",
|
|
202
|
+
"detections": 0,
|
|
203
|
+
"rule_ids": [...],
|
|
204
|
+
"scan_duration_ms": 5.2
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
"""
|
|
208
|
+
self._stats["total_requests"] += 1
|
|
209
|
+
start_time = time.time()
|
|
210
|
+
|
|
211
|
+
try:
|
|
212
|
+
event_type = data.get("eventType", "beforeRequest")
|
|
213
|
+
|
|
214
|
+
if event_type == "beforeRequest":
|
|
215
|
+
self._stats["before_requests"] += 1
|
|
216
|
+
return self._handle_before_request(data, start_time)
|
|
217
|
+
elif event_type == "afterRequest":
|
|
218
|
+
self._stats["after_requests"] += 1
|
|
219
|
+
return self._handle_after_request(data, start_time)
|
|
220
|
+
else:
|
|
221
|
+
# Unknown event type, pass through
|
|
222
|
+
return self._make_pass_verdict(
|
|
223
|
+
reason=f"Unknown event type: {event_type}",
|
|
224
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
except Exception as e:
|
|
228
|
+
self._stats["errors"] += 1
|
|
229
|
+
logger.warning(f"Portkey guardrail error: {e}")
|
|
230
|
+
|
|
231
|
+
# Fail-open: return pass verdict on error
|
|
232
|
+
if self.config.fail_open:
|
|
233
|
+
return self._make_pass_verdict(
|
|
234
|
+
reason="Scan error (fail-open)",
|
|
235
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
236
|
+
error=str(e),
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
return self._make_fail_verdict(
|
|
240
|
+
reason=f"Scan error: {e}",
|
|
241
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
async def handle_request_async(self, data: dict[str, Any]) -> dict[str, Any]:
|
|
245
|
+
"""Async version of handle_request.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
data: Request data from Portkey
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Portkey-compatible verdict response
|
|
252
|
+
"""
|
|
253
|
+
# For now, delegate to sync version
|
|
254
|
+
# Future: implement true async scanning
|
|
255
|
+
return self.handle_request(data)
|
|
256
|
+
|
|
257
|
+
def _handle_before_request(
|
|
258
|
+
self,
|
|
259
|
+
data: dict[str, Any],
|
|
260
|
+
start_time: float,
|
|
261
|
+
) -> dict[str, Any]:
|
|
262
|
+
"""Handle beforeRequest event (input scanning).
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
data: Request data
|
|
266
|
+
start_time: Request start timestamp
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
Verdict response
|
|
270
|
+
"""
|
|
271
|
+
if not self.config.scan_inputs:
|
|
272
|
+
return self._make_pass_verdict(
|
|
273
|
+
reason="Input scanning disabled",
|
|
274
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
request = data.get("request", {})
|
|
278
|
+
messages = request.get("messages", [])
|
|
279
|
+
|
|
280
|
+
if not messages:
|
|
281
|
+
return self._make_pass_verdict(
|
|
282
|
+
reason="No messages to scan",
|
|
283
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
# Extract text to scan
|
|
287
|
+
text_to_scan = self._extract_messages_text(messages)
|
|
288
|
+
|
|
289
|
+
if not text_to_scan.strip():
|
|
290
|
+
return self._make_pass_verdict(
|
|
291
|
+
reason="No text content to scan",
|
|
292
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Perform scan with integration telemetry
|
|
296
|
+
result = self.raxe.scan(text_to_scan, integration_type="portkey")
|
|
297
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
298
|
+
|
|
299
|
+
return self._result_to_verdict(result, duration_ms)
|
|
300
|
+
|
|
301
|
+
def _handle_after_request(
|
|
302
|
+
self,
|
|
303
|
+
data: dict[str, Any],
|
|
304
|
+
start_time: float,
|
|
305
|
+
) -> dict[str, Any]:
|
|
306
|
+
"""Handle afterRequest event (output scanning).
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
data: Response data
|
|
310
|
+
start_time: Request start timestamp
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
Verdict response
|
|
314
|
+
"""
|
|
315
|
+
if not self.config.scan_outputs:
|
|
316
|
+
return self._make_pass_verdict(
|
|
317
|
+
reason="Output scanning disabled",
|
|
318
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
response = data.get("response", {})
|
|
322
|
+
|
|
323
|
+
# Extract text from response
|
|
324
|
+
text_to_scan = self._extract_response_text(response)
|
|
325
|
+
|
|
326
|
+
if not text_to_scan.strip():
|
|
327
|
+
return self._make_pass_verdict(
|
|
328
|
+
reason="No response content to scan",
|
|
329
|
+
duration_ms=(time.time() - start_time) * 1000,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
# Perform scan with integration telemetry
|
|
333
|
+
result = self.raxe.scan(text_to_scan, integration_type="portkey")
|
|
334
|
+
duration_ms = (time.time() - start_time) * 1000
|
|
335
|
+
|
|
336
|
+
return self._result_to_verdict(result, duration_ms)
|
|
337
|
+
|
|
338
|
+
def _extract_messages_text(self, messages: list[dict[str, Any]]) -> str:
|
|
339
|
+
"""Extract scannable text from messages.
|
|
340
|
+
|
|
341
|
+
Focuses on user messages as primary scan targets.
|
|
342
|
+
|
|
343
|
+
Args:
|
|
344
|
+
messages: List of chat messages
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
Combined text for scanning
|
|
348
|
+
"""
|
|
349
|
+
texts = []
|
|
350
|
+
|
|
351
|
+
for msg in messages:
|
|
352
|
+
role = msg.get("role", "")
|
|
353
|
+
content = msg.get("content", "")
|
|
354
|
+
|
|
355
|
+
# Scan user messages primarily
|
|
356
|
+
if role == "user" and content:
|
|
357
|
+
if isinstance(content, str):
|
|
358
|
+
texts.append(content)
|
|
359
|
+
elif isinstance(content, list):
|
|
360
|
+
# Multi-modal content
|
|
361
|
+
for part in content:
|
|
362
|
+
if isinstance(part, dict) and part.get("type") == "text":
|
|
363
|
+
texts.append(part.get("text", ""))
|
|
364
|
+
elif isinstance(part, str):
|
|
365
|
+
texts.append(part)
|
|
366
|
+
|
|
367
|
+
return "\n".join(texts)
|
|
368
|
+
|
|
369
|
+
def _extract_response_text(self, response: dict[str, Any]) -> str:
|
|
370
|
+
"""Extract scannable text from LLM response.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
response: LLM response object
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
Combined response text for scanning
|
|
377
|
+
"""
|
|
378
|
+
texts = []
|
|
379
|
+
|
|
380
|
+
choices = response.get("choices", [])
|
|
381
|
+
for choice in choices:
|
|
382
|
+
message = choice.get("message", {})
|
|
383
|
+
content = message.get("content", "")
|
|
384
|
+
|
|
385
|
+
if content:
|
|
386
|
+
texts.append(content)
|
|
387
|
+
|
|
388
|
+
return "\n".join(texts)
|
|
389
|
+
|
|
390
|
+
def _result_to_verdict(
|
|
391
|
+
self,
|
|
392
|
+
result: Any,
|
|
393
|
+
duration_ms: float,
|
|
394
|
+
) -> dict[str, Any]:
|
|
395
|
+
"""Convert scan result to Portkey verdict format.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
result: RAXE scan result
|
|
399
|
+
duration_ms: Scan duration in milliseconds
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
Portkey verdict response
|
|
403
|
+
"""
|
|
404
|
+
if result.has_threats:
|
|
405
|
+
self._stats["threats_detected"] += 1
|
|
406
|
+
|
|
407
|
+
# Determine if we should block based on severity
|
|
408
|
+
should_block = self.config.block_on_threats and self._should_block(result)
|
|
409
|
+
|
|
410
|
+
if should_block:
|
|
411
|
+
self._stats["verdicts_false"] += 1
|
|
412
|
+
return self._make_fail_verdict(
|
|
413
|
+
reason="Threat detected",
|
|
414
|
+
severity=result.severity,
|
|
415
|
+
detections=result.total_detections,
|
|
416
|
+
rule_ids=[d.rule_id for d in result.detections],
|
|
417
|
+
duration_ms=duration_ms,
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
# Pass verdict
|
|
421
|
+
return self._make_pass_verdict(
|
|
422
|
+
reason="No threats detected" if not result.has_threats else "Threat logged (non-blocking)",
|
|
423
|
+
severity=result.severity if result.has_threats else None,
|
|
424
|
+
detections=result.total_detections,
|
|
425
|
+
duration_ms=duration_ms,
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
def _should_block(self, result: Any) -> bool:
|
|
429
|
+
"""Check if result severity meets blocking threshold.
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
result: Scan result with severity
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
True if should block
|
|
436
|
+
"""
|
|
437
|
+
severity_order = ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
|
|
438
|
+
threshold = self.config.block_severity_threshold
|
|
439
|
+
|
|
440
|
+
if not result.severity:
|
|
441
|
+
return False
|
|
442
|
+
|
|
443
|
+
try:
|
|
444
|
+
result_idx = severity_order.index(result.severity.upper())
|
|
445
|
+
threshold_idx = severity_order.index(threshold.upper())
|
|
446
|
+
return result_idx >= threshold_idx
|
|
447
|
+
except ValueError:
|
|
448
|
+
return False
|
|
449
|
+
|
|
450
|
+
def _make_pass_verdict(
|
|
451
|
+
self,
|
|
452
|
+
reason: str,
|
|
453
|
+
duration_ms: float,
|
|
454
|
+
severity: str | None = None,
|
|
455
|
+
detections: int = 0,
|
|
456
|
+
error: str | None = None,
|
|
457
|
+
) -> dict[str, Any]:
|
|
458
|
+
"""Create a pass (true) verdict response.
|
|
459
|
+
|
|
460
|
+
Args:
|
|
461
|
+
reason: Reason for the verdict
|
|
462
|
+
duration_ms: Scan duration
|
|
463
|
+
severity: Detected severity (if any)
|
|
464
|
+
detections: Number of detections
|
|
465
|
+
error: Error message (if any)
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
Portkey verdict with verdict=true
|
|
469
|
+
"""
|
|
470
|
+
data: dict[str, Any] = {
|
|
471
|
+
"reason": reason,
|
|
472
|
+
"detections": detections,
|
|
473
|
+
"scan_duration_ms": round(duration_ms, 2),
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if severity:
|
|
477
|
+
data["severity"] = severity
|
|
478
|
+
|
|
479
|
+
if error:
|
|
480
|
+
data["error"] = error
|
|
481
|
+
|
|
482
|
+
return {"verdict": True, "data": data}
|
|
483
|
+
|
|
484
|
+
def _make_fail_verdict(
|
|
485
|
+
self,
|
|
486
|
+
reason: str,
|
|
487
|
+
duration_ms: float,
|
|
488
|
+
severity: str | None = None,
|
|
489
|
+
detections: int = 0,
|
|
490
|
+
rule_ids: list[str] | None = None,
|
|
491
|
+
) -> dict[str, Any]:
|
|
492
|
+
"""Create a fail (false) verdict response.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
reason: Reason for the verdict
|
|
496
|
+
duration_ms: Scan duration
|
|
497
|
+
severity: Detected severity
|
|
498
|
+
detections: Number of detections
|
|
499
|
+
rule_ids: List of triggered rule IDs
|
|
500
|
+
|
|
501
|
+
Returns:
|
|
502
|
+
Portkey verdict with verdict=false
|
|
503
|
+
"""
|
|
504
|
+
data: dict[str, Any] = {
|
|
505
|
+
"reason": reason,
|
|
506
|
+
"detections": detections,
|
|
507
|
+
"scan_duration_ms": round(duration_ms, 2),
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if severity:
|
|
511
|
+
data["severity"] = severity
|
|
512
|
+
|
|
513
|
+
if rule_ids:
|
|
514
|
+
data["rule_ids"] = rule_ids
|
|
515
|
+
|
|
516
|
+
return {"verdict": False, "data": data}
|
|
517
|
+
|
|
518
|
+
@property
|
|
519
|
+
def stats(self) -> dict[str, int]:
|
|
520
|
+
"""Get webhook statistics."""
|
|
521
|
+
return self._stats.copy()
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
# =============================================================================
|
|
525
|
+
# Client Guard
|
|
526
|
+
# =============================================================================
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
class RaxePortkeyGuard:
|
|
530
|
+
"""Client-side guard for Portkey SDK.
|
|
531
|
+
|
|
532
|
+
Wraps Portkey client to scan inputs before sending and
|
|
533
|
+
optionally scan outputs after receiving.
|
|
534
|
+
|
|
535
|
+
Attributes:
|
|
536
|
+
raxe: Raxe client for scanning
|
|
537
|
+
config: Guard configuration
|
|
538
|
+
|
|
539
|
+
Example:
|
|
540
|
+
from portkey_ai import Portkey
|
|
541
|
+
from raxe.sdk.integrations.portkey import RaxePortkeyGuard
|
|
542
|
+
|
|
543
|
+
guard = RaxePortkeyGuard(block_on_threats=True)
|
|
544
|
+
client = guard.wrap_client(Portkey(api_key="..."))
|
|
545
|
+
|
|
546
|
+
# All calls are now scanned
|
|
547
|
+
response = client.chat.completions.create(
|
|
548
|
+
messages=[{"role": "user", "content": "Hello"}],
|
|
549
|
+
model="gpt-4"
|
|
550
|
+
)
|
|
551
|
+
"""
|
|
552
|
+
|
|
553
|
+
def __init__(
|
|
554
|
+
self,
|
|
555
|
+
raxe: "Raxe | None" = None,
|
|
556
|
+
config: PortkeyGuardConfig | None = None,
|
|
557
|
+
*,
|
|
558
|
+
block_on_threats: bool | None = None,
|
|
559
|
+
block_severity_threshold: str | None = None,
|
|
560
|
+
) -> None:
|
|
561
|
+
"""Initialize client guard.
|
|
562
|
+
|
|
563
|
+
Args:
|
|
564
|
+
raxe: Raxe client for scanning. Created if not provided.
|
|
565
|
+
config: Guard configuration. Uses defaults if not provided.
|
|
566
|
+
block_on_threats: Override config block_on_threats
|
|
567
|
+
block_severity_threshold: Override config threshold
|
|
568
|
+
"""
|
|
569
|
+
if raxe is None:
|
|
570
|
+
from raxe.sdk.client import Raxe
|
|
571
|
+
|
|
572
|
+
raxe = Raxe()
|
|
573
|
+
|
|
574
|
+
self.raxe = raxe
|
|
575
|
+
|
|
576
|
+
# Build config
|
|
577
|
+
if config is None:
|
|
578
|
+
config = PortkeyGuardConfig()
|
|
579
|
+
|
|
580
|
+
if block_on_threats is not None:
|
|
581
|
+
config = PortkeyGuardConfig(
|
|
582
|
+
block_on_threats=block_on_threats,
|
|
583
|
+
block_severity_threshold=config.block_severity_threshold,
|
|
584
|
+
scan_inputs=config.scan_inputs,
|
|
585
|
+
scan_outputs=config.scan_outputs,
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
if block_severity_threshold is not None:
|
|
589
|
+
config = PortkeyGuardConfig(
|
|
590
|
+
block_on_threats=config.block_on_threats,
|
|
591
|
+
block_severity_threshold=block_severity_threshold,
|
|
592
|
+
scan_inputs=config.scan_inputs,
|
|
593
|
+
scan_outputs=config.scan_outputs,
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
self.config = config
|
|
597
|
+
|
|
598
|
+
# Create AgentScanner for unified scanning with integration telemetry
|
|
599
|
+
# Always use log mode - Portkey handles blocking with severity threshold
|
|
600
|
+
scanner_config = AgentScannerConfig(
|
|
601
|
+
scan_prompts=config.scan_inputs,
|
|
602
|
+
scan_responses=config.scan_outputs,
|
|
603
|
+
on_threat="log", # Portkey controls blocking via severity threshold
|
|
604
|
+
)
|
|
605
|
+
self._scanner = create_agent_scanner(raxe, scanner_config, integration_type="portkey")
|
|
606
|
+
|
|
607
|
+
# Statistics
|
|
608
|
+
self._stats = {
|
|
609
|
+
"total_scans": 0,
|
|
610
|
+
"threats_detected": 0,
|
|
611
|
+
"threats_blocked": 0,
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
def wrap_client(self, client: T) -> T:
|
|
615
|
+
"""Wrap a Portkey client with RAXE scanning.
|
|
616
|
+
|
|
617
|
+
Args:
|
|
618
|
+
client: Portkey client instance
|
|
619
|
+
|
|
620
|
+
Returns:
|
|
621
|
+
Wrapped client with scanning enabled
|
|
622
|
+
"""
|
|
623
|
+
return _PortkeyClientWrapper(client, self) # type: ignore
|
|
624
|
+
|
|
625
|
+
def scan_and_call(
|
|
626
|
+
self,
|
|
627
|
+
fn: Callable[..., T],
|
|
628
|
+
*,
|
|
629
|
+
messages: list[dict[str, Any]] | None = None,
|
|
630
|
+
**kwargs: Any,
|
|
631
|
+
) -> T:
|
|
632
|
+
"""Scan input and call function if safe.
|
|
633
|
+
|
|
634
|
+
Args:
|
|
635
|
+
fn: Function to call (e.g., client.chat.completions.create)
|
|
636
|
+
messages: Messages to scan
|
|
637
|
+
**kwargs: Additional arguments to pass to fn
|
|
638
|
+
|
|
639
|
+
Returns:
|
|
640
|
+
Result from fn
|
|
641
|
+
|
|
642
|
+
Raises:
|
|
643
|
+
ThreatDetectedError: If threat detected and blocking enabled
|
|
644
|
+
"""
|
|
645
|
+
self._stats["total_scans"] += 1
|
|
646
|
+
|
|
647
|
+
if messages and self.config.scan_inputs:
|
|
648
|
+
# Extract and scan text
|
|
649
|
+
text_to_scan = self._extract_messages_text(messages)
|
|
650
|
+
|
|
651
|
+
if text_to_scan.strip():
|
|
652
|
+
# Use AgentScanner for unified scanning with integration telemetry
|
|
653
|
+
result = self._scanner.scan_prompt(text_to_scan)
|
|
654
|
+
|
|
655
|
+
if result.has_threats:
|
|
656
|
+
self._stats["threats_detected"] += 1
|
|
657
|
+
logger.warning(
|
|
658
|
+
f"Threat detected in Portkey request: {result.severity} "
|
|
659
|
+
f"(rules={result.rule_ids})"
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
# Check severity threshold for blocking
|
|
663
|
+
if self.config.block_on_threats and self._severity_meets_threshold(result.severity):
|
|
664
|
+
self._stats["threats_blocked"] += 1
|
|
665
|
+
raise ThreatDetectedError(result)
|
|
666
|
+
|
|
667
|
+
# Call the function
|
|
668
|
+
return fn(messages=messages, **kwargs)
|
|
669
|
+
|
|
670
|
+
def _extract_messages_text(self, messages: list[dict[str, Any]]) -> str:
|
|
671
|
+
"""Extract scannable text from messages."""
|
|
672
|
+
texts = []
|
|
673
|
+
|
|
674
|
+
for msg in messages:
|
|
675
|
+
role = msg.get("role", "")
|
|
676
|
+
content = msg.get("content", "")
|
|
677
|
+
|
|
678
|
+
if role == "user" and content:
|
|
679
|
+
if isinstance(content, str):
|
|
680
|
+
texts.append(content)
|
|
681
|
+
elif isinstance(content, list):
|
|
682
|
+
for part in content:
|
|
683
|
+
if isinstance(part, dict) and part.get("type") == "text":
|
|
684
|
+
texts.append(part.get("text", ""))
|
|
685
|
+
|
|
686
|
+
return "\n".join(texts)
|
|
687
|
+
|
|
688
|
+
def _severity_meets_threshold(self, severity: str | None) -> bool:
|
|
689
|
+
"""Check if severity meets blocking threshold.
|
|
690
|
+
|
|
691
|
+
Args:
|
|
692
|
+
severity: Severity level (LOW, MEDIUM, HIGH, CRITICAL)
|
|
693
|
+
|
|
694
|
+
Returns:
|
|
695
|
+
True if severity meets or exceeds threshold
|
|
696
|
+
"""
|
|
697
|
+
severity_order = ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
|
|
698
|
+
threshold = self.config.block_severity_threshold
|
|
699
|
+
|
|
700
|
+
if not severity:
|
|
701
|
+
return False
|
|
702
|
+
|
|
703
|
+
try:
|
|
704
|
+
result_idx = severity_order.index(severity.upper())
|
|
705
|
+
threshold_idx = severity_order.index(threshold.upper())
|
|
706
|
+
return result_idx >= threshold_idx
|
|
707
|
+
except ValueError:
|
|
708
|
+
return False
|
|
709
|
+
|
|
710
|
+
def _should_block(self, result: Any) -> bool:
|
|
711
|
+
"""Check if result severity meets blocking threshold.
|
|
712
|
+
|
|
713
|
+
Args:
|
|
714
|
+
result: Scan result with severity attribute
|
|
715
|
+
|
|
716
|
+
Returns:
|
|
717
|
+
True if should block
|
|
718
|
+
"""
|
|
719
|
+
return self._severity_meets_threshold(getattr(result, "severity", None))
|
|
720
|
+
|
|
721
|
+
@property
|
|
722
|
+
def stats(self) -> dict[str, int]:
|
|
723
|
+
"""Get guard statistics."""
|
|
724
|
+
return self._stats.copy()
|
|
725
|
+
|
|
726
|
+
def reset_stats(self) -> None:
|
|
727
|
+
"""Reset statistics."""
|
|
728
|
+
self._stats = {
|
|
729
|
+
"total_scans": 0,
|
|
730
|
+
"threats_detected": 0,
|
|
731
|
+
"threats_blocked": 0,
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
class _PortkeyClientWrapper:
|
|
736
|
+
"""Internal wrapper for Portkey client.
|
|
737
|
+
|
|
738
|
+
Intercepts chat.completions.create calls for scanning.
|
|
739
|
+
"""
|
|
740
|
+
|
|
741
|
+
def __init__(self, client: Any, guard: RaxePortkeyGuard) -> None:
|
|
742
|
+
self._client = client
|
|
743
|
+
self._guard = guard
|
|
744
|
+
self.chat = _ChatWrapper(client.chat, guard)
|
|
745
|
+
|
|
746
|
+
def __getattr__(self, name: str) -> Any:
|
|
747
|
+
return getattr(self._client, name)
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
class _ChatWrapper:
|
|
751
|
+
"""Wrapper for chat namespace."""
|
|
752
|
+
|
|
753
|
+
def __init__(self, chat: Any, guard: RaxePortkeyGuard) -> None:
|
|
754
|
+
self._chat = chat
|
|
755
|
+
self._guard = guard
|
|
756
|
+
self.completions = _CompletionsWrapper(chat.completions, guard)
|
|
757
|
+
|
|
758
|
+
def __getattr__(self, name: str) -> Any:
|
|
759
|
+
return getattr(self._chat, name)
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
class _CompletionsWrapper:
|
|
763
|
+
"""Wrapper for completions namespace."""
|
|
764
|
+
|
|
765
|
+
def __init__(self, completions: Any, guard: RaxePortkeyGuard) -> None:
|
|
766
|
+
self._completions = completions
|
|
767
|
+
self._guard = guard
|
|
768
|
+
|
|
769
|
+
def create(self, **kwargs: Any) -> Any:
|
|
770
|
+
"""Create completion with RAXE scanning."""
|
|
771
|
+
messages = kwargs.get("messages")
|
|
772
|
+
|
|
773
|
+
return self._guard.scan_and_call(
|
|
774
|
+
self._completions.create,
|
|
775
|
+
messages=messages,
|
|
776
|
+
**{k: v for k, v in kwargs.items() if k != "messages"},
|
|
777
|
+
)
|
|
778
|
+
|
|
779
|
+
def __getattr__(self, name: str) -> Any:
|
|
780
|
+
return getattr(self._completions, name)
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
# =============================================================================
|
|
784
|
+
# Convenience Factory Functions
|
|
785
|
+
# =============================================================================
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
def create_portkey_guard(
|
|
789
|
+
raxe: "Raxe | None" = None,
|
|
790
|
+
*,
|
|
791
|
+
block_on_threats: bool = False,
|
|
792
|
+
block_severity_threshold: str = "HIGH",
|
|
793
|
+
) -> RaxePortkeyGuard:
|
|
794
|
+
"""Create a Portkey client guard.
|
|
795
|
+
|
|
796
|
+
Args:
|
|
797
|
+
raxe: Raxe client. Created if not provided.
|
|
798
|
+
block_on_threats: Whether to block on threat detection
|
|
799
|
+
block_severity_threshold: Minimum severity to trigger blocking
|
|
800
|
+
|
|
801
|
+
Returns:
|
|
802
|
+
Configured RaxePortkeyGuard
|
|
803
|
+
"""
|
|
804
|
+
config = PortkeyGuardConfig(
|
|
805
|
+
block_on_threats=block_on_threats,
|
|
806
|
+
block_severity_threshold=block_severity_threshold,
|
|
807
|
+
)
|
|
808
|
+
return RaxePortkeyGuard(raxe, config)
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
def create_portkey_webhook(
|
|
812
|
+
raxe: "Raxe | None" = None,
|
|
813
|
+
*,
|
|
814
|
+
block_on_threats: bool = False,
|
|
815
|
+
block_severity_threshold: str = "HIGH",
|
|
816
|
+
) -> RaxePortkeyWebhook:
|
|
817
|
+
"""Create a Portkey webhook handler.
|
|
818
|
+
|
|
819
|
+
Args:
|
|
820
|
+
raxe: Raxe client. Created if not provided.
|
|
821
|
+
block_on_threats: Whether to return false verdict on threats
|
|
822
|
+
block_severity_threshold: Minimum severity to trigger blocking
|
|
823
|
+
|
|
824
|
+
Returns:
|
|
825
|
+
Configured RaxePortkeyWebhook
|
|
826
|
+
"""
|
|
827
|
+
config = PortkeyGuardConfig(
|
|
828
|
+
block_on_threats=block_on_threats,
|
|
829
|
+
block_severity_threshold=block_severity_threshold,
|
|
830
|
+
)
|
|
831
|
+
return RaxePortkeyWebhook(raxe, config)
|