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,1049 @@
|
|
|
1
|
+
"""LlamaIndex integration for RAXE scanning.
|
|
2
|
+
|
|
3
|
+
Provides callback handlers and instrumentation for automatic RAXE scanning
|
|
4
|
+
in LlamaIndex applications. Supports both the legacy callback system and
|
|
5
|
+
the new instrumentation API (v0.10.20+).
|
|
6
|
+
|
|
7
|
+
This integration works with:
|
|
8
|
+
- Query engines (VectorStoreIndex, etc.)
|
|
9
|
+
- ReAct agents and function-calling agents
|
|
10
|
+
- Tool execution
|
|
11
|
+
- RAG pipelines (retrieval, synthesis)
|
|
12
|
+
- LLM calls and embeddings
|
|
13
|
+
|
|
14
|
+
Default behavior is LOG-ONLY (safe to add to production without breaking flows).
|
|
15
|
+
Enable blocking with `block_on_query_threats=True` for strict mode.
|
|
16
|
+
|
|
17
|
+
Usage (Callback Handler - v0.10+):
|
|
18
|
+
from llama_index.core import VectorStoreIndex, Settings
|
|
19
|
+
from llama_index.core.callbacks import CallbackManager
|
|
20
|
+
from raxe.sdk.integrations import RaxeLlamaIndexCallback
|
|
21
|
+
|
|
22
|
+
# Create callback handler
|
|
23
|
+
raxe_callback = RaxeLlamaIndexCallback()
|
|
24
|
+
|
|
25
|
+
# Add to callback manager
|
|
26
|
+
callback_manager = CallbackManager([raxe_callback])
|
|
27
|
+
Settings.callback_manager = callback_manager
|
|
28
|
+
|
|
29
|
+
# All queries automatically scanned
|
|
30
|
+
index = VectorStoreIndex.from_documents(documents)
|
|
31
|
+
response = index.as_query_engine().query("What is AI?")
|
|
32
|
+
|
|
33
|
+
Usage (Instrumentation - v0.10.20+):
|
|
34
|
+
from llama_index.core.instrumentation import get_dispatcher
|
|
35
|
+
from raxe.sdk.integrations import RaxeSpanHandler
|
|
36
|
+
|
|
37
|
+
# Create and register span handler
|
|
38
|
+
span_handler = RaxeSpanHandler()
|
|
39
|
+
root_dispatcher = get_dispatcher()
|
|
40
|
+
root_dispatcher.add_span_handler(span_handler)
|
|
41
|
+
|
|
42
|
+
# All operations automatically traced and scanned
|
|
43
|
+
response = index.as_query_engine().query("What is AI?")
|
|
44
|
+
"""
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
import logging
|
|
48
|
+
from typing import Any
|
|
49
|
+
|
|
50
|
+
from raxe.sdk.agent_scanner import (
|
|
51
|
+
AgentScannerConfig,
|
|
52
|
+
ThreatDetectedError,
|
|
53
|
+
create_agent_scanner,
|
|
54
|
+
)
|
|
55
|
+
from raxe.sdk.client import Raxe
|
|
56
|
+
from raxe.sdk.exceptions import SecurityException
|
|
57
|
+
from raxe.sdk.integrations.extractors import (
|
|
58
|
+
extract_text_from_message,
|
|
59
|
+
extract_text_from_response,
|
|
60
|
+
extract_texts_from_value,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
logger = logging.getLogger(__name__)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# CBEventType Enum Values (from llama_index.core.callbacks.schema)
|
|
68
|
+
# ============================================================================
|
|
69
|
+
# These are the event types we care about for security scanning:
|
|
70
|
+
#
|
|
71
|
+
# QUERY - Query start/end events
|
|
72
|
+
# LLM - LLM call events (prompts and responses)
|
|
73
|
+
# EMBEDDING - Embedding events
|
|
74
|
+
# RETRIEVE - Retrieval events (RAG context)
|
|
75
|
+
# SYNTHESIZE - Response synthesis events
|
|
76
|
+
# AGENT_STEP - Agent step events
|
|
77
|
+
# FUNCTION_CALL - Function/tool call events
|
|
78
|
+
# CHUNKING - Document chunking events
|
|
79
|
+
# TEMPLATING - Template processing events
|
|
80
|
+
# RERANKING - Reranking events
|
|
81
|
+
# ============================================================================
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _get_base_callback_handler():
|
|
85
|
+
"""Get BaseCallbackHandler class from llama_index."""
|
|
86
|
+
try:
|
|
87
|
+
from llama_index.core.callbacks.base import BaseCallbackHandler
|
|
88
|
+
return BaseCallbackHandler
|
|
89
|
+
except ImportError:
|
|
90
|
+
# Return object as fallback if llama_index not installed
|
|
91
|
+
return object
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# Dynamically inherit from BaseCallbackHandler
|
|
95
|
+
_LlamaIndexBaseHandler = _get_base_callback_handler()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class RaxeLlamaIndexCallback(_LlamaIndexBaseHandler):
|
|
99
|
+
"""LlamaIndex callback handler for automatic RAXE scanning.
|
|
100
|
+
|
|
101
|
+
This callback handler integrates with LlamaIndex's CallbackManager system
|
|
102
|
+
to automatically scan prompts, queries, and responses for security threats.
|
|
103
|
+
|
|
104
|
+
The handler intercepts events at key points in the LlamaIndex pipeline:
|
|
105
|
+
1. QUERY events - Scan user queries before processing
|
|
106
|
+
2. LLM events - Scan prompts before LLM calls
|
|
107
|
+
3. RETRIEVE events - Monitor retrieved context (future)
|
|
108
|
+
4. SYNTHESIZE events - Scan synthesized responses
|
|
109
|
+
5. Agent events - Scan agent actions and tool inputs
|
|
110
|
+
|
|
111
|
+
The handler supports both blocking and monitoring modes:
|
|
112
|
+
- Blocking mode: Raises SecurityException on threat detection
|
|
113
|
+
- Monitoring mode: Logs threats but allows execution
|
|
114
|
+
|
|
115
|
+
Attributes:
|
|
116
|
+
raxe: Raxe client instance for scanning
|
|
117
|
+
block_on_query_threats: Block if query contains threats
|
|
118
|
+
block_on_response_threats: Block if response contains threats
|
|
119
|
+
scan_retrieved_context: Scan retrieved RAG context (future)
|
|
120
|
+
scan_agent_actions: Scan agent tool inputs
|
|
121
|
+
|
|
122
|
+
Example:
|
|
123
|
+
>>> from llama_index.core import VectorStoreIndex, Settings
|
|
124
|
+
>>> from llama_index.core.callbacks import CallbackManager
|
|
125
|
+
>>> from raxe.sdk.integrations import RaxeLlamaIndexCallback
|
|
126
|
+
>>>
|
|
127
|
+
>>> # Blocking mode (default)
|
|
128
|
+
>>> raxe_callback = RaxeLlamaIndexCallback()
|
|
129
|
+
>>> Settings.callback_manager = CallbackManager([raxe_callback])
|
|
130
|
+
>>>
|
|
131
|
+
>>> # Monitoring mode
|
|
132
|
+
>>> raxe_callback = RaxeLlamaIndexCallback(block_on_query_threats=False)
|
|
133
|
+
>>>
|
|
134
|
+
>>> # Custom Raxe client
|
|
135
|
+
>>> raxe = Raxe(telemetry=False)
|
|
136
|
+
>>> raxe_callback = RaxeLlamaIndexCallback(raxe_client=raxe)
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
def __init__(
|
|
140
|
+
self,
|
|
141
|
+
raxe_client: Raxe | None = None,
|
|
142
|
+
*,
|
|
143
|
+
block_on_query_threats: bool = False,
|
|
144
|
+
block_on_response_threats: bool = False,
|
|
145
|
+
scan_retrieved_context: bool = False,
|
|
146
|
+
scan_agent_actions: bool = True,
|
|
147
|
+
) -> None:
|
|
148
|
+
"""Initialize RAXE callback handler for LlamaIndex.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
raxe_client: Optional Raxe instance (creates default if None)
|
|
152
|
+
block_on_query_threats: Block on query/prompt threats (default: False)
|
|
153
|
+
NOTE: Default is False (log-only mode) per requirements
|
|
154
|
+
block_on_response_threats: Block on response threats (default: False)
|
|
155
|
+
scan_retrieved_context: Scan retrieved RAG context (default: False)
|
|
156
|
+
NOTE: Placeholder for future RAG context validation
|
|
157
|
+
scan_agent_actions: Scan agent tool inputs (default: True)
|
|
158
|
+
|
|
159
|
+
Example:
|
|
160
|
+
# Log-only mode (default)
|
|
161
|
+
callback = RaxeLlamaIndexCallback()
|
|
162
|
+
|
|
163
|
+
# Blocking mode for queries
|
|
164
|
+
callback = RaxeLlamaIndexCallback(block_on_query_threats=True)
|
|
165
|
+
|
|
166
|
+
# With custom Raxe client
|
|
167
|
+
raxe = Raxe(api_key="raxe_...", telemetry=True)
|
|
168
|
+
callback = RaxeLlamaIndexCallback(raxe_client=raxe)
|
|
169
|
+
"""
|
|
170
|
+
# Initialize base class if it's a real LlamaIndex handler
|
|
171
|
+
if _LlamaIndexBaseHandler is not object:
|
|
172
|
+
# Pass empty ignore lists - we want to handle all events
|
|
173
|
+
super().__init__(
|
|
174
|
+
event_starts_to_ignore=[],
|
|
175
|
+
event_ends_to_ignore=[],
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Create or use provided Raxe client
|
|
179
|
+
raxe = raxe_client or Raxe()
|
|
180
|
+
self.raxe = raxe
|
|
181
|
+
self.block_on_query_threats = block_on_query_threats
|
|
182
|
+
self.block_on_response_threats = block_on_response_threats
|
|
183
|
+
self.scan_retrieved_context = scan_retrieved_context
|
|
184
|
+
self.scan_agent_actions = scan_agent_actions
|
|
185
|
+
|
|
186
|
+
# Create AgentScanner for unified scanning with integration telemetry
|
|
187
|
+
# Determine blocking behavior based on any blocking enabled
|
|
188
|
+
on_threat = "block" if (block_on_query_threats or block_on_response_threats) else "log"
|
|
189
|
+
config = AgentScannerConfig(
|
|
190
|
+
scan_prompts=True,
|
|
191
|
+
scan_responses=True,
|
|
192
|
+
on_threat=on_threat,
|
|
193
|
+
)
|
|
194
|
+
self._scanner = create_agent_scanner(raxe, config, integration_type="llamaindex")
|
|
195
|
+
|
|
196
|
+
# Track active events for correlation
|
|
197
|
+
self._active_events: dict[str, dict[str, Any]] = {}
|
|
198
|
+
|
|
199
|
+
logger.debug(
|
|
200
|
+
"RaxeLlamaIndexCallback initialized: "
|
|
201
|
+
f"block_queries={block_on_query_threats}, "
|
|
202
|
+
f"block_responses={block_on_response_threats}, "
|
|
203
|
+
f"scan_agent_actions={scan_agent_actions}"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
def on_event_start(
|
|
207
|
+
self,
|
|
208
|
+
event_type: Any,
|
|
209
|
+
payload: dict[str, Any] | None = None,
|
|
210
|
+
event_id: str = "",
|
|
211
|
+
parent_id: str = "",
|
|
212
|
+
**kwargs: Any,
|
|
213
|
+
) -> str:
|
|
214
|
+
"""Handle event start - scan inputs before processing.
|
|
215
|
+
|
|
216
|
+
This method is called by LlamaIndex's CallbackManager when an event
|
|
217
|
+
starts. We use it to scan queries, prompts, and agent inputs.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
event_type: CBEventType enum value
|
|
221
|
+
payload: Event payload with context data
|
|
222
|
+
event_id: Unique event identifier
|
|
223
|
+
parent_id: Parent event identifier
|
|
224
|
+
**kwargs: Additional callback arguments
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Event ID for tracking
|
|
228
|
+
|
|
229
|
+
Raises:
|
|
230
|
+
SecurityException: If threat detected and blocking enabled
|
|
231
|
+
"""
|
|
232
|
+
payload = payload or {}
|
|
233
|
+
|
|
234
|
+
# Store event context for correlation
|
|
235
|
+
self._active_events[event_id] = {
|
|
236
|
+
"event_type": event_type,
|
|
237
|
+
"parent_id": parent_id,
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Get event type name for comparison
|
|
241
|
+
event_name = self._get_event_type_name(event_type)
|
|
242
|
+
|
|
243
|
+
# Handle QUERY events - scan user query
|
|
244
|
+
if event_name == "QUERY":
|
|
245
|
+
query_str = payload.get("query_str") or payload.get("QUERY_STR", "")
|
|
246
|
+
if query_str:
|
|
247
|
+
self._scan_text(
|
|
248
|
+
text=query_str,
|
|
249
|
+
context="query",
|
|
250
|
+
block=self.block_on_query_threats,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# Handle LLM events - scan prompts
|
|
254
|
+
elif event_name == "LLM":
|
|
255
|
+
# Scan messages if present
|
|
256
|
+
messages = payload.get("messages", [])
|
|
257
|
+
for msg in messages:
|
|
258
|
+
content = self._extract_message_content(msg)
|
|
259
|
+
if content:
|
|
260
|
+
self._scan_text(
|
|
261
|
+
text=content,
|
|
262
|
+
context="llm_prompt",
|
|
263
|
+
block=self.block_on_query_threats,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# Scan template if present
|
|
267
|
+
template = payload.get("template", "")
|
|
268
|
+
if template and "{" not in template: # Skip templates with placeholders
|
|
269
|
+
self._scan_text(
|
|
270
|
+
text=template,
|
|
271
|
+
context="llm_template",
|
|
272
|
+
block=self.block_on_query_threats,
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Handle AGENT_STEP events - scan agent inputs
|
|
276
|
+
elif event_name == "AGENT_STEP" and self.scan_agent_actions:
|
|
277
|
+
task_str = payload.get("task_str", "")
|
|
278
|
+
if task_str:
|
|
279
|
+
self._scan_text(
|
|
280
|
+
text=task_str,
|
|
281
|
+
context="agent_input",
|
|
282
|
+
block=self.block_on_query_threats,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Handle FUNCTION_CALL events - scan tool inputs
|
|
286
|
+
elif event_name == "FUNCTION_CALL" and self.scan_agent_actions:
|
|
287
|
+
tool_input = payload.get("tool_input", "")
|
|
288
|
+
if isinstance(tool_input, str) and tool_input:
|
|
289
|
+
self._scan_text(
|
|
290
|
+
text=tool_input,
|
|
291
|
+
context="tool_input",
|
|
292
|
+
block=self.block_on_query_threats,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# Handle RETRIEVE events - future context validation
|
|
296
|
+
elif event_name == "RETRIEVE" and self.scan_retrieved_context:
|
|
297
|
+
# Placeholder for future retrieved context validation
|
|
298
|
+
# This would scan the query before retrieval
|
|
299
|
+
query_str = payload.get("query_str", "")
|
|
300
|
+
if query_str:
|
|
301
|
+
self._scan_text(
|
|
302
|
+
text=query_str,
|
|
303
|
+
context="retrieve_query",
|
|
304
|
+
block=self.block_on_query_threats,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
return event_id
|
|
308
|
+
|
|
309
|
+
def on_event_end(
|
|
310
|
+
self,
|
|
311
|
+
event_type: Any,
|
|
312
|
+
payload: dict[str, Any] | None = None,
|
|
313
|
+
event_id: str = "",
|
|
314
|
+
**kwargs: Any,
|
|
315
|
+
) -> None:
|
|
316
|
+
"""Handle event end - scan outputs after processing.
|
|
317
|
+
|
|
318
|
+
This method is called by LlamaIndex's CallbackManager when an event
|
|
319
|
+
ends. We use it to scan responses and synthesized content.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
event_type: CBEventType enum value
|
|
323
|
+
payload: Event payload with response data
|
|
324
|
+
event_id: Event identifier
|
|
325
|
+
**kwargs: Additional callback arguments
|
|
326
|
+
|
|
327
|
+
Raises:
|
|
328
|
+
SecurityException: If threat detected and blocking enabled
|
|
329
|
+
"""
|
|
330
|
+
payload = payload or {}
|
|
331
|
+
|
|
332
|
+
# Get event type name for comparison
|
|
333
|
+
event_name = self._get_event_type_name(event_type)
|
|
334
|
+
|
|
335
|
+
# Handle LLM events - scan responses
|
|
336
|
+
if event_name == "LLM":
|
|
337
|
+
response = payload.get("response", "")
|
|
338
|
+
if response:
|
|
339
|
+
response_text = self._extract_response_text(response)
|
|
340
|
+
if response_text:
|
|
341
|
+
self._scan_text(
|
|
342
|
+
text=response_text,
|
|
343
|
+
context="llm_response",
|
|
344
|
+
block=self.block_on_response_threats,
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
# Handle SYNTHESIZE events - scan synthesized responses
|
|
348
|
+
elif event_name == "SYNTHESIZE":
|
|
349
|
+
response = payload.get("response", "")
|
|
350
|
+
if response:
|
|
351
|
+
response_text = self._extract_response_text(response)
|
|
352
|
+
if response_text:
|
|
353
|
+
self._scan_text(
|
|
354
|
+
text=response_text,
|
|
355
|
+
context="synthesized_response",
|
|
356
|
+
block=self.block_on_response_threats,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
# Handle QUERY events - scan final query response
|
|
360
|
+
elif event_name == "QUERY":
|
|
361
|
+
response = payload.get("response", "")
|
|
362
|
+
if response:
|
|
363
|
+
response_text = self._extract_response_text(response)
|
|
364
|
+
if response_text:
|
|
365
|
+
self._scan_text(
|
|
366
|
+
text=response_text,
|
|
367
|
+
context="query_response",
|
|
368
|
+
block=self.block_on_response_threats,
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# Handle RETRIEVE events - future context validation
|
|
372
|
+
elif event_name == "RETRIEVE" and self.scan_retrieved_context:
|
|
373
|
+
# Placeholder for scanning retrieved nodes
|
|
374
|
+
# This would scan the actual retrieved context for threats
|
|
375
|
+
nodes = payload.get("nodes", [])
|
|
376
|
+
for node in nodes:
|
|
377
|
+
if hasattr(node, "text"):
|
|
378
|
+
self._scan_text(
|
|
379
|
+
text=node.text,
|
|
380
|
+
context="retrieved_context",
|
|
381
|
+
block=False, # Never block on retrieved context
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
# Handle FUNCTION_CALL events - scan tool outputs
|
|
385
|
+
elif event_name == "FUNCTION_CALL" and self.scan_agent_actions:
|
|
386
|
+
output = payload.get("output", "")
|
|
387
|
+
if isinstance(output, str) and output:
|
|
388
|
+
self._scan_text(
|
|
389
|
+
text=output,
|
|
390
|
+
context="tool_output",
|
|
391
|
+
block=self.block_on_response_threats,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
# Cleanup event tracking
|
|
395
|
+
self._active_events.pop(event_id, None)
|
|
396
|
+
|
|
397
|
+
def start_trace(self, trace_id: str | None = None) -> None:
|
|
398
|
+
"""Called when a trace starts.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
trace_id: Optional trace identifier
|
|
402
|
+
"""
|
|
403
|
+
# Optional: Could track trace-level metadata
|
|
404
|
+
pass
|
|
405
|
+
|
|
406
|
+
def end_trace(
|
|
407
|
+
self,
|
|
408
|
+
trace_id: str | None = None,
|
|
409
|
+
trace_map: dict[str, list[str]] | None = None,
|
|
410
|
+
) -> None:
|
|
411
|
+
"""Called when a trace ends.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
trace_id: Optional trace identifier
|
|
415
|
+
trace_map: Mapping of event IDs to child event IDs
|
|
416
|
+
"""
|
|
417
|
+
# Cleanup any remaining event state
|
|
418
|
+
self._active_events.clear()
|
|
419
|
+
|
|
420
|
+
def _scan_text(
|
|
421
|
+
self,
|
|
422
|
+
text: str,
|
|
423
|
+
context: str,
|
|
424
|
+
block: bool,
|
|
425
|
+
) -> None:
|
|
426
|
+
"""Scan text for security threats.
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
text: Text to scan
|
|
430
|
+
context: Context description for logging
|
|
431
|
+
block: Whether to raise exception on threat
|
|
432
|
+
|
|
433
|
+
Raises:
|
|
434
|
+
ThreatDetectedError: If threat detected and block=True
|
|
435
|
+
"""
|
|
436
|
+
if not text or not text.strip():
|
|
437
|
+
return
|
|
438
|
+
|
|
439
|
+
try:
|
|
440
|
+
# Determine scan type based on context
|
|
441
|
+
is_response = "response" in context or "output" in context
|
|
442
|
+
if is_response:
|
|
443
|
+
result = self._scanner.scan_response(text)
|
|
444
|
+
else:
|
|
445
|
+
result = self._scanner.scan_prompt(text)
|
|
446
|
+
|
|
447
|
+
if result.has_threats:
|
|
448
|
+
logger.warning(
|
|
449
|
+
f"Threat detected in LlamaIndex {context}: "
|
|
450
|
+
f"{result.severity} severity (action={result.action_taken})"
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
except ThreatDetectedError:
|
|
454
|
+
logger.error(
|
|
455
|
+
f"Blocked LlamaIndex {context} due to security threat"
|
|
456
|
+
)
|
|
457
|
+
raise
|
|
458
|
+
|
|
459
|
+
def _get_event_type_name(self, event_type: Any) -> str:
|
|
460
|
+
"""Extract event type name from CBEventType enum.
|
|
461
|
+
|
|
462
|
+
Args:
|
|
463
|
+
event_type: CBEventType enum value or string
|
|
464
|
+
|
|
465
|
+
Returns:
|
|
466
|
+
Event type name as string
|
|
467
|
+
"""
|
|
468
|
+
if isinstance(event_type, str):
|
|
469
|
+
return event_type.upper()
|
|
470
|
+
|
|
471
|
+
# Handle enum value
|
|
472
|
+
if hasattr(event_type, "name"):
|
|
473
|
+
return event_type.name.upper()
|
|
474
|
+
if hasattr(event_type, "value"):
|
|
475
|
+
return str(event_type.value).upper()
|
|
476
|
+
|
|
477
|
+
return str(event_type).upper()
|
|
478
|
+
|
|
479
|
+
def _extract_message_content(self, message: Any) -> str:
|
|
480
|
+
"""Extract text content from LlamaIndex message.
|
|
481
|
+
|
|
482
|
+
Uses unified extractor from raxe.sdk.integrations.extractors.
|
|
483
|
+
|
|
484
|
+
Args:
|
|
485
|
+
message: ChatMessage or dict with content
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
Extracted text content
|
|
489
|
+
"""
|
|
490
|
+
return extract_text_from_message(message) or ""
|
|
491
|
+
|
|
492
|
+
def _extract_response_text(self, response: Any) -> str:
|
|
493
|
+
"""Extract text from LlamaIndex response objects.
|
|
494
|
+
|
|
495
|
+
Uses unified extractor with LlamaIndex-specific fallbacks.
|
|
496
|
+
|
|
497
|
+
Args:
|
|
498
|
+
response: Response object (various formats)
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
Extracted response text
|
|
502
|
+
"""
|
|
503
|
+
if isinstance(response, str):
|
|
504
|
+
return response
|
|
505
|
+
|
|
506
|
+
# Handle LlamaIndex Response object with response attribute
|
|
507
|
+
if hasattr(response, "response"):
|
|
508
|
+
return str(response.response)
|
|
509
|
+
|
|
510
|
+
# Try unified extractor for other formats
|
|
511
|
+
text = extract_text_from_response(response)
|
|
512
|
+
if text:
|
|
513
|
+
return text
|
|
514
|
+
|
|
515
|
+
# Handle dict response (LlamaIndex-specific keys)
|
|
516
|
+
if isinstance(response, dict):
|
|
517
|
+
return response.get("response", "") or response.get("text", "")
|
|
518
|
+
|
|
519
|
+
return ""
|
|
520
|
+
|
|
521
|
+
def __repr__(self) -> str:
|
|
522
|
+
"""String representation of callback handler.
|
|
523
|
+
|
|
524
|
+
Returns:
|
|
525
|
+
Human-readable string
|
|
526
|
+
"""
|
|
527
|
+
return (
|
|
528
|
+
f"RaxeLlamaIndexCallback("
|
|
529
|
+
f"block_queries={self.block_on_query_threats}, "
|
|
530
|
+
f"block_responses={self.block_on_response_threats}, "
|
|
531
|
+
f"scan_agent_actions={self.scan_agent_actions})"
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
# ========================================================================
|
|
535
|
+
# Async Event Handlers
|
|
536
|
+
# ========================================================================
|
|
537
|
+
# Async versions of event handlers for use in async contexts.
|
|
538
|
+
|
|
539
|
+
async def on_event_start_async(
|
|
540
|
+
self,
|
|
541
|
+
event_type: Any,
|
|
542
|
+
payload: dict[str, Any] | None = None,
|
|
543
|
+
event_id: str = "",
|
|
544
|
+
parent_id: str = "",
|
|
545
|
+
**kwargs: Any,
|
|
546
|
+
) -> str:
|
|
547
|
+
"""Async version of on_event_start - scan inputs before processing.
|
|
548
|
+
|
|
549
|
+
Args:
|
|
550
|
+
event_type: CBEventType enum value
|
|
551
|
+
payload: Event payload with context data
|
|
552
|
+
event_id: Unique event identifier
|
|
553
|
+
parent_id: Parent event identifier
|
|
554
|
+
**kwargs: Additional callback arguments
|
|
555
|
+
|
|
556
|
+
Returns:
|
|
557
|
+
Event ID for tracking
|
|
558
|
+
|
|
559
|
+
Raises:
|
|
560
|
+
SecurityException: If threat detected and blocking enabled
|
|
561
|
+
"""
|
|
562
|
+
import asyncio
|
|
563
|
+
|
|
564
|
+
payload = payload or {}
|
|
565
|
+
|
|
566
|
+
self._active_events[event_id] = {
|
|
567
|
+
"event_type": event_type,
|
|
568
|
+
"parent_id": parent_id,
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
event_name = self._get_event_type_name(event_type)
|
|
572
|
+
|
|
573
|
+
if event_name == "QUERY":
|
|
574
|
+
query_str = payload.get("query_str") or payload.get("QUERY_STR", "")
|
|
575
|
+
if query_str:
|
|
576
|
+
await self._scan_text_async(
|
|
577
|
+
text=query_str,
|
|
578
|
+
context="query",
|
|
579
|
+
block=self.block_on_query_threats,
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
elif event_name == "LLM":
|
|
583
|
+
messages = payload.get("messages", [])
|
|
584
|
+
for msg in messages:
|
|
585
|
+
content = self._extract_message_content(msg)
|
|
586
|
+
if content:
|
|
587
|
+
await self._scan_text_async(
|
|
588
|
+
text=content,
|
|
589
|
+
context="llm_prompt",
|
|
590
|
+
block=self.block_on_query_threats,
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
template = payload.get("template", "")
|
|
594
|
+
if template and "{" not in template:
|
|
595
|
+
await self._scan_text_async(
|
|
596
|
+
text=template,
|
|
597
|
+
context="llm_template",
|
|
598
|
+
block=self.block_on_query_threats,
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
elif event_name == "AGENT_STEP" and self.scan_agent_actions:
|
|
602
|
+
task_str = payload.get("task_str", "")
|
|
603
|
+
if task_str:
|
|
604
|
+
await self._scan_text_async(
|
|
605
|
+
text=task_str,
|
|
606
|
+
context="agent_input",
|
|
607
|
+
block=self.block_on_query_threats,
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
elif event_name == "FUNCTION_CALL" and self.scan_agent_actions:
|
|
611
|
+
tool_input = payload.get("tool_input", "")
|
|
612
|
+
if isinstance(tool_input, str) and tool_input:
|
|
613
|
+
await self._scan_text_async(
|
|
614
|
+
text=tool_input,
|
|
615
|
+
context="tool_input",
|
|
616
|
+
block=self.block_on_query_threats,
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
elif event_name == "RETRIEVE" and self.scan_retrieved_context:
|
|
620
|
+
query_str = payload.get("query_str", "")
|
|
621
|
+
if query_str:
|
|
622
|
+
await self._scan_text_async(
|
|
623
|
+
text=query_str,
|
|
624
|
+
context="retrieve_query",
|
|
625
|
+
block=self.block_on_query_threats,
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
return event_id
|
|
629
|
+
|
|
630
|
+
async def on_event_end_async(
|
|
631
|
+
self,
|
|
632
|
+
event_type: Any,
|
|
633
|
+
payload: dict[str, Any] | None = None,
|
|
634
|
+
event_id: str = "",
|
|
635
|
+
**kwargs: Any,
|
|
636
|
+
) -> None:
|
|
637
|
+
"""Async version of on_event_end - scan outputs after processing.
|
|
638
|
+
|
|
639
|
+
Args:
|
|
640
|
+
event_type: CBEventType enum value
|
|
641
|
+
payload: Event payload with response data
|
|
642
|
+
event_id: Event identifier
|
|
643
|
+
**kwargs: Additional callback arguments
|
|
644
|
+
|
|
645
|
+
Raises:
|
|
646
|
+
SecurityException: If threat detected and blocking enabled
|
|
647
|
+
"""
|
|
648
|
+
import asyncio
|
|
649
|
+
|
|
650
|
+
payload = payload or {}
|
|
651
|
+
event_name = self._get_event_type_name(event_type)
|
|
652
|
+
|
|
653
|
+
if event_name == "LLM":
|
|
654
|
+
response = payload.get("response", "")
|
|
655
|
+
if response:
|
|
656
|
+
response_text = self._extract_response_text(response)
|
|
657
|
+
if response_text:
|
|
658
|
+
await self._scan_text_async(
|
|
659
|
+
text=response_text,
|
|
660
|
+
context="llm_response",
|
|
661
|
+
block=self.block_on_response_threats,
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
elif event_name == "SYNTHESIZE":
|
|
665
|
+
response = payload.get("response", "")
|
|
666
|
+
if response:
|
|
667
|
+
response_text = self._extract_response_text(response)
|
|
668
|
+
if response_text:
|
|
669
|
+
await self._scan_text_async(
|
|
670
|
+
text=response_text,
|
|
671
|
+
context="synthesized_response",
|
|
672
|
+
block=self.block_on_response_threats,
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
elif event_name == "QUERY":
|
|
676
|
+
response = payload.get("response", "")
|
|
677
|
+
if response:
|
|
678
|
+
response_text = self._extract_response_text(response)
|
|
679
|
+
if response_text:
|
|
680
|
+
await self._scan_text_async(
|
|
681
|
+
text=response_text,
|
|
682
|
+
context="query_response",
|
|
683
|
+
block=self.block_on_response_threats,
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
elif event_name == "RETRIEVE" and self.scan_retrieved_context:
|
|
687
|
+
nodes = payload.get("nodes", [])
|
|
688
|
+
for node in nodes:
|
|
689
|
+
if hasattr(node, "text"):
|
|
690
|
+
await self._scan_text_async(
|
|
691
|
+
text=node.text,
|
|
692
|
+
context="retrieved_context",
|
|
693
|
+
block=False,
|
|
694
|
+
)
|
|
695
|
+
|
|
696
|
+
elif event_name == "FUNCTION_CALL" and self.scan_agent_actions:
|
|
697
|
+
output = payload.get("output", "")
|
|
698
|
+
if isinstance(output, str) and output:
|
|
699
|
+
await self._scan_text_async(
|
|
700
|
+
text=output,
|
|
701
|
+
context="tool_output",
|
|
702
|
+
block=self.block_on_response_threats,
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
self._active_events.pop(event_id, None)
|
|
706
|
+
|
|
707
|
+
async def _scan_text_async(
|
|
708
|
+
self,
|
|
709
|
+
text: str,
|
|
710
|
+
context: str,
|
|
711
|
+
block: bool,
|
|
712
|
+
) -> None:
|
|
713
|
+
"""Async version of _scan_text - scan text for security threats.
|
|
714
|
+
|
|
715
|
+
Args:
|
|
716
|
+
text: Text to scan
|
|
717
|
+
context: Context description for logging
|
|
718
|
+
block: Whether to raise exception on threat
|
|
719
|
+
|
|
720
|
+
Raises:
|
|
721
|
+
ThreatDetectedError: If threat detected and block=True
|
|
722
|
+
"""
|
|
723
|
+
import asyncio
|
|
724
|
+
|
|
725
|
+
if not text or not text.strip():
|
|
726
|
+
return
|
|
727
|
+
|
|
728
|
+
try:
|
|
729
|
+
# Determine scan type based on context
|
|
730
|
+
is_response = "response" in context or "output" in context
|
|
731
|
+
if is_response:
|
|
732
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
733
|
+
None,
|
|
734
|
+
lambda: self._scanner.scan_response(text),
|
|
735
|
+
)
|
|
736
|
+
else:
|
|
737
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
738
|
+
None,
|
|
739
|
+
lambda: self._scanner.scan_prompt(text),
|
|
740
|
+
)
|
|
741
|
+
|
|
742
|
+
if result.has_threats:
|
|
743
|
+
logger.warning(
|
|
744
|
+
f"Threat detected in LlamaIndex {context} (async): "
|
|
745
|
+
f"{result.severity} severity (action={result.action_taken})"
|
|
746
|
+
)
|
|
747
|
+
|
|
748
|
+
except ThreatDetectedError:
|
|
749
|
+
logger.error(
|
|
750
|
+
f"Blocked LlamaIndex {context} due to security threat (async)"
|
|
751
|
+
)
|
|
752
|
+
raise
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
class RaxeSpanHandler:
|
|
756
|
+
"""LlamaIndex instrumentation span handler for RAXE scanning.
|
|
757
|
+
|
|
758
|
+
This handler integrates with LlamaIndex's new instrumentation API
|
|
759
|
+
(v0.10.20+) for more granular observability and scanning.
|
|
760
|
+
|
|
761
|
+
The instrumentation API provides:
|
|
762
|
+
- Structured spans with duration and context
|
|
763
|
+
- Event-based tracking within spans
|
|
764
|
+
- Parent-child relationships for tracing
|
|
765
|
+
- OpenTelemetry compatibility
|
|
766
|
+
|
|
767
|
+
Usage:
|
|
768
|
+
>>> from llama_index.core.instrumentation import get_dispatcher
|
|
769
|
+
>>> from raxe.sdk.integrations import RaxeSpanHandler
|
|
770
|
+
>>>
|
|
771
|
+
>>> span_handler = RaxeSpanHandler()
|
|
772
|
+
>>> root_dispatcher = get_dispatcher()
|
|
773
|
+
>>> root_dispatcher.add_span_handler(span_handler)
|
|
774
|
+
|
|
775
|
+
Note:
|
|
776
|
+
This is designed for LlamaIndex v0.10.20+ which introduced
|
|
777
|
+
the instrumentation module. For earlier versions, use
|
|
778
|
+
RaxeLlamaIndexCallback instead.
|
|
779
|
+
"""
|
|
780
|
+
|
|
781
|
+
def __init__(
|
|
782
|
+
self,
|
|
783
|
+
raxe_client: Raxe | None = None,
|
|
784
|
+
*,
|
|
785
|
+
block_on_threats: bool = False,
|
|
786
|
+
scan_llm_inputs: bool = True,
|
|
787
|
+
scan_llm_outputs: bool = True,
|
|
788
|
+
) -> None:
|
|
789
|
+
"""Initialize RAXE span handler.
|
|
790
|
+
|
|
791
|
+
Args:
|
|
792
|
+
raxe_client: Optional Raxe instance (creates default if None)
|
|
793
|
+
block_on_threats: Block on any threats (default: False)
|
|
794
|
+
scan_llm_inputs: Scan LLM inputs (default: True)
|
|
795
|
+
scan_llm_outputs: Scan LLM outputs (default: True)
|
|
796
|
+
"""
|
|
797
|
+
raxe = raxe_client or Raxe()
|
|
798
|
+
self.raxe = raxe
|
|
799
|
+
self.block_on_threats = block_on_threats
|
|
800
|
+
self.scan_llm_inputs = scan_llm_inputs
|
|
801
|
+
self.scan_llm_outputs = scan_llm_outputs
|
|
802
|
+
|
|
803
|
+
# Create AgentScanner for unified scanning with integration telemetry
|
|
804
|
+
config = AgentScannerConfig(
|
|
805
|
+
scan_prompts=scan_llm_inputs,
|
|
806
|
+
scan_responses=scan_llm_outputs,
|
|
807
|
+
on_threat="block" if block_on_threats else "log",
|
|
808
|
+
)
|
|
809
|
+
self._scanner = create_agent_scanner(raxe, config, integration_type="llamaindex")
|
|
810
|
+
|
|
811
|
+
logger.debug(
|
|
812
|
+
"RaxeSpanHandler initialized: "
|
|
813
|
+
f"block={block_on_threats}, "
|
|
814
|
+
f"scan_inputs={scan_llm_inputs}, "
|
|
815
|
+
f"scan_outputs={scan_llm_outputs}"
|
|
816
|
+
)
|
|
817
|
+
|
|
818
|
+
def span_enter(
|
|
819
|
+
self,
|
|
820
|
+
id_: str,
|
|
821
|
+
bound_args: dict[str, Any],
|
|
822
|
+
instance: Any | None = None,
|
|
823
|
+
parent_id: str | None = None,
|
|
824
|
+
**kwargs: Any,
|
|
825
|
+
) -> None:
|
|
826
|
+
"""Called when entering a span.
|
|
827
|
+
|
|
828
|
+
Args:
|
|
829
|
+
id_: Span identifier
|
|
830
|
+
bound_args: Arguments bound to the function
|
|
831
|
+
instance: Instance the method is bound to
|
|
832
|
+
parent_id: Parent span identifier
|
|
833
|
+
**kwargs: Additional span data
|
|
834
|
+
"""
|
|
835
|
+
if not self.scan_llm_inputs:
|
|
836
|
+
return
|
|
837
|
+
|
|
838
|
+
# Scan any string arguments
|
|
839
|
+
for key, value in bound_args.items():
|
|
840
|
+
if key in ("query", "prompt", "messages", "input"):
|
|
841
|
+
self._scan_value(value, f"span_input_{key}")
|
|
842
|
+
|
|
843
|
+
def span_exit(
|
|
844
|
+
self,
|
|
845
|
+
id_: str,
|
|
846
|
+
bound_args: dict[str, Any],
|
|
847
|
+
instance: Any | None = None,
|
|
848
|
+
result: Any | None = None,
|
|
849
|
+
**kwargs: Any,
|
|
850
|
+
) -> None:
|
|
851
|
+
"""Called when exiting a span.
|
|
852
|
+
|
|
853
|
+
Args:
|
|
854
|
+
id_: Span identifier
|
|
855
|
+
bound_args: Arguments bound to the function
|
|
856
|
+
instance: Instance the method is bound to
|
|
857
|
+
result: Result of the function
|
|
858
|
+
**kwargs: Additional span data
|
|
859
|
+
"""
|
|
860
|
+
if not self.scan_llm_outputs:
|
|
861
|
+
return
|
|
862
|
+
|
|
863
|
+
if result is not None:
|
|
864
|
+
self._scan_value(result, "span_output")
|
|
865
|
+
|
|
866
|
+
def span_drop(
|
|
867
|
+
self,
|
|
868
|
+
id_: str,
|
|
869
|
+
bound_args: dict[str, Any],
|
|
870
|
+
instance: Any | None = None,
|
|
871
|
+
err: Exception | None = None,
|
|
872
|
+
**kwargs: Any,
|
|
873
|
+
) -> None:
|
|
874
|
+
"""Called when a span is dropped (error occurred).
|
|
875
|
+
|
|
876
|
+
Args:
|
|
877
|
+
id_: Span identifier
|
|
878
|
+
bound_args: Arguments bound to the function
|
|
879
|
+
instance: Instance the method is bound to
|
|
880
|
+
err: Exception that caused the drop
|
|
881
|
+
**kwargs: Additional span data
|
|
882
|
+
"""
|
|
883
|
+
# Don't interfere with error handling
|
|
884
|
+
pass
|
|
885
|
+
|
|
886
|
+
def _scan_value(self, value: Any, context: str) -> None:
|
|
887
|
+
"""Scan a value for security threats.
|
|
888
|
+
|
|
889
|
+
Args:
|
|
890
|
+
value: Value to scan (string, list, or object with text)
|
|
891
|
+
context: Context description for logging
|
|
892
|
+
"""
|
|
893
|
+
texts = self._extract_texts(value)
|
|
894
|
+
|
|
895
|
+
for text in texts:
|
|
896
|
+
if text and text.strip():
|
|
897
|
+
try:
|
|
898
|
+
# Determine scan type based on context
|
|
899
|
+
is_output = "output" in context
|
|
900
|
+
if is_output:
|
|
901
|
+
result = self._scanner.scan_response(text)
|
|
902
|
+
else:
|
|
903
|
+
result = self._scanner.scan_prompt(text)
|
|
904
|
+
|
|
905
|
+
if result.has_threats:
|
|
906
|
+
logger.warning(
|
|
907
|
+
f"Threat detected in LlamaIndex {context}: "
|
|
908
|
+
f"{result.severity} severity (action={result.action_taken})"
|
|
909
|
+
)
|
|
910
|
+
|
|
911
|
+
except ThreatDetectedError:
|
|
912
|
+
logger.error(
|
|
913
|
+
f"Blocked LlamaIndex {context} due to security threat"
|
|
914
|
+
)
|
|
915
|
+
raise
|
|
916
|
+
|
|
917
|
+
def _extract_texts(self, value: Any) -> list[str]:
|
|
918
|
+
"""Extract text strings from various value types.
|
|
919
|
+
|
|
920
|
+
Uses unified extractor from raxe.sdk.integrations.extractors.
|
|
921
|
+
|
|
922
|
+
Args:
|
|
923
|
+
value: Value to extract text from
|
|
924
|
+
|
|
925
|
+
Returns:
|
|
926
|
+
List of text strings
|
|
927
|
+
"""
|
|
928
|
+
return extract_texts_from_value(value)
|
|
929
|
+
|
|
930
|
+
def __repr__(self) -> str:
|
|
931
|
+
"""String representation of span handler."""
|
|
932
|
+
return (
|
|
933
|
+
f"RaxeSpanHandler("
|
|
934
|
+
f"block={self.block_on_threats}, "
|
|
935
|
+
f"scan_inputs={self.scan_llm_inputs}, "
|
|
936
|
+
f"scan_outputs={self.scan_llm_outputs})"
|
|
937
|
+
)
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
class RaxeQueryEngineCallback(RaxeLlamaIndexCallback):
|
|
941
|
+
"""Specialized callback handler for Query Engine use cases.
|
|
942
|
+
|
|
943
|
+
This is a convenience subclass of RaxeLlamaIndexCallback that is
|
|
944
|
+
optimized for query engine and RAG pipeline use cases.
|
|
945
|
+
|
|
946
|
+
Key features:
|
|
947
|
+
- Focused on QUERY, RETRIEVE, and SYNTHESIZE events
|
|
948
|
+
- Simplified configuration for RAG pipelines
|
|
949
|
+
- Default log-only mode for non-intrusive integration
|
|
950
|
+
|
|
951
|
+
Example:
|
|
952
|
+
>>> from llama_index.core import VectorStoreIndex, Settings
|
|
953
|
+
>>> from llama_index.core.callbacks import CallbackManager
|
|
954
|
+
>>> from raxe.sdk.integrations import RaxeQueryEngineCallback
|
|
955
|
+
>>>
|
|
956
|
+
>>> # Create and configure
|
|
957
|
+
>>> callback = RaxeQueryEngineCallback()
|
|
958
|
+
>>> Settings.callback_manager = CallbackManager([callback])
|
|
959
|
+
>>>
|
|
960
|
+
>>> # Query with automatic scanning
|
|
961
|
+
>>> index = VectorStoreIndex.from_documents(documents)
|
|
962
|
+
>>> engine = index.as_query_engine()
|
|
963
|
+
>>> response = engine.query("What is the summary?")
|
|
964
|
+
"""
|
|
965
|
+
|
|
966
|
+
def __init__(
|
|
967
|
+
self,
|
|
968
|
+
raxe_client: Raxe | None = None,
|
|
969
|
+
*,
|
|
970
|
+
block_on_threats: bool = False,
|
|
971
|
+
) -> None:
|
|
972
|
+
"""Initialize Query Engine callback.
|
|
973
|
+
|
|
974
|
+
Args:
|
|
975
|
+
raxe_client: Optional Raxe instance
|
|
976
|
+
block_on_threats: Block on any threats (default: False)
|
|
977
|
+
"""
|
|
978
|
+
super().__init__(
|
|
979
|
+
raxe_client=raxe_client,
|
|
980
|
+
block_on_query_threats=block_on_threats,
|
|
981
|
+
block_on_response_threats=block_on_threats,
|
|
982
|
+
scan_retrieved_context=False, # Future feature
|
|
983
|
+
scan_agent_actions=False, # Not needed for query engines
|
|
984
|
+
)
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
class RaxeAgentCallback(RaxeLlamaIndexCallback):
|
|
988
|
+
"""Specialized callback handler for Agent use cases.
|
|
989
|
+
|
|
990
|
+
This is a convenience subclass of RaxeLlamaIndexCallback that is
|
|
991
|
+
optimized for LlamaIndex agents (ReActAgent, FunctionCallingAgent, etc.).
|
|
992
|
+
|
|
993
|
+
Key features:
|
|
994
|
+
- Focused on AGENT_STEP and FUNCTION_CALL events
|
|
995
|
+
- Scans tool inputs and outputs
|
|
996
|
+
- Default log-only mode for non-intrusive integration
|
|
997
|
+
|
|
998
|
+
Example:
|
|
999
|
+
>>> from llama_index.core.agent import ReActAgent
|
|
1000
|
+
>>> from llama_index.core.callbacks import CallbackManager
|
|
1001
|
+
>>> from raxe.sdk.integrations import RaxeAgentCallback
|
|
1002
|
+
>>>
|
|
1003
|
+
>>> # Create and configure
|
|
1004
|
+
>>> callback = RaxeAgentCallback()
|
|
1005
|
+
>>> callback_manager = CallbackManager([callback])
|
|
1006
|
+
>>>
|
|
1007
|
+
>>> # Create agent with scanning
|
|
1008
|
+
>>> agent = ReActAgent.from_tools(
|
|
1009
|
+
... tools=[...],
|
|
1010
|
+
... callback_manager=callback_manager,
|
|
1011
|
+
... verbose=True,
|
|
1012
|
+
... )
|
|
1013
|
+
>>> response = agent.chat("Calculate 2+2")
|
|
1014
|
+
"""
|
|
1015
|
+
|
|
1016
|
+
def __init__(
|
|
1017
|
+
self,
|
|
1018
|
+
raxe_client: Raxe | None = None,
|
|
1019
|
+
*,
|
|
1020
|
+
block_on_threats: bool = False,
|
|
1021
|
+
scan_tool_outputs: bool = True,
|
|
1022
|
+
) -> None:
|
|
1023
|
+
"""Initialize Agent callback.
|
|
1024
|
+
|
|
1025
|
+
Args:
|
|
1026
|
+
raxe_client: Optional Raxe instance
|
|
1027
|
+
block_on_threats: Block on any threats (default: False)
|
|
1028
|
+
scan_tool_outputs: Scan tool output values (default: True)
|
|
1029
|
+
"""
|
|
1030
|
+
super().__init__(
|
|
1031
|
+
raxe_client=raxe_client,
|
|
1032
|
+
block_on_query_threats=block_on_threats,
|
|
1033
|
+
block_on_response_threats=block_on_threats and scan_tool_outputs,
|
|
1034
|
+
scan_retrieved_context=False,
|
|
1035
|
+
scan_agent_actions=True,
|
|
1036
|
+
)
|
|
1037
|
+
self._scan_tool_outputs = scan_tool_outputs
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
# ============================================================================
|
|
1041
|
+
# Exports
|
|
1042
|
+
# ============================================================================
|
|
1043
|
+
|
|
1044
|
+
__all__ = [
|
|
1045
|
+
"RaxeAgentCallback",
|
|
1046
|
+
"RaxeLlamaIndexCallback",
|
|
1047
|
+
"RaxeQueryEngineCallback",
|
|
1048
|
+
"RaxeSpanHandler",
|
|
1049
|
+
]
|