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
raxe/cli/auth.py
ADDED
|
@@ -0,0 +1,1047 @@
|
|
|
1
|
+
"""CLI commands for authentication and API key management.
|
|
2
|
+
|
|
3
|
+
Provides commands for:
|
|
4
|
+
- Device flow authentication (recommended): Opens browser for one-click setup
|
|
5
|
+
- Manual authentication: Opens RAXE Console for copy-paste key setup
|
|
6
|
+
- Validating API key configuration
|
|
7
|
+
- Checking remote API key status
|
|
8
|
+
|
|
9
|
+
Example usage:
|
|
10
|
+
raxe auth # Device flow (recommended)
|
|
11
|
+
raxe auth connect # Same as above
|
|
12
|
+
raxe auth login # Manual key setup
|
|
13
|
+
raxe auth status
|
|
14
|
+
raxe auth status --remote
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import time
|
|
21
|
+
import webbrowser
|
|
22
|
+
from datetime import datetime, timezone
|
|
23
|
+
from typing import Optional
|
|
24
|
+
|
|
25
|
+
import click
|
|
26
|
+
import httpx
|
|
27
|
+
from rich.table import Table
|
|
28
|
+
|
|
29
|
+
from raxe.cli.error_handler import handle_cli_error
|
|
30
|
+
from raxe.cli.output import console, display_error, display_success
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Console URLs - resolved via centralized endpoints module
|
|
34
|
+
def _get_console_url() -> str:
|
|
35
|
+
"""Get console URL from centralized endpoints."""
|
|
36
|
+
from raxe.infrastructure.config.endpoints import get_console_url
|
|
37
|
+
return get_console_url()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _get_api_base_url() -> str:
|
|
41
|
+
"""Get API base URL from centralized endpoints."""
|
|
42
|
+
from raxe.infrastructure.config.endpoints import get_api_base
|
|
43
|
+
return get_api_base()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _get_cli_session_endpoint() -> str:
|
|
47
|
+
"""Get CLI session endpoint from centralized endpoints."""
|
|
48
|
+
from raxe.infrastructure.config.endpoints import get_cli_session_endpoint
|
|
49
|
+
return get_cli_session_endpoint()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _get_cli_link_endpoint() -> str:
|
|
53
|
+
"""Get CLI link endpoint from centralized endpoints."""
|
|
54
|
+
from raxe.infrastructure.config.endpoints import Endpoint, get_endpoint
|
|
55
|
+
return get_endpoint(Endpoint.CLI_LINK)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _get_console_keys_url() -> str:
|
|
59
|
+
"""Get console keys URL."""
|
|
60
|
+
return f"{_get_console_url()}/keys"
|
|
61
|
+
|
|
62
|
+
# Polling configuration
|
|
63
|
+
POLL_INTERVAL_SECONDS = 2
|
|
64
|
+
POLL_TIMEOUT_SECONDS = 300 # 5 minutes
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@click.group(invoke_without_command=True)
|
|
68
|
+
@click.option(
|
|
69
|
+
"--no-link-history",
|
|
70
|
+
is_flag=True,
|
|
71
|
+
default=False,
|
|
72
|
+
help="Do not link existing CLI history to the new account",
|
|
73
|
+
)
|
|
74
|
+
@click.pass_context
|
|
75
|
+
def auth(ctx, no_link_history: bool) -> None:
|
|
76
|
+
"""Manage authentication and API keys.
|
|
77
|
+
|
|
78
|
+
Run without subcommand for interactive device flow authentication.
|
|
79
|
+
"""
|
|
80
|
+
if ctx.invoked_subcommand is None:
|
|
81
|
+
# Default to connect flow when no subcommand
|
|
82
|
+
ctx.invoke(auth_connect, no_link_history=no_link_history)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _get_current_key_id_from_telemetry() -> Optional[str]:
|
|
86
|
+
"""Get the current api_key_id from telemetry state.
|
|
87
|
+
|
|
88
|
+
This ensures the temp_key_id sent during authentication matches
|
|
89
|
+
what telemetry events are using, enabling proper event linking
|
|
90
|
+
when upgrading from temporary to permanent keys.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
The api_key_id from telemetry state, or None if not available.
|
|
94
|
+
"""
|
|
95
|
+
try:
|
|
96
|
+
from raxe.application.telemetry_orchestrator import get_orchestrator
|
|
97
|
+
orchestrator = get_orchestrator()
|
|
98
|
+
return orchestrator.get_current_api_key_id()
|
|
99
|
+
except Exception:
|
|
100
|
+
# Gracefully handle any initialization errors
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@auth.command("connect")
|
|
105
|
+
@click.option(
|
|
106
|
+
"--no-link-history",
|
|
107
|
+
is_flag=True,
|
|
108
|
+
default=False,
|
|
109
|
+
help="Do not link existing CLI history to the new account",
|
|
110
|
+
)
|
|
111
|
+
@handle_cli_error
|
|
112
|
+
def auth_connect(no_link_history: bool) -> None:
|
|
113
|
+
"""Connect CLI to your RAXE account (recommended).
|
|
114
|
+
|
|
115
|
+
Opens your browser for one-click authentication.
|
|
116
|
+
Your CLI will be automatically configured.
|
|
117
|
+
|
|
118
|
+
By default, any existing CLI history from a temporary key will be
|
|
119
|
+
automatically linked to your account. Use --no-link-history to
|
|
120
|
+
skip this and start fresh.
|
|
121
|
+
|
|
122
|
+
Examples:
|
|
123
|
+
raxe auth
|
|
124
|
+
raxe auth connect
|
|
125
|
+
raxe auth --no-link-history
|
|
126
|
+
"""
|
|
127
|
+
from rich.prompt import Confirm
|
|
128
|
+
|
|
129
|
+
from raxe.cli.branding import print_logo
|
|
130
|
+
from raxe.infrastructure.telemetry.credential_store import (
|
|
131
|
+
CredentialStore,
|
|
132
|
+
compute_key_id,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
print_logo(console, compact=True)
|
|
136
|
+
console.print()
|
|
137
|
+
console.print("[bold cyan]RAXE CLI Authentication[/bold cyan]")
|
|
138
|
+
console.print()
|
|
139
|
+
|
|
140
|
+
# Get current credentials
|
|
141
|
+
store = CredentialStore()
|
|
142
|
+
credentials = store.load()
|
|
143
|
+
temp_key_id: Optional[str] = None
|
|
144
|
+
installation_id: Optional[str] = None
|
|
145
|
+
|
|
146
|
+
# Only detect temp_key_id if we want to link history (default behavior)
|
|
147
|
+
if not no_link_history:
|
|
148
|
+
# Priority 1: Get key_id from telemetry state (ensures consistency with events)
|
|
149
|
+
temp_key_id = _get_current_key_id_from_telemetry()
|
|
150
|
+
|
|
151
|
+
# Priority 2: Fall back to computing from credentials
|
|
152
|
+
if temp_key_id is None and credentials and credentials.api_key:
|
|
153
|
+
temp_key_id = compute_key_id(credentials.api_key)
|
|
154
|
+
|
|
155
|
+
if credentials:
|
|
156
|
+
installation_id = credentials.installation_id
|
|
157
|
+
|
|
158
|
+
# Check if already authenticated with a permanent key
|
|
159
|
+
if credentials.api_key and credentials.api_key.startswith("raxe_live_"):
|
|
160
|
+
masked_key = f"{credentials.api_key[:15]}...{credentials.api_key[-4:]}"
|
|
161
|
+
console.print(f"[green]Already authenticated![/green]")
|
|
162
|
+
console.print(f" API Key: [cyan]{masked_key}[/cyan]")
|
|
163
|
+
console.print()
|
|
164
|
+
|
|
165
|
+
if not Confirm.ask("Re-authenticate with a different account?", default=False):
|
|
166
|
+
console.print()
|
|
167
|
+
console.print("[dim]Run [cyan]raxe auth status[/cyan] to see details[/dim]")
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
console.print()
|
|
171
|
+
|
|
172
|
+
# Create CLI session
|
|
173
|
+
console.print("[dim]Creating authentication session...[/dim]")
|
|
174
|
+
|
|
175
|
+
try:
|
|
176
|
+
session_data = _create_cli_session(temp_key_id, installation_id)
|
|
177
|
+
except Exception as e:
|
|
178
|
+
display_error(
|
|
179
|
+
"Failed to create session",
|
|
180
|
+
details=str(e),
|
|
181
|
+
)
|
|
182
|
+
console.print()
|
|
183
|
+
console.print("[dim]Falling back to manual authentication:[/dim]")
|
|
184
|
+
console.print(f" Visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
|
|
185
|
+
console.print(" Then run: [cyan]raxe config set api_key YOUR_KEY[/cyan]")
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
session_id = session_data["session_id"]
|
|
189
|
+
connect_url = session_data["connect_url"]
|
|
190
|
+
scan_count = session_data.get("scan_count", 0)
|
|
191
|
+
|
|
192
|
+
# Show scan preview if any (only when linking history)
|
|
193
|
+
# We show "scans" (not "events") for consistency with Portal metrics
|
|
194
|
+
if scan_count > 0 and not no_link_history:
|
|
195
|
+
console.print()
|
|
196
|
+
console.print(f"[green]Found {scan_count:,} scans from your CLI history![/green]")
|
|
197
|
+
console.print("[dim] These will be linked to your account.[/dim]")
|
|
198
|
+
elif no_link_history:
|
|
199
|
+
console.print()
|
|
200
|
+
console.print("[dim]History linking disabled (--no-link-history)[/dim]")
|
|
201
|
+
|
|
202
|
+
console.print()
|
|
203
|
+
console.print("[cyan]Opening browser...[/cyan]")
|
|
204
|
+
console.print()
|
|
205
|
+
|
|
206
|
+
# Open browser
|
|
207
|
+
try:
|
|
208
|
+
webbrowser.open(connect_url)
|
|
209
|
+
console.print("[dim]If browser doesn't open, visit:[/dim]")
|
|
210
|
+
console.print(f"[blue underline]{connect_url}[/blue underline]")
|
|
211
|
+
except Exception:
|
|
212
|
+
console.print("[yellow]Could not open browser. Please visit:[/yellow]")
|
|
213
|
+
console.print(f"[blue underline]{connect_url}[/blue underline]")
|
|
214
|
+
|
|
215
|
+
console.print()
|
|
216
|
+
|
|
217
|
+
# Poll for completion
|
|
218
|
+
with console.status("[cyan]Waiting for authentication...[/cyan]") as status:
|
|
219
|
+
start_time = time.time()
|
|
220
|
+
|
|
221
|
+
while time.time() - start_time < POLL_TIMEOUT_SECONDS:
|
|
222
|
+
try:
|
|
223
|
+
result = _poll_cli_session(session_id)
|
|
224
|
+
|
|
225
|
+
if result["status"] == "completed":
|
|
226
|
+
# Success! Save the new key
|
|
227
|
+
api_key = result["api_key"]
|
|
228
|
+
linked_scans = result.get("linked_scans", 0)
|
|
229
|
+
user_email = result.get("user_email", "")
|
|
230
|
+
|
|
231
|
+
# Save to credentials
|
|
232
|
+
_save_new_credentials(store, api_key, credentials)
|
|
233
|
+
|
|
234
|
+
# Show success
|
|
235
|
+
console.print()
|
|
236
|
+
console.print("[bold green]CLI Connected Successfully![/bold green]")
|
|
237
|
+
console.print()
|
|
238
|
+
|
|
239
|
+
# Display info table
|
|
240
|
+
table = Table(show_header=False, box=None, padding=(0, 2))
|
|
241
|
+
table.add_column("Label", style="dim")
|
|
242
|
+
table.add_column("Value")
|
|
243
|
+
|
|
244
|
+
masked_key = f"{api_key[:15]}...{api_key[-4:]}"
|
|
245
|
+
table.add_row("API Key:", f"[green]{masked_key}[/green]")
|
|
246
|
+
if user_email:
|
|
247
|
+
table.add_row("Account:", user_email)
|
|
248
|
+
if linked_scans > 0:
|
|
249
|
+
table.add_row("Scans Linked:", f"[green]{linked_scans:,}[/green]")
|
|
250
|
+
|
|
251
|
+
console.print(table)
|
|
252
|
+
console.print()
|
|
253
|
+
console.print(f"[dim]View your dashboard:[/dim] [blue underline]{_get_console_url()}/portal[/blue underline]")
|
|
254
|
+
console.print()
|
|
255
|
+
return
|
|
256
|
+
|
|
257
|
+
elif result["status"] == "expired":
|
|
258
|
+
display_error(
|
|
259
|
+
"Session expired",
|
|
260
|
+
details="Please run `raxe auth` again.",
|
|
261
|
+
)
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
# Still pending, continue polling
|
|
265
|
+
time.sleep(POLL_INTERVAL_SECONDS)
|
|
266
|
+
|
|
267
|
+
except httpx.HTTPError:
|
|
268
|
+
# Network error, retry
|
|
269
|
+
status.update("[yellow]Connection issue, retrying...[/yellow]")
|
|
270
|
+
time.sleep(POLL_INTERVAL_SECONDS)
|
|
271
|
+
except Exception as e:
|
|
272
|
+
# Processing error - don't retry, show actual error
|
|
273
|
+
console.print()
|
|
274
|
+
display_error(
|
|
275
|
+
"Authentication failed",
|
|
276
|
+
details=str(e),
|
|
277
|
+
)
|
|
278
|
+
return
|
|
279
|
+
|
|
280
|
+
# Timeout
|
|
281
|
+
console.print()
|
|
282
|
+
display_error(
|
|
283
|
+
"Authentication timed out",
|
|
284
|
+
details="Please complete the authentication in your browser within 5 minutes.",
|
|
285
|
+
)
|
|
286
|
+
console.print()
|
|
287
|
+
console.print("[dim]You can also set your API key manually:[/dim]")
|
|
288
|
+
console.print("[cyan] raxe config set api_key YOUR_API_KEY[/cyan]")
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _create_cli_session(
|
|
292
|
+
temp_key_id: Optional[str],
|
|
293
|
+
installation_id: Optional[str],
|
|
294
|
+
) -> dict:
|
|
295
|
+
"""Create a CLI auth session on the server.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
temp_key_id: BigQuery-compatible ID of current temp key (if any).
|
|
299
|
+
installation_id: Installation ID for this CLI instance.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Session data containing session_id, connect_url, and events_count.
|
|
303
|
+
|
|
304
|
+
Raises:
|
|
305
|
+
Exception: If session creation fails.
|
|
306
|
+
"""
|
|
307
|
+
with httpx.Client(timeout=10) as client:
|
|
308
|
+
response = client.post(
|
|
309
|
+
_get_cli_session_endpoint(),
|
|
310
|
+
json={
|
|
311
|
+
"temp_key_id": temp_key_id,
|
|
312
|
+
"installation_id": installation_id,
|
|
313
|
+
},
|
|
314
|
+
)
|
|
315
|
+
response.raise_for_status()
|
|
316
|
+
data = response.json()
|
|
317
|
+
|
|
318
|
+
if not data.get("success"):
|
|
319
|
+
raise Exception(data.get("error", "Failed to create session"))
|
|
320
|
+
|
|
321
|
+
return data["data"]
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def _poll_cli_session(session_id: str) -> dict:
|
|
325
|
+
"""Poll for CLI session status.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
session_id: Session ID to check.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
Session status data containing status and optionally api_key.
|
|
332
|
+
|
|
333
|
+
Raises:
|
|
334
|
+
Exception: If polling fails.
|
|
335
|
+
"""
|
|
336
|
+
with httpx.Client(timeout=10) as client:
|
|
337
|
+
response = client.get(f"{_get_cli_session_endpoint()}/{session_id}")
|
|
338
|
+
response.raise_for_status()
|
|
339
|
+
data = response.json()
|
|
340
|
+
|
|
341
|
+
if not data.get("success"):
|
|
342
|
+
raise Exception(data.get("error", "Failed to check session"))
|
|
343
|
+
|
|
344
|
+
return data["data"]
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def _save_new_credentials(
|
|
348
|
+
store, # CredentialStore
|
|
349
|
+
api_key: str,
|
|
350
|
+
old_credentials, # Credentials | None
|
|
351
|
+
) -> None:
|
|
352
|
+
"""Save new API key and send upgrade event.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
store: CredentialStore instance.
|
|
356
|
+
api_key: New API key from authentication.
|
|
357
|
+
old_credentials: Previous credentials (may be None).
|
|
358
|
+
"""
|
|
359
|
+
from raxe.domain.telemetry.events import create_key_upgrade_event
|
|
360
|
+
from raxe.infrastructure.telemetry.credential_store import compute_key_id
|
|
361
|
+
|
|
362
|
+
# Compute key IDs for upgrade event
|
|
363
|
+
old_key_id: Optional[str] = None
|
|
364
|
+
old_key_type = "temp"
|
|
365
|
+
days_on_previous: Optional[int] = None
|
|
366
|
+
|
|
367
|
+
if old_credentials and old_credentials.api_key:
|
|
368
|
+
old_key_id = compute_key_id(old_credentials.api_key)
|
|
369
|
+
if old_credentials.api_key.startswith("raxe_live_"):
|
|
370
|
+
old_key_type = "community"
|
|
371
|
+
elif old_credentials.api_key.startswith("raxe_test_"):
|
|
372
|
+
old_key_type = "test"
|
|
373
|
+
else:
|
|
374
|
+
old_key_type = "temp"
|
|
375
|
+
# Calculate days on previous key
|
|
376
|
+
try:
|
|
377
|
+
created = datetime.fromisoformat(
|
|
378
|
+
old_credentials.created_at.replace("Z", "+00:00")
|
|
379
|
+
)
|
|
380
|
+
now = datetime.now(timezone.utc)
|
|
381
|
+
days_on_previous = (now - created).days
|
|
382
|
+
except (ValueError, TypeError, AttributeError):
|
|
383
|
+
days_on_previous = None
|
|
384
|
+
|
|
385
|
+
new_key_id = compute_key_id(api_key)
|
|
386
|
+
|
|
387
|
+
# Determine new key type
|
|
388
|
+
if api_key.startswith("raxe_live_"):
|
|
389
|
+
new_key_type = "community"
|
|
390
|
+
elif api_key.startswith("raxe_test_"):
|
|
391
|
+
new_key_type = "test"
|
|
392
|
+
else:
|
|
393
|
+
new_key_type = "community" # Default for connected keys
|
|
394
|
+
|
|
395
|
+
# Update credentials file
|
|
396
|
+
store.upgrade_key(api_key, "live" if new_key_type == "community" else "test")
|
|
397
|
+
|
|
398
|
+
# Send upgrade event (fire and forget)
|
|
399
|
+
try:
|
|
400
|
+
from raxe.infrastructure.telemetry.sender import BatchSender
|
|
401
|
+
|
|
402
|
+
# Get config for endpoint
|
|
403
|
+
try:
|
|
404
|
+
from raxe.infrastructure.config.yaml_config import RaxeConfig
|
|
405
|
+
config = RaxeConfig.load()
|
|
406
|
+
endpoint = getattr(config.telemetry, "endpoint", None)
|
|
407
|
+
except Exception:
|
|
408
|
+
endpoint = None
|
|
409
|
+
|
|
410
|
+
if not endpoint:
|
|
411
|
+
endpoint = f"{_get_api_base_url()}/v1/telemetry"
|
|
412
|
+
|
|
413
|
+
# Create upgrade event
|
|
414
|
+
event = create_key_upgrade_event(
|
|
415
|
+
previous_key_type=old_key_type,
|
|
416
|
+
new_key_type=new_key_type,
|
|
417
|
+
previous_key_id=old_key_id,
|
|
418
|
+
new_key_id=new_key_id,
|
|
419
|
+
days_on_previous=days_on_previous,
|
|
420
|
+
conversion_trigger="cli_connect",
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
# Get installation_id for sender
|
|
424
|
+
installation_id = None
|
|
425
|
+
if old_credentials:
|
|
426
|
+
installation_id = old_credentials.installation_id
|
|
427
|
+
|
|
428
|
+
# Send via batch sender - use old_key_id for correlation (preserves temp key_id)
|
|
429
|
+
sender = BatchSender(
|
|
430
|
+
endpoint=endpoint,
|
|
431
|
+
api_key=api_key,
|
|
432
|
+
installation_id=installation_id or "inst_unknown",
|
|
433
|
+
api_key_id=old_key_id, # Correlate upgrade event with temp key_id
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
# Convert event to dict for sending
|
|
437
|
+
from raxe.domain.telemetry.events import event_to_dict
|
|
438
|
+
sender.send_batch([event_to_dict(event)])
|
|
439
|
+
|
|
440
|
+
except Exception:
|
|
441
|
+
pass # Don't fail auth on telemetry error
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
@auth.command("login")
|
|
445
|
+
@handle_cli_error
|
|
446
|
+
def auth_login() -> None:
|
|
447
|
+
"""Open RAXE Console to manage API keys (manual).
|
|
448
|
+
|
|
449
|
+
For automatic CLI connection, use: raxe auth
|
|
450
|
+
|
|
451
|
+
Examples:
|
|
452
|
+
raxe auth login
|
|
453
|
+
"""
|
|
454
|
+
console.print()
|
|
455
|
+
console.print("[cyan]Opening RAXE Console in your browser...[/cyan]")
|
|
456
|
+
console.print()
|
|
457
|
+
|
|
458
|
+
# Open the console URL in default browser
|
|
459
|
+
try:
|
|
460
|
+
webbrowser.open(_get_console_keys_url())
|
|
461
|
+
display_success(f"Opened {_get_console_keys_url()}")
|
|
462
|
+
except Exception as e:
|
|
463
|
+
console.print(f"[yellow]Could not open browser automatically: {e}[/yellow]")
|
|
464
|
+
console.print()
|
|
465
|
+
console.print(f"Please visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
|
|
466
|
+
|
|
467
|
+
console.print()
|
|
468
|
+
console.print("[dim]After creating your API key, configure it with:[/dim]")
|
|
469
|
+
console.print("[cyan] raxe config set api_key YOUR_API_KEY[/cyan]")
|
|
470
|
+
console.print()
|
|
471
|
+
console.print("[dim]Or set the environment variable:[/dim]")
|
|
472
|
+
console.print("[cyan] export RAXE_API_KEY=YOUR_API_KEY[/cyan]")
|
|
473
|
+
console.print()
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
@auth.command("link")
|
|
477
|
+
@click.argument("code")
|
|
478
|
+
@handle_cli_error
|
|
479
|
+
def auth_link(code: str) -> None:
|
|
480
|
+
"""Link CLI to an existing API key using a link code.
|
|
481
|
+
|
|
482
|
+
Get a link code from the RAXE Console by clicking "Link CLI" on any
|
|
483
|
+
API key card. Then run this command with the code.
|
|
484
|
+
|
|
485
|
+
This preserves your CLI's historical telemetry data and links it
|
|
486
|
+
to the selected API key.
|
|
487
|
+
|
|
488
|
+
NOTE: This command requires existing CLI history (from prior usage).
|
|
489
|
+
For first-time setup, use 'raxe auth' instead.
|
|
490
|
+
|
|
491
|
+
Examples:
|
|
492
|
+
raxe auth link ABC123
|
|
493
|
+
raxe link ABC123
|
|
494
|
+
"""
|
|
495
|
+
from rich.prompt import Confirm
|
|
496
|
+
|
|
497
|
+
from raxe.cli.branding import print_logo
|
|
498
|
+
from raxe.infrastructure.telemetry.credential_store import (
|
|
499
|
+
CredentialStore,
|
|
500
|
+
compute_key_id,
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
print_logo(console, compact=True)
|
|
504
|
+
console.print()
|
|
505
|
+
console.print("[bold cyan]Link CLI to API Key[/bold cyan]")
|
|
506
|
+
console.print()
|
|
507
|
+
|
|
508
|
+
# Normalize link code
|
|
509
|
+
normalized_code = code.upper().strip()
|
|
510
|
+
if len(normalized_code) != 6:
|
|
511
|
+
display_error(
|
|
512
|
+
"Invalid link code format",
|
|
513
|
+
details="Link codes are 6 characters. Example: ABC123",
|
|
514
|
+
)
|
|
515
|
+
return
|
|
516
|
+
|
|
517
|
+
# Get current credentials
|
|
518
|
+
store = CredentialStore()
|
|
519
|
+
credentials = store.load()
|
|
520
|
+
temp_key_id: Optional[str] = None
|
|
521
|
+
|
|
522
|
+
# Priority 1: Get key_id from telemetry state (ensures consistency with events)
|
|
523
|
+
temp_key_id = _get_current_key_id_from_telemetry()
|
|
524
|
+
|
|
525
|
+
# Priority 2: Fall back to computing from credentials
|
|
526
|
+
if temp_key_id is None and credentials and credentials.api_key:
|
|
527
|
+
temp_key_id = compute_key_id(credentials.api_key)
|
|
528
|
+
|
|
529
|
+
if credentials and credentials.api_key:
|
|
530
|
+
# Check if already authenticated with a permanent key
|
|
531
|
+
if credentials.api_key.startswith("raxe_live_"):
|
|
532
|
+
masked_key = f"{credentials.api_key[:15]}...{credentials.api_key[-4:]}"
|
|
533
|
+
console.print(f"[green]Already authenticated![/green]")
|
|
534
|
+
console.print(f" API Key: [cyan]{masked_key}[/cyan]")
|
|
535
|
+
console.print()
|
|
536
|
+
|
|
537
|
+
if not Confirm.ask("Replace with a different key?", default=False):
|
|
538
|
+
console.print()
|
|
539
|
+
console.print("[dim]Run [cyan]raxe auth status[/cyan] to see details[/dim]")
|
|
540
|
+
return
|
|
541
|
+
|
|
542
|
+
console.print()
|
|
543
|
+
else:
|
|
544
|
+
console.print(f"[dim]Current key ID: {temp_key_id}[/dim]")
|
|
545
|
+
else:
|
|
546
|
+
# No credentials at all - link code requires existing CLI history
|
|
547
|
+
console.print("[yellow]No CLI history found.[/yellow]")
|
|
548
|
+
console.print()
|
|
549
|
+
console.print("The [cyan]raxe link[/cyan] command is used to link existing CLI history")
|
|
550
|
+
console.print("to an API key you've already created in the Console.")
|
|
551
|
+
console.print()
|
|
552
|
+
console.print("[bold]For first-time setup, use:[/bold]")
|
|
553
|
+
console.print(" [cyan]raxe auth[/cyan] - Connect your CLI to your RAXE account")
|
|
554
|
+
console.print()
|
|
555
|
+
return
|
|
556
|
+
|
|
557
|
+
console.print()
|
|
558
|
+
|
|
559
|
+
# Call the link API
|
|
560
|
+
try:
|
|
561
|
+
with console.status("[cyan]Linking CLI to API key...[/cyan]"):
|
|
562
|
+
result = _link_cli_to_key(normalized_code, temp_key_id)
|
|
563
|
+
|
|
564
|
+
if result.get("success"):
|
|
565
|
+
api_key = result["api_key"]
|
|
566
|
+
key_id = result["key_id"]
|
|
567
|
+
events_count = result.get("events_count", 0)
|
|
568
|
+
message = result.get("message", "")
|
|
569
|
+
|
|
570
|
+
# Save new credentials
|
|
571
|
+
_save_new_credentials(store, api_key, credentials)
|
|
572
|
+
|
|
573
|
+
# Show success
|
|
574
|
+
console.print("[bold green]CLI Linked Successfully![/bold green]")
|
|
575
|
+
console.print()
|
|
576
|
+
|
|
577
|
+
# Display info table
|
|
578
|
+
table = Table(show_header=False, box=None, padding=(0, 2))
|
|
579
|
+
table.add_column("Label", style="dim")
|
|
580
|
+
table.add_column("Value")
|
|
581
|
+
|
|
582
|
+
masked_key = f"{api_key[:15]}...{api_key[-4:]}"
|
|
583
|
+
table.add_row("API Key:", f"[green]{masked_key}[/green]")
|
|
584
|
+
table.add_row("Key ID:", key_id)
|
|
585
|
+
if events_count > 0:
|
|
586
|
+
table.add_row("Events Linked:", f"[green]{events_count:,}[/green]")
|
|
587
|
+
|
|
588
|
+
console.print(table)
|
|
589
|
+
console.print()
|
|
590
|
+
if message:
|
|
591
|
+
console.print(f"[dim]{message}[/dim]")
|
|
592
|
+
console.print()
|
|
593
|
+
console.print(f"[dim]View your dashboard:[/dim] [blue underline]{_get_console_url()}/portal[/blue underline]")
|
|
594
|
+
console.print()
|
|
595
|
+
else:
|
|
596
|
+
display_error(
|
|
597
|
+
"Link failed",
|
|
598
|
+
details=result.get("error", {}).get("message", "Unknown error"),
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
except Exception as e:
|
|
602
|
+
display_error(
|
|
603
|
+
"Failed to link CLI",
|
|
604
|
+
details=str(e),
|
|
605
|
+
)
|
|
606
|
+
console.print()
|
|
607
|
+
console.print("[dim]Make sure the link code is correct and hasn't expired.[/dim]")
|
|
608
|
+
console.print("[dim]Get a new code from the RAXE Console: [/dim]")
|
|
609
|
+
console.print(f"[blue underline]{_get_console_url()}/api-keys[/blue underline]")
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
def _link_cli_to_key(code: str, temp_key_id: Optional[str]) -> dict:
|
|
613
|
+
"""Call the CLI link API to link temp key data to an existing key.
|
|
614
|
+
|
|
615
|
+
Args:
|
|
616
|
+
code: The 6-character link code from Console.
|
|
617
|
+
temp_key_id: The current temp key ID (if any).
|
|
618
|
+
|
|
619
|
+
Returns:
|
|
620
|
+
Response data containing success, api_key, key_id, events_count, message.
|
|
621
|
+
|
|
622
|
+
Raises:
|
|
623
|
+
Exception: If the link fails.
|
|
624
|
+
"""
|
|
625
|
+
with httpx.Client(timeout=30) as client:
|
|
626
|
+
response = client.post(
|
|
627
|
+
_get_cli_link_endpoint(),
|
|
628
|
+
json={
|
|
629
|
+
"code": code,
|
|
630
|
+
"temp_key_id": temp_key_id or "",
|
|
631
|
+
},
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
data = response.json()
|
|
635
|
+
|
|
636
|
+
# Handle HTTP errors
|
|
637
|
+
if response.status_code != 200:
|
|
638
|
+
if not data.get("success"):
|
|
639
|
+
return {
|
|
640
|
+
"success": False,
|
|
641
|
+
"error": data.get("error", {"message": f"HTTP {response.status_code}"}),
|
|
642
|
+
}
|
|
643
|
+
response.raise_for_status()
|
|
644
|
+
|
|
645
|
+
if not data.get("success"):
|
|
646
|
+
return {
|
|
647
|
+
"success": False,
|
|
648
|
+
"error": data.get("error", {"message": "Unknown error"}),
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
return data.get("data", {})
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
@auth.command("status")
|
|
655
|
+
@click.option(
|
|
656
|
+
"--remote",
|
|
657
|
+
"-r",
|
|
658
|
+
is_flag=True,
|
|
659
|
+
default=False,
|
|
660
|
+
help="Check status with remote server (requires network)",
|
|
661
|
+
)
|
|
662
|
+
@handle_cli_error
|
|
663
|
+
def auth_status(remote: bool) -> None:
|
|
664
|
+
"""Show current authentication status.
|
|
665
|
+
|
|
666
|
+
Displays information about the configured API key:
|
|
667
|
+
- Whether an API key is configured
|
|
668
|
+
- Key type (temporary, live, test)
|
|
669
|
+
- Key tier (if determinable)
|
|
670
|
+
|
|
671
|
+
Use --remote to fetch real-time information from the server including:
|
|
672
|
+
- Actual days remaining (server-calculated)
|
|
673
|
+
- Events sent today / remaining
|
|
674
|
+
- Rate limits
|
|
675
|
+
- Feature flags
|
|
676
|
+
|
|
677
|
+
Examples:
|
|
678
|
+
raxe auth status
|
|
679
|
+
raxe auth status --remote
|
|
680
|
+
raxe auth status -r
|
|
681
|
+
"""
|
|
682
|
+
import os
|
|
683
|
+
|
|
684
|
+
from raxe.cli.branding import print_logo
|
|
685
|
+
from raxe.infrastructure.config.yaml_config import RaxeConfig
|
|
686
|
+
from raxe.infrastructure.telemetry.credential_store import CredentialStore
|
|
687
|
+
|
|
688
|
+
print_logo(console, compact=True)
|
|
689
|
+
console.print()
|
|
690
|
+
|
|
691
|
+
# Load API key with fallback chain:
|
|
692
|
+
# 1. RAXE_API_KEY environment variable (highest priority)
|
|
693
|
+
# 2. config.yaml (explicit user config)
|
|
694
|
+
# 3. credentials.json (auto-generated from raxe auth)
|
|
695
|
+
api_key = None
|
|
696
|
+
api_key_source = None
|
|
697
|
+
|
|
698
|
+
# Priority 1: Environment variable
|
|
699
|
+
env_api_key = os.environ.get("RAXE_API_KEY", "").strip()
|
|
700
|
+
if env_api_key:
|
|
701
|
+
api_key = env_api_key
|
|
702
|
+
api_key_source = "environment"
|
|
703
|
+
|
|
704
|
+
# Priority 2: config.yaml
|
|
705
|
+
if not api_key:
|
|
706
|
+
try:
|
|
707
|
+
config = RaxeConfig.load()
|
|
708
|
+
if config.core.api_key:
|
|
709
|
+
api_key = config.core.api_key
|
|
710
|
+
api_key_source = "config"
|
|
711
|
+
except Exception:
|
|
712
|
+
pass
|
|
713
|
+
|
|
714
|
+
# Priority 3: credentials.json
|
|
715
|
+
if not api_key:
|
|
716
|
+
try:
|
|
717
|
+
store = CredentialStore()
|
|
718
|
+
credentials = store.load()
|
|
719
|
+
if credentials:
|
|
720
|
+
api_key = credentials.api_key
|
|
721
|
+
api_key_source = "credentials"
|
|
722
|
+
except Exception:
|
|
723
|
+
pass
|
|
724
|
+
|
|
725
|
+
if not api_key:
|
|
726
|
+
console.print("[bold cyan]Authentication Status[/bold cyan]")
|
|
727
|
+
console.print()
|
|
728
|
+
console.print("[yellow]No API key configured[/yellow]")
|
|
729
|
+
console.print()
|
|
730
|
+
console.print("To get an API key:")
|
|
731
|
+
console.print(" 1. Run: [cyan]raxe auth[/cyan]")
|
|
732
|
+
console.print(" 2. Complete authentication in your browser")
|
|
733
|
+
console.print()
|
|
734
|
+
console.print("Or manually:")
|
|
735
|
+
console.print(" 1. Run: [cyan]raxe auth login[/cyan]")
|
|
736
|
+
console.print(" 2. Create a key in the RAXE Console")
|
|
737
|
+
console.print(" 3. Configure it: [cyan]raxe config set api_key YOUR_KEY[/cyan]")
|
|
738
|
+
console.print()
|
|
739
|
+
console.print(f"Or visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
|
|
740
|
+
console.print()
|
|
741
|
+
return
|
|
742
|
+
|
|
743
|
+
if remote:
|
|
744
|
+
_display_remote_status(api_key, config)
|
|
745
|
+
else:
|
|
746
|
+
_display_local_status(api_key, api_key_source)
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
def _display_local_status(api_key: str, source: str | None = None) -> None:
|
|
750
|
+
"""Display local-only authentication status.
|
|
751
|
+
|
|
752
|
+
Args:
|
|
753
|
+
api_key: The configured API key
|
|
754
|
+
source: Where the key was loaded from (environment, config, credentials)
|
|
755
|
+
"""
|
|
756
|
+
console.print("[bold cyan]Authentication Status[/bold cyan]")
|
|
757
|
+
console.print()
|
|
758
|
+
|
|
759
|
+
# Determine key type from prefix
|
|
760
|
+
if api_key.startswith("raxe_live_"):
|
|
761
|
+
key_type = "Live (production)"
|
|
762
|
+
key_style = "green"
|
|
763
|
+
elif api_key.startswith("raxe_test_"):
|
|
764
|
+
key_type = "Test"
|
|
765
|
+
key_style = "yellow"
|
|
766
|
+
elif api_key.startswith("raxe_temp_"):
|
|
767
|
+
key_type = "Temporary (14-day expiry)"
|
|
768
|
+
key_style = "yellow"
|
|
769
|
+
else:
|
|
770
|
+
key_type = "Unknown format"
|
|
771
|
+
key_style = "red"
|
|
772
|
+
|
|
773
|
+
# Mask the key for display
|
|
774
|
+
if len(api_key) > 15:
|
|
775
|
+
masked_key = f"{api_key[:12]}...{api_key[-4:]}"
|
|
776
|
+
else:
|
|
777
|
+
masked_key = "***"
|
|
778
|
+
|
|
779
|
+
console.print(f" API Key: [{key_style}]{masked_key}[/{key_style}]")
|
|
780
|
+
console.print(f" Type: [{key_style}]{key_type}[/{key_style}]")
|
|
781
|
+
|
|
782
|
+
# Show source of the key
|
|
783
|
+
if source:
|
|
784
|
+
source_display = {
|
|
785
|
+
"environment": "RAXE_API_KEY env var",
|
|
786
|
+
"config": "~/.raxe/config.yaml",
|
|
787
|
+
"credentials": "~/.raxe/credentials.json",
|
|
788
|
+
}.get(source, source)
|
|
789
|
+
console.print(f" Source: [dim]{source_display}[/dim]")
|
|
790
|
+
|
|
791
|
+
# For temporary keys, show days remaining from credentials file
|
|
792
|
+
if api_key.startswith("raxe_temp_"):
|
|
793
|
+
_display_temp_key_expiry()
|
|
794
|
+
console.print()
|
|
795
|
+
console.print(f"Get a permanent key at: [blue underline]{_get_console_keys_url()}[/blue underline]")
|
|
796
|
+
console.print("Or run: [cyan]raxe auth[/cyan]")
|
|
797
|
+
|
|
798
|
+
console.print()
|
|
799
|
+
console.print("[dim]Use --remote flag for real-time server information[/dim]")
|
|
800
|
+
console.print()
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
def _display_temp_key_expiry() -> None:
|
|
804
|
+
"""Display days remaining for temporary key from credentials file.
|
|
805
|
+
|
|
806
|
+
Reads the credentials file to get the expires_at field and
|
|
807
|
+
calculates the remaining days until expiry.
|
|
808
|
+
"""
|
|
809
|
+
try:
|
|
810
|
+
from raxe.infrastructure.telemetry.credential_store import CredentialStore
|
|
811
|
+
|
|
812
|
+
store = CredentialStore()
|
|
813
|
+
credentials = store.load()
|
|
814
|
+
|
|
815
|
+
if credentials is None or not credentials.is_temporary():
|
|
816
|
+
console.print()
|
|
817
|
+
console.print("[yellow]Temporary keys expire after 14 days.[/yellow]")
|
|
818
|
+
return
|
|
819
|
+
|
|
820
|
+
days_remaining = credentials.days_until_expiry()
|
|
821
|
+
|
|
822
|
+
if days_remaining is None:
|
|
823
|
+
console.print()
|
|
824
|
+
console.print("[yellow]Temporary keys expire after 14 days.[/yellow]")
|
|
825
|
+
return
|
|
826
|
+
|
|
827
|
+
console.print()
|
|
828
|
+
|
|
829
|
+
if days_remaining <= 0:
|
|
830
|
+
console.print("[red bold] Expiry: EXPIRED[/red bold]")
|
|
831
|
+
elif days_remaining == 1:
|
|
832
|
+
console.print("[red bold] Expiry: Expires TODAY[/red bold]")
|
|
833
|
+
elif days_remaining <= 3:
|
|
834
|
+
console.print(f"[red] Expiry: {days_remaining} days remaining[/red]")
|
|
835
|
+
elif days_remaining <= 7:
|
|
836
|
+
console.print(f"[yellow] Expiry: {days_remaining} days remaining[/yellow]")
|
|
837
|
+
else:
|
|
838
|
+
console.print(f"[green] Expiry: {days_remaining} days remaining[/green]")
|
|
839
|
+
|
|
840
|
+
except Exception:
|
|
841
|
+
# Fallback to generic message if we can't read credentials
|
|
842
|
+
console.print()
|
|
843
|
+
console.print("[yellow]Temporary keys expire after 14 days.[/yellow]")
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
def _display_remote_status(api_key: str, config) -> None:
|
|
847
|
+
"""Display authentication status from remote server.
|
|
848
|
+
|
|
849
|
+
Makes a request to the /v1/health endpoint to get real-time
|
|
850
|
+
information about the API key.
|
|
851
|
+
|
|
852
|
+
Args:
|
|
853
|
+
api_key: The configured API key
|
|
854
|
+
config: The RaxeConfig object
|
|
855
|
+
"""
|
|
856
|
+
from raxe.infrastructure.telemetry.health_client import (
|
|
857
|
+
AuthenticationError,
|
|
858
|
+
HealthCheckError,
|
|
859
|
+
NetworkError,
|
|
860
|
+
TimeoutError,
|
|
861
|
+
check_health,
|
|
862
|
+
)
|
|
863
|
+
|
|
864
|
+
console.print("[bold cyan]Authentication Status (Remote)[/bold cyan]")
|
|
865
|
+
console.print()
|
|
866
|
+
|
|
867
|
+
# Mask the key for display
|
|
868
|
+
if len(api_key) > 15:
|
|
869
|
+
masked_key = f"{api_key[:12]}...{api_key[-4:]}"
|
|
870
|
+
else:
|
|
871
|
+
masked_key = "***"
|
|
872
|
+
|
|
873
|
+
# Get endpoint from config or use default
|
|
874
|
+
endpoint = getattr(config.telemetry, "endpoint", None)
|
|
875
|
+
if endpoint:
|
|
876
|
+
# Extract base URL from telemetry endpoint
|
|
877
|
+
# e.g., "https://api.raxe.ai/v1/telemetry" -> "https://api.raxe.ai"
|
|
878
|
+
if endpoint.endswith("/v1/telemetry"):
|
|
879
|
+
endpoint = endpoint.rsplit("/v1/telemetry", 1)[0]
|
|
880
|
+
|
|
881
|
+
try:
|
|
882
|
+
# Show spinner while fetching
|
|
883
|
+
with console.status("[cyan]Fetching status from server...[/cyan]"):
|
|
884
|
+
if endpoint:
|
|
885
|
+
response = check_health(api_key, endpoint=endpoint)
|
|
886
|
+
else:
|
|
887
|
+
response = check_health(api_key)
|
|
888
|
+
|
|
889
|
+
# Display key info
|
|
890
|
+
_display_key_info_table(masked_key, response)
|
|
891
|
+
|
|
892
|
+
except AuthenticationError as e:
|
|
893
|
+
display_error(
|
|
894
|
+
"Invalid or expired API key",
|
|
895
|
+
details=str(e),
|
|
896
|
+
)
|
|
897
|
+
console.print()
|
|
898
|
+
console.print(f"Get a new key at: [blue underline]{_get_console_keys_url()}[/blue underline]")
|
|
899
|
+
console.print("Or run: [cyan]raxe auth[/cyan]")
|
|
900
|
+
console.print()
|
|
901
|
+
|
|
902
|
+
except NetworkError:
|
|
903
|
+
display_error(
|
|
904
|
+
"Could not reach server",
|
|
905
|
+
details="Check your network connection and try again.",
|
|
906
|
+
)
|
|
907
|
+
console.print()
|
|
908
|
+
console.print("[dim]Showing local status instead:[/dim]")
|
|
909
|
+
console.print()
|
|
910
|
+
_display_local_status(api_key)
|
|
911
|
+
|
|
912
|
+
except TimeoutError:
|
|
913
|
+
display_error(
|
|
914
|
+
"Server timeout",
|
|
915
|
+
details="The server took too long to respond. Please try again.",
|
|
916
|
+
)
|
|
917
|
+
console.print()
|
|
918
|
+
console.print("[dim]Showing local status instead:[/dim]")
|
|
919
|
+
console.print()
|
|
920
|
+
_display_local_status(api_key)
|
|
921
|
+
|
|
922
|
+
except HealthCheckError as e:
|
|
923
|
+
display_error(
|
|
924
|
+
"Health check failed",
|
|
925
|
+
details=str(e),
|
|
926
|
+
)
|
|
927
|
+
console.print()
|
|
928
|
+
console.print("[dim]Showing local status instead:[/dim]")
|
|
929
|
+
console.print()
|
|
930
|
+
_display_local_status(api_key)
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
def _display_key_info_table(masked_key: str, response) -> None:
|
|
934
|
+
"""Display formatted key information table.
|
|
935
|
+
|
|
936
|
+
Args:
|
|
937
|
+
masked_key: Masked API key for display
|
|
938
|
+
response: HealthResponse from server
|
|
939
|
+
"""
|
|
940
|
+
# Determine key type display
|
|
941
|
+
key_type_display = response.key_type.capitalize()
|
|
942
|
+
if response.key_type == "temp":
|
|
943
|
+
key_type_display = "Temporary"
|
|
944
|
+
elif response.key_type == "live":
|
|
945
|
+
key_type_display = "Live (production)"
|
|
946
|
+
|
|
947
|
+
# Key type style
|
|
948
|
+
if response.key_type == "live":
|
|
949
|
+
key_style = "green"
|
|
950
|
+
elif response.key_type in ("test", "temp"):
|
|
951
|
+
key_style = "yellow"
|
|
952
|
+
else:
|
|
953
|
+
key_style = "white"
|
|
954
|
+
|
|
955
|
+
# Create main info table
|
|
956
|
+
table = Table(show_header=False, box=None, padding=(0, 2))
|
|
957
|
+
table.add_column("Label", style="dim")
|
|
958
|
+
table.add_column("Value")
|
|
959
|
+
|
|
960
|
+
table.add_row("API Key:", f"[{key_style}]{masked_key}[/{key_style}]")
|
|
961
|
+
table.add_row("Type:", f"[{key_style}]{key_type_display}[/{key_style}]")
|
|
962
|
+
table.add_row("Tier:", response.tier.capitalize())
|
|
963
|
+
|
|
964
|
+
console.print(table)
|
|
965
|
+
console.print()
|
|
966
|
+
|
|
967
|
+
# Trial status section (for temp keys)
|
|
968
|
+
if response.trial_status and response.trial_status.is_trial:
|
|
969
|
+
console.print("[bold]Trial Status:[/bold]")
|
|
970
|
+
trial_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
971
|
+
trial_table.add_column("Label", style="dim")
|
|
972
|
+
trial_table.add_column("Value")
|
|
973
|
+
|
|
974
|
+
days = response.days_remaining
|
|
975
|
+
if days is not None:
|
|
976
|
+
if days <= 3:
|
|
977
|
+
days_style = "red bold"
|
|
978
|
+
elif days <= 7:
|
|
979
|
+
days_style = "yellow"
|
|
980
|
+
else:
|
|
981
|
+
days_style = "green"
|
|
982
|
+
trial_table.add_row("Days Remaining:", f"[{days_style}]{days}[/{days_style}]")
|
|
983
|
+
|
|
984
|
+
if response.trial_status.scans_during_trial > 0:
|
|
985
|
+
trial_table.add_row(
|
|
986
|
+
"Scans During Trial:",
|
|
987
|
+
f"{response.trial_status.scans_during_trial:,}",
|
|
988
|
+
)
|
|
989
|
+
if response.trial_status.threats_detected_during_trial > 0:
|
|
990
|
+
trial_table.add_row(
|
|
991
|
+
"Threats Detected:",
|
|
992
|
+
f"{response.trial_status.threats_detected_during_trial:,}",
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
console.print(trial_table)
|
|
996
|
+
console.print()
|
|
997
|
+
|
|
998
|
+
# Usage section
|
|
999
|
+
console.print("[bold]Usage Today:[/bold]")
|
|
1000
|
+
usage_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
1001
|
+
usage_table.add_column("Label", style="dim")
|
|
1002
|
+
usage_table.add_column("Value")
|
|
1003
|
+
|
|
1004
|
+
usage_table.add_row("Events Sent:", f"{response.events_today:,}")
|
|
1005
|
+
usage_table.add_row("Events Remaining:", f"{response.events_remaining:,}")
|
|
1006
|
+
|
|
1007
|
+
console.print(usage_table)
|
|
1008
|
+
console.print()
|
|
1009
|
+
|
|
1010
|
+
# Rate limits section
|
|
1011
|
+
console.print("[bold]Rate Limits:[/bold]")
|
|
1012
|
+
rate_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
1013
|
+
rate_table.add_column("Label", style="dim")
|
|
1014
|
+
rate_table.add_column("Value")
|
|
1015
|
+
|
|
1016
|
+
rate_table.add_row("Requests/min:", f"{response.rate_limit_rpm:,}")
|
|
1017
|
+
rate_table.add_row("Events/day:", f"{response.rate_limit_daily:,}")
|
|
1018
|
+
|
|
1019
|
+
console.print(rate_table)
|
|
1020
|
+
console.print()
|
|
1021
|
+
|
|
1022
|
+
# Features section
|
|
1023
|
+
console.print("[bold]Features:[/bold]")
|
|
1024
|
+
features_table = Table(show_header=False, box=None, padding=(0, 2))
|
|
1025
|
+
features_table.add_column("Label", style="dim")
|
|
1026
|
+
features_table.add_column("Value")
|
|
1027
|
+
|
|
1028
|
+
telemetry_status = "[green]Yes[/green]" if response.can_disable_telemetry else "[yellow]No[/yellow]"
|
|
1029
|
+
offline_status = "[green]Yes[/green]" if response.offline_mode else "[yellow]No[/yellow]"
|
|
1030
|
+
|
|
1031
|
+
features_table.add_row("Can Disable Telemetry:", telemetry_status)
|
|
1032
|
+
features_table.add_row("Offline Mode:", offline_status)
|
|
1033
|
+
|
|
1034
|
+
console.print(features_table)
|
|
1035
|
+
console.print()
|
|
1036
|
+
|
|
1037
|
+
# Upgrade prompt for temp/community keys
|
|
1038
|
+
if response.key_type == "temp" or response.tier in ("temporary", "community"):
|
|
1039
|
+
console.print("[dim]" + "-" * 50 + "[/dim]")
|
|
1040
|
+
console.print()
|
|
1041
|
+
if response.key_type == "temp":
|
|
1042
|
+
console.print("[yellow]Upgrade to a permanent key for uninterrupted service.[/yellow]")
|
|
1043
|
+
else:
|
|
1044
|
+
console.print("[cyan]Upgrade to Pro for higher limits and more features.[/cyan]")
|
|
1045
|
+
console.print(f"Visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
|
|
1046
|
+
console.print("Or run: [cyan]raxe auth[/cyan]")
|
|
1047
|
+
console.print()
|