praetorian-cli 2.4.8__tar.gz → 2.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {praetorian_cli-2.4.8/praetorian_cli.egg-info → praetorian_cli-2.6.0}/PKG-INFO +262 -6
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/README.md +258 -5
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/access.py +125 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/add.py +148 -7
- praetorian_cli-2.6.0/praetorian_cli/handlers/aegis.py +387 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/agent.py +189 -10
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/chariot.py +8 -1
- praetorian_cli-2.6.0/praetorian_cli/handlers/cli_decorators.py +658 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/configure.py +3 -1
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/delete.py +5 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/get.py +5 -2
- praetorian_cli-2.6.0/praetorian_cli/handlers/hunt.py +1017 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/list.py +2 -1
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/run.py +73 -67
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/ssh_utils.py +22 -29
- praetorian_cli-2.6.0/praetorian_cli/handlers/test.py +202 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/update.py +32 -3
- praetorian_cli-2.6.0/praetorian_cli/handlers/vm.py +261 -0
- praetorian_cli-2.6.0/praetorian_cli/handlers/vm_proxy.py +120 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/main.py +54 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/chariot.py +16 -6
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/account_discovery.py +181 -20
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/accounts.py +19 -1
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/aegis.py +360 -29
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/agents.py +90 -6
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/assets.py +82 -1
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/capabilities.py +63 -3
- praetorian_cli-2.6.0/praetorian_cli/sdk/entities/conversations.py +364 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/credentials.py +134 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/entities/endpoint_executions.py +238 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/entities/engineer_vm.py +68 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/files.py +77 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/entities/hunts.py +463 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/jobs.py +29 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/preseeds.py +3 -3
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/search.py +22 -4
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/seeds.py +9 -7
- praetorian_cli-2.6.0/praetorian_cli/sdk/exceptions.py +63 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/keychain.py +357 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/mcp_server.py +30 -8
- praetorian_cli-2.6.0/praetorian_cli/sdk/model/aegis.py +319 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/model/query.py +19 -3
- praetorian_cli-2.6.0/praetorian_cli/sdk/model/vm.py +21 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_access_github.py +201 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_account.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_add_file_cli.py +128 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_aegis_endpoint_live.py +546 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_aegis_management_users.py +97 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_aegis_network_policy.py +259 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_aegis_tunnel.py +99 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_aegis_v2_enrollment.py +202 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_agent.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_agent_interactions.py +220 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_asset.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_async_http.py +210 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_attribute.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_capabilities.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_cli_errors.py +802 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_configuration.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_conversation.py +4 -3
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_conversation_approval_surfaces.py +620 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_conversation_interactions.py +317 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_credentials.py +146 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_definition.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_endpoint_approvals.py +430 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_endpoint_execution_cli.py +171 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_endpoint_executions.py +264 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_endpoint_network_policy.py +79 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_endpoint_status.py +164 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_engineer_vm.py +183 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_entity_resolution_cli.py +75 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_entity_resolver.py +197 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_file.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_file_verified_download.py +175 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_all_surface_cli.py +615 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_chat.py +212 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_chat_live.py +591 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_data.py +95 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_internal_cli.py +892 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_launch.py +227 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_memory_browser.py +269 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_open.py +855 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_overview.py +210 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_scope_selector.py +306 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunt_workflows.py +185 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_hunts_internal.py +535 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_job.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_key.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_keychain.py +321 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_keychain_cache.py +50 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_local_runner.py +1 -1
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_mcp.py +243 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_my_by_raw_query.py +7 -7
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_preseed.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_risk.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_run_cli.py +81 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_sdk_exceptions.py +564 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_search.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_seed.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_setting.py +3 -2
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_terminal.py +16 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_test_handler.py +560 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_test_target.py +369 -0
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/test_update_check.py +2063 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_webhook.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_webpage.py +3 -2
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_z_cli.py +20 -6
- praetorian_cli-2.6.0/praetorian_cli/sdk/test/ui_mocks.py +444 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/utils.py +33 -3
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/cp.py +4 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/enrollment.py +230 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/help.py +40 -5
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/hunt.py +1254 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/info.py +22 -4
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/job.py +85 -57
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/job_helpers.py +5 -8
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/job_v2.py +584 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/network_policy.py +561 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/proxy.py +4 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/schedule.py +4 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/set.py +109 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/ssh.py +7 -3
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/tunnel.py +260 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/aegis/commands/user.py +146 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/menu.py +178 -20
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/utils.py +80 -17
- praetorian_cli-2.6.0/praetorian_cli/ui/async_http.py +244 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/context.py +26 -18
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/marcus.py +128 -4
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/tools.py +54 -39
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/console.py +12 -17
- praetorian_cli-2.6.0/praetorian_cli/ui/conversation/approvals.py +405 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/conversation/endpoint_status.py +124 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/conversation/textual_chat.py +1169 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/entity_resolver.py +197 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/entity_selector.py +608 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_chat.py +617 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_chat_live.py +1147 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_data.py +214 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_defaults.py +35 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_format.py +54 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_launch.py +684 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_memory.py +753 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_open.py +1331 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_overview.py +326 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/hunt_workflows.py +856 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/terminal.py +11 -0
- praetorian_cli-2.6.0/praetorian_cli/ui/textual_refresh.py +96 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0/praetorian_cli.egg-info}/PKG-INFO +262 -6
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli.egg-info/SOURCES.txt +71 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli.egg-info/requires.txt +3 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/setup.cfg +4 -1
- praetorian_cli-2.4.8/praetorian_cli/handlers/aegis.py +0 -171
- praetorian_cli-2.4.8/praetorian_cli/handlers/cli_decorators.py +0 -83
- praetorian_cli-2.4.8/praetorian_cli/handlers/test.py +0 -29
- praetorian_cli-2.4.8/praetorian_cli/sdk/entities/conversations.py +0 -107
- praetorian_cli-2.4.8/praetorian_cli/sdk/keychain.py +0 -200
- praetorian_cli-2.4.8/praetorian_cli/sdk/model/aegis.py +0 -156
- praetorian_cli-2.4.8/praetorian_cli/sdk/test/test_mcp.py +0 -28
- praetorian_cli-2.4.8/praetorian_cli/sdk/test/ui_mocks.py +0 -214
- praetorian_cli-2.4.8/praetorian_cli/ui/aegis/commands/set.py +0 -65
- praetorian_cli-2.4.8/praetorian_cli/ui/conversation/textual_chat.py +0 -622
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/LICENSE +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/MANIFEST.in +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/critfinder.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/engagement.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/enrich.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/export.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/find.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/imports.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/link.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/query.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/report.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/script.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/search.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/unlink.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/handlers/utils.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/runners/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/runners/local.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/scripts/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/scripts/commands/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/scripts/commands/nmap-example.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/scripts/utils.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/ad.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/attributes.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/configurations.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/definitions.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/integrations.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/keys.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/reports.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/risks.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/scanners.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/schedules.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/schema.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/settings.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/statistics.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/webhook.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/entities/webpage.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/guard.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/model/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/model/globals.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/model/utils.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/pytest.ini +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_access_aws.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_bulk.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_credential_process.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_export_cli.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_extend.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/sdk/test/test_report.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/account_selector.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/list.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/commands/schedule_helpers.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/constants.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/aegis/theme.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/accounts.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/data.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/reporting.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/commands/search.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/context.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/console/renderer.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli/ui/conversation/__init__.py +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli.egg-info/dependency_links.txt +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli.egg-info/entry_points.txt +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/praetorian_cli.egg-info/top_level.txt +0 -0
- {praetorian_cli-2.4.8 → praetorian_cli-2.6.0}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: praetorian-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0
|
|
4
4
|
Summary: For interacting with the Guard API
|
|
5
5
|
Home-page: https://github.com/praetorian-inc/praetorian-cli
|
|
6
6
|
Author: Praetorian
|
|
@@ -14,17 +14,20 @@ License-File: LICENSE
|
|
|
14
14
|
Requires-Dist: click>=8.1.7
|
|
15
15
|
Requires-Dist: boto3>=1.34.0
|
|
16
16
|
Requires-Dist: requests>=2.31.0
|
|
17
|
+
Requires-Dist: truststore>=0.10.0
|
|
17
18
|
Requires-Dist: pytest>=8.0.2
|
|
18
19
|
Requires-Dist: mcp>=1.12.2
|
|
19
20
|
Requires-Dist: anyio>=3.0.0
|
|
21
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
20
22
|
Requires-Dist: textual>=0.47.0
|
|
21
23
|
Requires-Dist: rich>=13.0.0
|
|
22
24
|
Requires-Dist: prompt_toolkit>=3.0.0
|
|
25
|
+
Requires-Dist: websocket-client>=1.0.0
|
|
23
26
|
Dynamic: license-file
|
|
24
27
|
|
|
25
28
|
# Praetorian CLI and SDK
|
|
26
29
|
|
|
27
|
-
[](https://www.python.org/)
|
|
28
31
|
[](https://pypi.org/project/praetorian-cli/)
|
|
29
32
|
[](LICENSE)
|
|
30
33
|
[](CODE_OF_CONDUCT.md)
|
|
@@ -44,6 +47,12 @@ Dynamic: license-file
|
|
|
44
47
|
- [Signing up](#signing-up)
|
|
45
48
|
- [Authentication](#authentication)
|
|
46
49
|
- [Using the CLI](#using-the-cli)
|
|
50
|
+
- [Aegis v2 endpoints](#aegis-v2-endpoints)
|
|
51
|
+
- [AI Hunts](#ai-hunts)
|
|
52
|
+
- [Aegis endpoint network policy](#aegis-endpoint-network-policy)
|
|
53
|
+
- [Engineer VMs](#engineer-vms)
|
|
54
|
+
- [File upload partitions](#file-upload-partitions)
|
|
55
|
+
- [Update checks](#update-checks)
|
|
47
56
|
- [Operators](#operators)
|
|
48
57
|
- [Interactive Console](#interactive-console)
|
|
49
58
|
- [Install local security tools (optional)](#install-local-security-tools-optional)
|
|
@@ -52,6 +61,7 @@ Dynamic: license-file
|
|
|
52
61
|
- [Developers](#developers)
|
|
53
62
|
- [SDK](#sdk)
|
|
54
63
|
- [Developing external scripts](#developing-external-scripts)
|
|
64
|
+
- [Running the test suite](#running-the-test-suite)
|
|
55
65
|
- [Contributing](#contributing)
|
|
56
66
|
- [Support](#support)
|
|
57
67
|
- [License](#license)
|
|
@@ -69,7 +79,7 @@ offensive security platform.
|
|
|
69
79
|
|
|
70
80
|
## Prerequisites
|
|
71
81
|
|
|
72
|
-
- Python v3.
|
|
82
|
+
- Python v3.10 or above
|
|
73
83
|
- pip v23.0 or above
|
|
74
84
|
|
|
75
85
|
## Installation
|
|
@@ -80,7 +90,7 @@ Install the Python package:
|
|
|
80
90
|
pip install praetorian-cli
|
|
81
91
|
```
|
|
82
92
|
|
|
83
|
-
### Install from source
|
|
93
|
+
### Install from source
|
|
84
94
|
|
|
85
95
|
```zsh
|
|
86
96
|
git clone https://github.com/praetorian-inc/praetorian-cli.git
|
|
@@ -146,6 +156,10 @@ export PRAETORIAN_CLI_API_KEY_ID=your-api-key-id-here
|
|
|
146
156
|
export PRAETORIAN_CLI_API_KEY_SECRET=your-api-key-here
|
|
147
157
|
```
|
|
148
158
|
|
|
159
|
+
The backend API URL and the Cognito emulator endpoint (`aws_endpoint_url`)
|
|
160
|
+
must be HTTPS; the CLI refuses to send credentials over plaintext HTTP. For local development against a loopback endpoint (`localhost`,
|
|
161
|
+
`127.0.0.1`, `::1`), set `PRAETORIAN_CLI_ALLOW_HTTP_LOOPBACK=1`.
|
|
162
|
+
|
|
149
163
|
For more advanced configuration options or managing access in SSO organizations see
|
|
150
164
|
[the documentation on configuration](https://github.com/praetorian-inc/praetorian-cli/blob/main/docs/configure.md).
|
|
151
165
|
|
|
@@ -174,6 +188,185 @@ To get detailed information about a specific asset, run:
|
|
|
174
188
|
guard --account guard+example@praetorian.com get asset <ASSET_KEY>
|
|
175
189
|
```
|
|
176
190
|
|
|
191
|
+
## Aegis v2 endpoints
|
|
192
|
+
|
|
193
|
+
List Aegis endpoints or open the interactive endpoint console:
|
|
194
|
+
|
|
195
|
+
```zsh
|
|
196
|
+
guard aegis list --details
|
|
197
|
+
guard aegis
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Aegis v2 support includes durable online/offline inventory, enrollment approval,
|
|
201
|
+
endpoint-compatible capability execution, Linux user and Cloudflare tunnel
|
|
202
|
+
management and status diagnostics, endpoint-bound Hunts, host egress policy,
|
|
203
|
+
verified artifact downloads, and explicit session/task/operation cancellation.
|
|
204
|
+
|
|
205
|
+
```zsh
|
|
206
|
+
guard aegis enrollment inspect <USER_CODE>
|
|
207
|
+
guard aegis enrollment approve <USER_CODE>
|
|
208
|
+
guard agent endpoint status <CONVERSATION_ID>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
See [Aegis endpoints](docs/aegis.md) for enrollment, interactive commands,
|
|
212
|
+
endpoint execution, tunnels, users, and policy management.
|
|
213
|
+
|
|
214
|
+
## AI Hunts
|
|
215
|
+
|
|
216
|
+
Launch Hunts across External, Internal, Cloud, Web Application, and LLM Application surfaces:
|
|
217
|
+
|
|
218
|
+
```zsh
|
|
219
|
+
guard hunt launch
|
|
220
|
+
guard hunt launch --scope-mode specific --scope example.com --yes
|
|
221
|
+
guard hunt launch --internal --endpoint <ENDPOINT_ID> \
|
|
222
|
+
--scope 10.20.30.0/24 --confirm-endpoint --yes
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Use `guard hunt open <HUNT_ID>` for the unified Overview, Vulnerabilities,
|
|
226
|
+
Workflow, Log, Memory, Chat, and Approvals interface. Static commands provide
|
|
227
|
+
findings/evidence, finalized logs, memory CRUD, live chat and steering,
|
|
228
|
+
interactions, workflow status, projected cost, and pause/resume/stop/delete
|
|
229
|
+
lifecycle controls.
|
|
230
|
+
|
|
231
|
+
See [AI Hunts](docs/hunts.md) for launch options, scoped credentials, keyboard
|
|
232
|
+
controls, human-in-the-loop (HITL) approvals, and scriptable commands.
|
|
233
|
+
|
|
234
|
+
## Aegis endpoint network policy
|
|
235
|
+
|
|
236
|
+
Aegis v2 endpoint policies restrict egress from every active and future
|
|
237
|
+
workload on an endpoint, including agentic Hunt workloads. View the desired and
|
|
238
|
+
applied revisions, protected gateway/DNS connectivity, built-in rules, and
|
|
239
|
+
custom rules with:
|
|
240
|
+
|
|
241
|
+
```zsh
|
|
242
|
+
guard aegis network-policy show <ENDPOINT_ID>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Add address-wide or TCP-port-specific denies using canonical IP addresses or CIDRs:
|
|
246
|
+
|
|
247
|
+
```zsh
|
|
248
|
+
guard aegis network-policy deny add <ENDPOINT_ID> 10.20.30.0/24
|
|
249
|
+
guard aegis network-policy deny add <ENDPOINT_ID> 198.51.100.7 --tcp-ports 22,443
|
|
250
|
+
guard aegis network-policy deny remove <ENDPOINT_ID> 1
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The remove command accepts either the rule number shown by `show`, or an exact destination plus matching `--tcp-ports`.
|
|
254
|
+
|
|
255
|
+
Guard supplies four built-in rules: `deny-unspecified`, `deny-loopback`,
|
|
256
|
+
`deny-docker-api`, and `deny-control-plane`. They can be removed or restored
|
|
257
|
+
explicitly:
|
|
258
|
+
|
|
259
|
+
```zsh
|
|
260
|
+
guard aegis network-policy default remove <ENDPOINT_ID> deny-loopback
|
|
261
|
+
guard aegis network-policy default restore <ENDPOINT_ID> deny-loopback
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Changes require confirmation unless `--yes` is supplied. Guard rejects
|
|
265
|
+
policies that conflict with protected gateway or DNS connectivity, and
|
|
266
|
+
revisions prevent one operator from silently overwriting another operator's
|
|
267
|
+
changes.
|
|
268
|
+
|
|
269
|
+
The interactive `guard aegis` interface exposes the same operations for the
|
|
270
|
+
selected endpoint through `policy`, `policy default ...`, and `policy deny ...`.
|
|
271
|
+
See [Host egress network policy](docs/aegis.md#host-egress-network-policy) for
|
|
272
|
+
all built-in rules, safety behavior, and SDK access.
|
|
273
|
+
|
|
274
|
+
## Engineer VMs
|
|
275
|
+
|
|
276
|
+
Praetorian engineers can manage ad-hoc cloud workspaces with the `vm` command group:
|
|
277
|
+
|
|
278
|
+
```zsh
|
|
279
|
+
guard vm launch --tier general
|
|
280
|
+
guard vm list
|
|
281
|
+
guard vm ssh <VM_ID>
|
|
282
|
+
guard vm code-server <VM_ID>
|
|
283
|
+
guard vm pause <VM_ID>
|
|
284
|
+
guard vm archive <VM_ID>
|
|
285
|
+
guard vm revive <VM_ID>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
SSH uses an ephemeral keypair and short-lived VM-bound certificate through
|
|
289
|
+
Guard's authenticated gateway. See [Engineer VMs](docs/engineer-vms.md) for
|
|
290
|
+
lifecycle, access, and security details.
|
|
291
|
+
|
|
292
|
+
## File upload partitions
|
|
293
|
+
|
|
294
|
+
Praetorian operators can place an upload in the Praetorian-only partition independently of its destination path:
|
|
295
|
+
|
|
296
|
+
```zsh
|
|
297
|
+
guard add file ./narratives.md \
|
|
298
|
+
--name "reports/narratives.md" \
|
|
299
|
+
--praetorian
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`--praetorian` and `--public` are mutually exclusive. Guard enforces operator authorization server-side; customer users cannot write to the Praetorian partition.
|
|
303
|
+
|
|
304
|
+
## Update checks
|
|
305
|
+
|
|
306
|
+
After a command finishes, the CLI may check PyPI for a newer release of
|
|
307
|
+
`praetorian-cli` and print a three-line upgrade advisory to stderr. The check is
|
|
308
|
+
deliberately quiet and infrequent:
|
|
309
|
+
|
|
310
|
+
- **At most once every 24 hours.** Every attempt is recorded at
|
|
311
|
+
`${XDG_CACHE_HOME:-~/.cache}/praetorian-cli/update-check.json` *before* the
|
|
312
|
+
request is made, so a refresh that fails — offline, DNS, timeout, a malformed
|
|
313
|
+
response — is rate-limited exactly like one that succeeds, and keeps
|
|
314
|
+
advertising the last version it did learn. Between refreshes the check reads
|
|
315
|
+
that file and makes no network request at all — as long as the record is a
|
|
316
|
+
plain file that belongs to you and is no larger than 64 KiB. Anything else at
|
|
317
|
+
that path is ignored as though it were absent, so the next invocation refreshes
|
|
318
|
+
and replaces it rather than trusting what it found. Commands that start at the
|
|
319
|
+
same instant are excluded by a marker file created beside that record, so eight
|
|
320
|
+
concurrent invocations perform one refresh rather than eight — including when
|
|
321
|
+
the request fails instantly, since the attempt is recorded before it is made.
|
|
322
|
+
A process killed mid-refresh leaves the marker behind, which defers the next
|
|
323
|
+
refresh that is actually due rather than permitting an extra one — by up to a
|
|
324
|
+
minute, or up to two if the clock steps backwards in between, since a marker
|
|
325
|
+
counts as held while its age is within a minute in *either* direction. A
|
|
326
|
+
relative `XDG_CACHE_HOME` is
|
|
327
|
+
ignored in favour of `~/.cache`, as the base-directory spec requires —
|
|
328
|
+
honouring it would put a separate cache in every working directory and so
|
|
329
|
+
defeat the limit outright. If the cache directory cannot be written at all (a
|
|
330
|
+
read-only home, one owned by another user, or one reached through a symlink),
|
|
331
|
+
the check does not run: a probe whose rate we cannot limit is one we do not
|
|
332
|
+
send.
|
|
333
|
+
- **Only when a human is watching.** It is skipped unless **both** stdout and
|
|
334
|
+
stderr are a terminal, and skipped when `CI` or `GITHUB_ACTIONS` is set or
|
|
335
|
+
`TERM=dumb`. Piping either stream — `guard list assets | jq` — turns it off.
|
|
336
|
+
A script you launch by hand from your own terminal inherits your terminal, so
|
|
337
|
+
treat the opt-out below, not this gate, as the way to guarantee silence.
|
|
338
|
+
- **Never in place of your command's work.** A command that raises skips the
|
|
339
|
+
check, and a group that is only delegating to a subcommand leaves the check to
|
|
340
|
+
the subcommand that does the work. A command that reports an error but still
|
|
341
|
+
exits `0` is the one case where an advisory can follow a visible error.
|
|
342
|
+
- **Not on the path you run day to day.** The daily refresh passes a 2-second
|
|
343
|
+
timeout to `requests`, which bounds how long the server may go without
|
|
344
|
+
sending data — not total wall-clock, so DNS, TLS, redirects and a slow trickle
|
|
345
|
+
are outside it. Ordinary failures are swallowed and cannot change your exit
|
|
346
|
+
code; `Ctrl-C` and process-control exceptions raised during the check still
|
|
347
|
+
propagate, by design, so that interrupting the CLI always works.
|
|
348
|
+
|
|
349
|
+
### Disabling it
|
|
350
|
+
|
|
351
|
+
```zsh
|
|
352
|
+
export PRAETORIAN_CLI_DISABLE_UPDATE_CHECK=1
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
`1`, `true`, `yes` or `on` (any case). Nothing is read or written — no request,
|
|
356
|
+
no cache file.
|
|
357
|
+
|
|
358
|
+
### Privacy
|
|
359
|
+
|
|
360
|
+
A refresh is an unauthenticated `GET` to `https://pypi.org/pypi/praetorian-cli/json`.
|
|
361
|
+
It sends no account, profile, command, or argument — only what any HTTPS request
|
|
362
|
+
inherently reveals to the server: your IP address and the fact that some
|
|
363
|
+
`praetorian-cli` install asked for the package index at that moment. Because
|
|
364
|
+
every attempt is recorded before it is made and concurrent attempts are
|
|
365
|
+
excluded, that happens at most once per day per user account on the machine —
|
|
366
|
+
several users each get their own cache — so your per-command usage cadence is
|
|
367
|
+
not exposed. If contacting
|
|
368
|
+
pypi.org at all is unacceptable in your environment, set the variable above.
|
|
369
|
+
|
|
177
370
|
# Operators
|
|
178
371
|
|
|
179
372
|
## Interactive Console
|
|
@@ -190,7 +383,9 @@ The console provides:
|
|
|
190
383
|
- **Engagement management** — switch between accounts, view stats (seeds/assets/risks), create customers, manage vaults
|
|
191
384
|
- **Metasploit-style tool selection** — `use <tool>`, `show targets`, `set target`, `execute`
|
|
192
385
|
- **All 141 backend capabilities** — any capability can be selected via `use <name>` or `use <#>`
|
|
193
|
-
- **Marcus Aurelius AI** — inline queries
|
|
386
|
+
- **Marcus Aurelius AI** — inline queries, supervised multi-agent operations, HITL approvals, and secure credential prompts
|
|
387
|
+
- **Aegis v2 operations** — endpoint inventory, capability execution, tunnels, users, egress policy, and lifecycle controls
|
|
388
|
+
- **AI Hunts** — all-surface launch, unified monitoring, steering, memory, findings, workflows, and approvals
|
|
194
389
|
- **Fulltext search** — `find` for Neo4j graph search across all entity types
|
|
195
390
|
- **Evidence hydration** — `evidence <risk>` fetches all scattered evidence in one view
|
|
196
391
|
- **Report generation** — `report generate` / `report validate`
|
|
@@ -245,12 +440,23 @@ Marcus is Guard's AI operator, accessible from both the CLI and the interactive
|
|
|
245
440
|
guard ask "how many critical risks are there?"
|
|
246
441
|
guard ask "show me all assets with port 22 open" --mode query
|
|
247
442
|
|
|
443
|
+
# Supervised multi-agent operations
|
|
444
|
+
guard agent conversation --mode agent
|
|
445
|
+
|
|
248
446
|
# File analysis and ingestion
|
|
249
447
|
guard marcus read "vault/engagement/sow.pdf"
|
|
250
448
|
guard marcus ingest "vault/nessus-export.csv" --findings
|
|
251
449
|
guard marcus do "generate an executive summary"
|
|
252
450
|
```
|
|
253
451
|
|
|
452
|
+
Agent mode shows named tool and delegated-agent progress. Use `/agents`,
|
|
453
|
+
`/focus`, and `/guide` to navigate and steer the tree; `/stop <id-prefix>` stops
|
|
454
|
+
one branch, while `stop` or Ctrl+X stops Marcus and all correlated work.
|
|
455
|
+
Endpoint approvals and masked one-time credential/MFA prompts are handled in
|
|
456
|
+
the terminal without persisting secret values in conversation history.
|
|
457
|
+
|
|
458
|
+
See [Guard Interactive Console](docs/console.md#supervised-agent-mode) for the complete command set.
|
|
459
|
+
|
|
254
460
|
In the console, Marcus shows live tool execution:
|
|
255
461
|
```
|
|
256
462
|
guard > ask "analyze the top risks"
|
|
@@ -350,7 +556,14 @@ guard.add('asset', dict(name='example.com', dns='example.com'))
|
|
|
350
556
|
The best place to explore the SDK is the code of the CLI, especially
|
|
351
557
|
[the handlers of the CLI](https://github.com/praetorian-inc/praetorian-cli/tree/main/praetorian_cli/handlers)
|
|
352
558
|
|
|
353
|
-
You can inspect the handler code to see how each CLI command is implemented
|
|
559
|
+
You can inspect the handler code to see how each CLI command is implemented
|
|
560
|
+
with the SDK. The 2.6.0 release adds structured APIs under `sdk.aegis`,
|
|
561
|
+
`sdk.hunts`, `sdk.conversations`, `sdk.endpoint_executions`, and
|
|
562
|
+
`sdk.credentials`.
|
|
563
|
+
|
|
564
|
+
For higher-level examples and safety requirements, see
|
|
565
|
+
[Aegis endpoints](docs/aegis.md), [AI Hunts](docs/hunts.md), and
|
|
566
|
+
[Engineer VMs](docs/engineer-vms.md).
|
|
354
567
|
|
|
355
568
|
## Developing external scripts
|
|
356
569
|
|
|
@@ -370,6 +583,49 @@ For developing scripts, you can refer to
|
|
|
370
583
|
this [readme file](https://github.com/praetorian-inc/praetorian-cli/blob/main/docs/script-development.md).
|
|
371
584
|
|
|
372
585
|
|
|
586
|
+
## Running the test suite
|
|
587
|
+
|
|
588
|
+
`guard test` runs the integration suites that ship with the package. **Some of
|
|
589
|
+
those suites create, modify and delete real entities in whatever account the
|
|
590
|
+
selected profile points at**, so the command is gated.
|
|
591
|
+
|
|
592
|
+
Suites are selected with `-s`/`--suite`:
|
|
593
|
+
|
|
594
|
+
| Suite | What it runs | Touches a live account? |
|
|
595
|
+
| --- | --- | --- |
|
|
596
|
+
| `safe` *(default)* | Local, offline unit tests | No |
|
|
597
|
+
| `coherence` | End-to-end entity lifecycle tests | **Yes — creates and deletes assets, risks, settings, configurations** |
|
|
598
|
+
| `cli` | CLI-level integration tests | **Yes — mutating** |
|
|
599
|
+
| `tui` | Terminal UI tests | No |
|
|
600
|
+
|
|
601
|
+
A bare `guard test` runs the `safe` suite only. It executes with a temporary
|
|
602
|
+
`HOME` and with credential environment variables stripped, so it cannot reach
|
|
603
|
+
your real credentials.
|
|
604
|
+
|
|
605
|
+
The mutating suites additionally require:
|
|
606
|
+
|
|
607
|
+
1. **An explicit profile and account.** Both must be given and non-empty —
|
|
608
|
+
`guard --profile <profile> --account <account> test --suite coherence`.
|
|
609
|
+
There is no fallback: an unset or blank value is an error, so the suite can
|
|
610
|
+
never quietly run against a default profile.
|
|
611
|
+
2. **Interactive confirmation.** The command prints the suite, profile, account,
|
|
612
|
+
and whether the suite is live and mutating, then asks you to confirm.
|
|
613
|
+
Declining — or a non-interactive invocation, which cannot confirm — exits
|
|
614
|
+
non-zero without running any test.
|
|
615
|
+
|
|
616
|
+
```zsh
|
|
617
|
+
# Safe by default — no account is touched.
|
|
618
|
+
guard test
|
|
619
|
+
|
|
620
|
+
# Mutating suite: target must be explicit, and you must confirm.
|
|
621
|
+
guard --profile "United States" --account guard+scratch@praetorian.com \
|
|
622
|
+
test --suite coherence
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
Never point a mutating suite at a production account. Use a dedicated scratch
|
|
626
|
+
account whose contents you are willing to lose.
|
|
627
|
+
|
|
628
|
+
|
|
373
629
|
## Contributing
|
|
374
630
|
|
|
375
631
|
We welcome contributions from the community, from scripts, to the core CLI and SDK. To contribute, fork this
|