praetorian-cli 2.2.16__py3-none-any.whl → 2.3.0__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.
@@ -12,7 +12,7 @@ from praetorian_cli.sdk.model.globals import AddRisk, Asset, Seed, Kind
12
12
 
13
13
  @chariot.group()
14
14
  def add():
15
- """ Add an entity to Chariot """
15
+ """ Add an entity to Guard """
16
16
  pass
17
17
 
18
18
 
@@ -27,7 +27,7 @@ def add():
27
27
  def asset(sdk, name, dns, asset_type, status, surface):
28
28
  """ Add an asset
29
29
 
30
- Add an asset to the Chariot database. This command requires a DNS name for the asset.
30
+ Add an asset to the Guard database. This command requires a DNS name for the asset.
31
31
  Optionally, a name can be provided to give the asset more specific information,
32
32
  such as IP address. If no name is provided, the DNS name will be used as the name.
33
33
  The DNS is the group and the name is the specific identifier. This is for legacy reasons.
@@ -55,12 +55,12 @@ def asset(sdk, name, dns, asset_type, status, surface):
55
55
  @add.command()
56
56
  @cli_handler
57
57
  @click.argument('path')
58
- @click.option('-n', '--name', help='The file name in Chariot. Default: the full path of the uploaded file')
58
+ @click.option('-n', '--name', help='The file name in Guard. Default: the full path of the uploaded file')
59
59
  def file(sdk, path, name):
60
60
  """ Upload a file
61
61
 
62
62
  This commands takes the path to a local file and uploads it to the
63
- Chariot file system. The Chariot file system is where the platform
63
+ Guard file system. The Guard file system is where the platform
64
64
  stores proofs of exploit, risk definitions, and other supporting data.
65
65
 
66
66
  User files reside in the "home/" folder. Those files appear in the app
@@ -89,7 +89,7 @@ def definition(sdk, path, name):
89
89
  """ Upload a risk definition
90
90
 
91
91
  This commands takes the path to the local file and uploads it to the
92
- Chariot file system as risk definitions. Risk definitions reside
92
+ Guard file system as risk definitions. Risk definitions reside
93
93
  in the "definitions/" folder in the file system.
94
94
 
95
95
  Risk definitions need to be in the Markdown format.
@@ -141,7 +141,7 @@ def webhook(sdk):
141
141
  def risk(sdk, name, asset, status, comment, capability):
142
142
  """ Add a risk
143
143
 
144
- This command adds a risk to Chariot. A risk must have an associated asset.
144
+ This command adds a risk to Guard. A risk must have an associated asset.
145
145
  The asset is specified by its key, which can be retrieved by listing and
146
146
  searching the assets.
147
147
 
@@ -211,7 +211,7 @@ def attribute(sdk, key, name, value):
211
211
  def seed(sdk, seed_type, status, field_list):
212
212
  """ Add a seed
213
213
 
214
- Add a seed to the Chariot database. Seeds are now assets with special labeling.
214
+ Add a seed to the Guard database. Seeds are now assets with special labeling.
215
215
  You can specify the asset type and provide dynamic fields using --fields.
216
216
 
217
217
  \b
@@ -247,7 +247,7 @@ def seed(sdk, seed_type, status, field_list):
247
247
  def preseed(sdk, type, title, value, status):
248
248
  """ Add a preseed
249
249
 
250
- This command adds a preseed to the Chariot database.
250
+ This command adds a preseed to the Guard database.
251
251
  Preseeds default to ACTIVE and cannot be added as PENDING.
252
252
 
253
253
  \b
@@ -337,7 +337,7 @@ def key(sdk, name, expires):
337
337
  def webpage(sdk, url, parent):
338
338
  """ Add a Webpage
339
339
 
340
- Add a web page to the Chariot database. Webpages can optionally be associated
340
+ Add a web page to the Guard database. Webpages can optionally be associated
341
341
  with a parent WebApplication or exist independently.
342
342
 
343
343
  \b
@@ -29,14 +29,14 @@ def affiliation(sdk, key):
29
29
 
30
30
  @agent.group()
31
31
  def mcp():
32
- """ Chariot's MCP server """
32
+ """ Guard's MCP server """
33
33
  pass
34
34
 
35
35
  @mcp.command()
36
36
  @cli_handler
37
37
  @click.option('--allowed', '-a', type=str, multiple=True, default=['search_by_query', '*_list', '*_get'])
38
38
  def start(sdk, allowed):
39
- """ Starts the Chariot MCP server
39
+ """ Starts the Guard MCP server
40
40
 
41
41
  \b
42
42
  Example usages:
@@ -73,9 +73,9 @@ def tools(sdk, allowed):
73
73
  @agent.command()
74
74
  @cli_handler
75
75
  def conversation(sdk):
76
- """ Interactive conversation with Chariot AI assistant
76
+ """ Interactive conversation with Guard AI assistant
77
77
 
78
- Start an interactive chat session with the Chariot AI assistant.
78
+ Start an interactive chat session with the Guard AI assistant.
79
79
  The AI can help you query security data, understand findings,
80
80
  and provide insights about your attack surface.
81
81
 
@@ -7,7 +7,7 @@ def chariot(click_context):
7
7
  # import done here to avoid circular import errors in praetorian_cli/handlers/cli_decorators.py
8
8
  from praetorian_cli.sdk.chariot import Chariot
9
9
 
10
- """ Command group for interacting with the Chariot product """
10
+ """ Command group for interacting with the Guard product """
11
11
  # Replace the click context (previously a Keychain instance) with a Chariot
12
12
  # instance, after creating it using the Keychain instance.
13
13
  keychain = click_context.obj['keychain']
@@ -7,7 +7,7 @@ from praetorian_cli.sdk.model.globals import Risk
7
7
 
8
8
  @chariot.group()
9
9
  def delete():
10
- """ Delete an entity from Chariot """
10
+ """ Delete an entity from Guard """
11
11
  pass
12
12
 
13
13
 
@@ -106,7 +106,7 @@ def file(chariot, filepath):
106
106
 
107
107
  \b
108
108
  Arguments:
109
- - FILEPATH: The Chariot file path
109
+ - FILEPATH: The Guard file path
110
110
 
111
111
  \b
112
112
  Example usage:
@@ -9,7 +9,7 @@ from praetorian_cli.handlers.utils import print_json
9
9
 
10
10
  @chariot.group()
11
11
  def get():
12
- """ Get entity details from Chariot """
12
+ """ Get entity details from Guard """
13
13
  pass
14
14
 
15
15
 
@@ -319,13 +319,15 @@ def webpage(chariot, key):
319
319
  """
320
320
  print_json(chariot.webpage.get(key))
321
321
 
322
+ @get.command()
323
+ @cli_handler
322
324
  @click.option('-t', '--type', help='Optional specific entity type (e.g., asset, risk, attribute)')
323
325
  @click.option('-d', '--details', is_flag=True, help='Further retrieve the details of the schema')
324
326
  def schema(chariot, type, details):
325
- """ Get Chariot entity schema
327
+ """ Get Guard entity schema
326
328
 
327
329
  \b
328
- Returns the JSON schema for Chariot entities. Optionally filter for a
330
+ Returns the JSON schema for Guard entities. Optionally filter for a
329
331
  specific entity type.
330
332
 
331
333
  \b
@@ -6,7 +6,7 @@ from praetorian_cli.handlers.cli_decorators import cli_handler
6
6
 
7
7
  @chariot.group()
8
8
  def imports():
9
- """ Import data to Chariot """
9
+ """ Import data to Guard """
10
10
  pass
11
11
 
12
12
 
@@ -7,7 +7,7 @@ from praetorian_cli.handlers.utils import render_offset, render_list_results, pa
7
7
 
8
8
  @chariot.group()
9
9
  def list():
10
- """ Get a list of entities from Chariot """
10
+ """ Get a list of entities from Guard """
11
11
  pass
12
12
 
13
13
 
@@ -121,7 +121,7 @@ def jobs(chariot, filter, details, offset, page):
121
121
  def files(chariot, filter, details, offset, page):
122
122
  """ List files
123
123
 
124
- Retrieve and display a list of files in the Chariot file system.
124
+ Retrieve and display a list of files in the Guard file system.
125
125
 
126
126
  \b
127
127
  Example usages:
@@ -16,7 +16,7 @@ from praetorian_cli.sdk.model.globals import Kind
16
16
  @click.option('-desc', '--desc', is_flag=True, default=False, help='Return data in descending order')
17
17
  @click.option('-g', '--global', 'global_', is_flag=True, default=False, help='Use the global data set')
18
18
  def search(chariot, term, count, kind, details, offset, page, desc, global_):
19
- """ Query Chariot for matches or counts using the search syntax
19
+ """ Query Guard for matches or counts using the search syntax
20
20
 
21
21
  \b
22
22
  Search syntax:
@@ -7,7 +7,7 @@ from praetorian_cli.sdk.model.globals import Risk, Seed, Asset
7
7
 
8
8
  @chariot.group()
9
9
  def update():
10
- """ Update an entity in Chariot """
10
+ """ Update an entity in Guard """
11
11
  pass
12
12
 
13
13
 
praetorian_cli/main.py CHANGED
@@ -36,3 +36,26 @@ def main(click_context, profile, account, debug, proxy):
36
36
 
37
37
  main.add_command(chariot)
38
38
  main.add_command(configure)
39
+
40
+
41
+ @click.group()
42
+ @click.option('--profile', default='United States', help='The profile to use in the keychain file', show_default=True)
43
+ @click.option('--account', default=None, help='Assume role into this account')
44
+ @click.option('--debug', is_flag=True, default=False, help='Run the CLI in debug mode')
45
+ @click.option('--proxy', default='', help='The proxy to use in the CLI')
46
+ @click.pass_context
47
+ @click.version_option()
48
+ def guard_main(click_context, profile, account, debug, proxy):
49
+ """Guard CLI - Praetorian's offensive security platform."""
50
+ from praetorian_cli.sdk.chariot import Chariot
51
+ if debug:
52
+ click.echo('Running in debug mode.')
53
+ chariot.is_debug = debug
54
+ click_context.obj = Chariot(Keychain(profile, account), proxy=proxy)
55
+ praetorian_cli.handlers.script.load_dynamic_commands()
56
+
57
+
58
+ # Add all chariot commands to guard_main
59
+ for cmd_name, cmd in chariot.commands.items():
60
+ guard_main.add_command(cmd, cmd_name)
61
+ guard_main.add_command(configure)
@@ -66,11 +66,9 @@ class Chariot:
66
66
 
67
67
  def chariot_request(self, method: str, url: str, headers: dict = {}, **kwargs) -> requests.Response:
68
68
  """
69
- Centralized wrapper around requests.request. Take care of proxy, beta flag, and
69
+ Centralized wrapper around requests.request. Takes care of proxy and
70
70
  supplies the authentication headers
71
71
  """
72
- self.add_beta_url_param(kwargs)
73
-
74
72
  if self.proxy:
75
73
  kwargs['proxies'] = {'http': self.proxy, 'https': self.proxy}
76
74
  kwargs['verify'] = False
@@ -78,12 +76,6 @@ class Chariot:
78
76
  return requests.request(method, url, headers=(headers | self.keychain.headers()), **kwargs)
79
77
 
80
78
 
81
- def add_beta_url_param(self, kwargs: dict):
82
- if 'params' in kwargs:
83
- kwargs['params']['beta'] = 'true'
84
- else:
85
- kwargs['params'] = {'beta': 'true'}
86
-
87
79
  def my(self, params: dict, pages=1) -> dict:
88
80
  final_resp = dict()
89
81
 
@@ -85,9 +85,9 @@ class Preseeds:
85
85
  """
86
86
  return self.api.search.by_exact_key(key, details)
87
87
 
88
- def update(self, key, status):
88
+ def update(self, key, status, comment=None):
89
89
  """Update the status of an existing preseed.
90
-
90
+
91
91
  Only the status field can be meaningfully updated for preseeds. This allows
92
92
  you to activate, freeze, or mark preseeds for deletion without recreating them.
93
93
  The preseed must exist before it can be updated.
@@ -101,24 +101,29 @@ class Preseeds:
101
101
  - 'FR' (FROZEN_REJECTED): Preseed is frozen and rejected
102
102
  - 'P' (PENDING): Preseed is pending activation
103
103
  :type status: str
104
+ :param comment: Optional comment to include with the update (stored in History field)
105
+ :type comment: str or None
104
106
  :return: The updated preseed object with new status
105
107
  :rtype: dict
106
108
  :raises: Prints error message if preseed with the specified key is not found
107
109
 
108
110
  **Example Usage:**
109
-
111
+
110
112
  .. code-block:: python
111
-
113
+
114
+ # Update status only
112
115
  sdk.preseeds.update(
113
116
  "#preseed#whois+company#Example Company#example company",
114
117
  "A"
115
118
  )
116
-
119
+
120
+ # Update status with comment
117
121
  sdk.preseeds.update(
118
122
  "#preseed#dns+subdomain#API Subdomain#api.example.com",
119
- "F"
123
+ "F",
124
+ comment="Temporarily frozen pending review"
120
125
  )
121
-
126
+
122
127
  sdk.preseeds.update(
123
128
  "#preseed#whois+company#Old Company#old company",
124
129
  "D"
@@ -130,7 +135,13 @@ class Preseeds:
130
135
  """
131
136
  preseed = self.api.search.by_exact_key(key)
132
137
  if preseed:
133
- return self.api.update('preseed', dict(key=key, status=status))
138
+ update_payload = {'key': key, 'status': status}
139
+
140
+ # Include comment if provided
141
+ if comment is not None:
142
+ update_payload['comment'] = comment
143
+
144
+ return self.api.update('preseed', update_payload)
134
145
  else:
135
146
  error(f'Pre-seed {key} is not found.')
136
147
 
@@ -69,26 +69,46 @@ class Seeds:
69
69
  return None
70
70
  return results[0]
71
71
 
72
- def update(self, key, status=None):
72
+ def update(self, key, status=None, comment=None):
73
73
  """
74
74
  Update seed fields dynamically.
75
-
75
+
76
76
  :param key: Seed/Asset key (e.g., '#seed#domain#example.com' or '#asset#domain#example.com')
77
77
  :type key: str
78
78
  :param status: Status for backward compatibility (can be positional)
79
79
  :type status: str or None
80
+ :param comment: Optional comment to include with the update (stored in History field)
81
+ :type comment: str or None
80
82
  :param kwargs: Fields to update
81
83
  :return: The updated seed, or None if the seed was not found
82
84
  :rtype: dict or None
85
+
86
+ **Example Usage:**
87
+
88
+ .. code-block:: python
89
+
90
+ # Update status only
91
+ sdk.seeds.update("#asset#domain#example.com", "A")
92
+
93
+ # Update status with comment
94
+ sdk.seeds.update(
95
+ "#asset#domain#example.com",
96
+ "A",
97
+ comment="Activated after verification"
98
+ )
83
99
  """
84
-
100
+
85
101
  seed = self.get(key) # This already handles old key format conversion
86
102
  if seed:
87
103
  update_payload = {
88
104
  'key': key,
89
105
  'status': status
90
106
  }
91
-
107
+
108
+ # Include comment if provided
109
+ if comment is not None:
110
+ update_payload['comment'] = comment
111
+
92
112
  return self.api.upsert('seed', update_payload)
93
113
  else:
94
114
  error(f'Seed {key} not found.')
@@ -0,0 +1,7 @@
1
+ """Guard SDK alias for Chariot."""
2
+
3
+ from praetorian_cli.sdk.chariot import Chariot
4
+
5
+ Guard = Chariot
6
+
7
+ __all__ = ["Guard"]
@@ -27,5 +27,15 @@ class TestPreseed:
27
27
  assert len(preseeds) > 0
28
28
  assert preseeds[0]['status'] == Preseed.FROZEN_REJECTED.value
29
29
 
30
+ def test_update_preseed_with_comment(self):
31
+ # Update preseed with comment parameter
32
+ self.sdk.preseeds.update(self.preseed_key, Preseed.ACTIVE.value, comment="Test comment for preseed update")
33
+ preseed = self.sdk.preseeds.get(self.preseed_key, details=True)
34
+ assert preseed['status'] == Preseed.ACTIVE.value
35
+ # Verify comment was stored in history
36
+ assert 'history' in preseed
37
+ assert len(preseed['history']) > 0
38
+ assert preseed['history'][0]['comment'] == "Test comment for preseed update"
39
+
30
40
  def teardown_class(self):
31
41
  clean_test_entities(self.sdk, self)
@@ -29,6 +29,16 @@ class TestSeed:
29
29
  self.sdk.seeds.update(self.seed_asset_key, Seed.ACTIVE.value)
30
30
  assert self.get_seed()['status'] == Seed.ACTIVE.value
31
31
 
32
+ def test_update_seed_with_comment(self):
33
+ # Update seed with comment parameter
34
+ self.sdk.seeds.update(self.seed_asset_key, Seed.FROZEN.value, comment="Test comment for seed update")
35
+ seed = self.get_seed()
36
+ assert seed['status'] == Seed.FROZEN.value
37
+ # Verify comment was stored in history
38
+ assert 'history' in seed
39
+ assert len(seed['history']) > 0
40
+ assert seed['history'][0]['comment'] == "Test comment for seed update"
41
+
32
42
  def test_delete_seed(self):
33
43
  self.sdk.seeds.delete(self.seed_asset_key)
34
44
  assert self.sdk.seeds.get(self.seed_asset_key)['status'] == Seed.DELETED.value
@@ -390,8 +390,14 @@ class TestZCli:
390
390
  self.verify('agent --help', ignore_stdout=True)
391
391
  self.verify('agent affiliation --help', ignore_stdout=True)
392
392
 
393
+ def test_guard_cli(self):
394
+ """Test the 'guard' entry point works correctly."""
395
+ self.verify('configure --help', expected_stdout=['Configure the CLI'])
396
+ self.verify('--help', expected_stdout=['configure', 'list', 'add', 'delete', 'update'])
397
+ self.verify('list --help', expected_stdout=['assets', 'risks', 'accounts'])
398
+
393
399
  def verify(self, command, expected_stdout=[], expected_stderr=[], ignore_stdout=False):
394
- result = run(f'praetorian --profile "{self.sdk.keychain.profile}" chariot {command}', capture_output=True,
400
+ result = run(f'guard --profile "{self.sdk.keychain.profile}" {command}', capture_output=True,
395
401
  text=True, shell=True)
396
402
  if expected_stdout:
397
403
  for out in expected_stdout:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: praetorian-cli
3
- Version: 2.2.16
3
+ Version: 2.3.0
4
4
  Summary: For interacting with the Chariot API
5
5
  Home-page: https://github.com/praetorian-inc/praetorian-cli
6
6
  Author: Praetorian
@@ -31,7 +31,7 @@ Dynamic: license-file
31
31
  [![Open Source Libraries](https://img.shields.io/badge/Open--source-%F0%9F%92%9A-28a745)](https://opensource.org/)
32
32
  [![Contributions Welcome](https://img.shields.io/badge/Contributions-Welcome-brightgreen.svg?style=flat)](https://github.com/praetorian-inc/chariot-ui/issues)
33
33
 
34
- :link: [Chariot Platform](https://chariot.praetorian.com)
34
+ :link: [Guard Platform](https://guard.praetorian.com)
35
35
  :book: [Documentation](https://docs.praetorian.com)
36
36
  :bookmark: [PyPI](https://pypi.org/project/praetorian-cli/)
37
37
 
@@ -48,14 +48,15 @@ Dynamic: license-file
48
48
  - [Contributing](#contributing)
49
49
  - [Support](#support)
50
50
  - [License](#license)
51
+ - [Backwards Compatibility](#backwards-compatibility)
51
52
 
52
53
  # Description
53
54
 
54
55
  Praetorian CLI and SDK are open-source tools for interacting with our products and services. Currently, they support
55
- access to [Chariot](https://www.praetorian.com/proactive-cybersecurity-technology/), our
56
+ access to [Guard](https://www.praetorian.com/proactive-cybersecurity-technology/), our
56
57
  offensive security platform.
57
- <br> The SDK exposes the full set of APIs that the Chariot UI uses.
58
- <br> The CLI is a fully-featured companion to the Chariot UI.
58
+ <br> The SDK exposes the full set of APIs that the Guard UI uses.
59
+ <br> The CLI is a fully-featured companion to the Guard UI.
59
60
 
60
61
  # Getting Started
61
62
 
@@ -74,14 +75,14 @@ pip install praetorian-cli
74
75
 
75
76
  ## Signing up
76
77
 
77
- Register for an account for [Chariot](http://chariot.praetorian.com) using the instructions
78
+ Register for an account for [Guard](http://guard.praetorian.com) using the instructions
78
79
  in [our documentation](https://docs.praetorian.com/hc/en-us/articles/38048335323547-Account-Creation-and-Attack-Surface-Setup).
79
80
 
80
81
  ## Authentication
81
82
 
82
- Once you can properly access Chariot through the UI. You can obtain API credentials through the UI under
83
+ Once you can properly access Guard through the UI. You can obtain API credentials through the UI under
83
84
  Settings -> User Settings -> API Keys. Be sure to careful copy the API credentials you created as
84
- you will need to provide them to the CLI for interacting with Chariot.
85
+ you will need to provide them to the CLI for interacting with Guard.
85
86
 
86
87
  **Note**: SSO Organizations should provision access through API Keys as well.
87
88
 
@@ -123,49 +124,49 @@ For more advanced configuration options or managing access in SSO organizations
123
124
 
124
125
  # Using the CLI
125
126
 
126
- The CLI is a command and option utility for accessing the full suite of Chariot's API. You can see the documentation for commands
127
+ The CLI is a command and option utility for accessing the full suite of Guard's API. You can see the documentation for commands
127
128
  using the `help` option:
128
129
 
129
130
  ```zsh
130
- praetorian chariot --help
131
+ guard --help
131
132
  ```
132
133
 
133
134
  As an example, run the following command to retrieve the list of all assets in your account:
134
135
 
135
136
  ```zsh
136
- praetorian --account chariot+example@praetorian.com chariot list assets
137
+ guard --account guard+example@praetorian.com list assets
137
138
  ```
138
139
 
139
- You can obtain the `account` argument by viewing the email of the first user on the Users page in your Chariot account, as shown below:
140
+ You can obtain the `account` argument by viewing the email of the first user on the Users page in your Guard account, as shown below:
140
141
 
141
142
  <img width="482" alt="image" src="https://github.com/user-attachments/assets/7c1024c9-7b74-46b1-87c5-af44671b1ec8" />
142
143
 
143
144
  To get detailed information about a specific asset, run:
144
145
 
145
146
  ```zsh
146
- praetorian --account chariot+example@praetorian.com chariot get asset <ASSET_KEY>
147
+ guard --account guard+example@praetorian.com get asset <ASSET_KEY>
147
148
  ```
148
149
 
149
150
  # Developers
150
151
 
151
152
  Both CLI and SDK is open-source in this repository. The SDK is installed along with the `praetorian-cli`
152
- package. You can extend Chariot by creating scripts using the SDK.
153
+ package. You can extend Guard by creating scripts using the SDK.
153
154
 
154
155
  ## SDK
155
156
 
156
157
  Integrate the SDK into your own Python application with the following steps:
157
158
 
158
159
  1. Include the dependency ``praetorian-cli`` in your project.
159
- 2. Import the Chariot class ``from praetorian_cli.sdk.chariot import Chariot``.
160
+ 2. Import the Guard class ``from praetorian_cli.sdk.guard import Guard``.
160
161
  3. Import the Keychain class ``from praetorian_cli.sdk.keychain import Keychain``.
161
- 4. Call any function of the Chariot class, which expose the full backend API. See example below:
162
+ 4. Call any function of the Guard class, which expose the full backend API. See example below:
162
163
 
163
164
  ```python
164
- from praetorian_cli.sdk.chariot import Chariot
165
+ from praetorian_cli.sdk.guard import Guard
165
166
  from praetorian_cli.sdk.keychain import Keychain
166
167
 
167
- chariot = Chariot(Keychain(account='chariot+example@praetorian.com'))
168
- chariot.add('asset', dict(name='example.com', dns='example.com'))
168
+ guard = Guard(Keychain(account='guard+example@praetorian.com'))
169
+ guard.add('asset', dict(name='example.com', dns='example.com'))
169
170
  ```
170
171
 
171
172
  The best place to explore the SDK is the code of the CLI, especially
@@ -184,7 +185,7 @@ environment to point to directories where you store additional extension scripts
184
185
  Those external scripts are available under the `script` commands. To see a list of them:
185
186
 
186
187
  ```zsh
187
- praetorian --account chariot+example@praetorian.com chariot script --help
188
+ guard --account guard+example@praetorian.com script --help
188
189
  ```
189
190
 
190
191
  For developing scripts, you can refer to
@@ -209,3 +210,39 @@ If you have any questions or need support, please open an issue
209
210
  ## License
210
211
 
211
212
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
213
+
214
+ ---
215
+
216
+ # Backwards Compatibility
217
+
218
+ **Guard** is a rebrand of **Chariot**.
219
+
220
+ ### CLI
221
+ The `guard` command is the new primary CLI entry point. The legacy `praetorian chariot` command continues to work:
222
+
223
+ ```zsh
224
+ # New (preferred):
225
+ guard list assets
226
+ guard --account example@praetorian.com list assets
227
+ guard configure
228
+
229
+ # Legacy (still supported):
230
+ praetorian chariot list assets
231
+ praetorian configure
232
+ ```
233
+
234
+ ### SDK
235
+ Both `Guard` and `Chariot` classes are available and interchangeable:
236
+
237
+ ```python
238
+ # New (preferred):
239
+ from praetorian_cli.sdk.guard import Guard
240
+ guard = Guard(Keychain())
241
+
242
+ # Legacy (still supported):
243
+ from praetorian_cli.sdk.chariot import Chariot
244
+ chariot = Chariot(Keychain())
245
+ ```
246
+
247
+ ### Configuration
248
+ The keychain file and environment variables remain unchanged. Existing configurations will continue to work without modification.
@@ -1,31 +1,32 @@
1
1
  praetorian_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- praetorian_cli/main.py,sha256=AVrOCQgioLDKm-Y8-b3lLLdLtaO1WwOAzUfs0obe5Nw,1451
2
+ praetorian_cli/main.py,sha256=B8Y5N6kSzOEAjSN3fPT8Urn2TvPPiHnauCeQcAlwpr0,2435
3
3
  praetorian_cli/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- praetorian_cli/handlers/add.py,sha256=q0lJlGroHx0dA6w7V35CHZoi8tqHdj8lv5wqqRu0ZIA,16266
4
+ praetorian_cli/handlers/add.py,sha256=CXABvU4wP4BszyefLvetuIqr9aOnG9-I4JzNWww2yBs,16246
5
5
  praetorian_cli/handlers/aegis.py,sha256=1259bNmoUOVhcs7GqI8TyTyCI_ZvKzEPvfUVvAHcTzU,3936
6
- praetorian_cli/handlers/agent.py,sha256=52_BcZF10VOuiwkySQpjeh07JdUKaMURo-RLVOINK1w,3165
7
- praetorian_cli/handlers/chariot.py,sha256=HClwYdsgFKlLY68RhV65W1Y4g-JgbBDdI4PdP4s8MgI,611
6
+ praetorian_cli/handlers/agent.py,sha256=pk9D-cNdJTJRQCbSE4YZXjn-ZoBOBNnGEwWLlLOAe7M,3157
7
+ praetorian_cli/handlers/chariot.py,sha256=BXO0biKVoy1EwulWPxFZ8NbaVoiMxUKl6lclw3Z1aJY,609
8
8
  praetorian_cli/handlers/cli_decorators.py,sha256=ZLPMZH9i-vNtTT0Y0qnYQsGw8B4lxIdEE1vBX9i75Wc,2884
9
9
  praetorian_cli/handlers/configure.py,sha256=8ABvisb_a4WekVVZ5kEhT1m4Mn2xV5RsO_xO_7f6TkM,1317
10
- praetorian_cli/handlers/delete.py,sha256=8K7yEnQQT88vbJG-ouX-aFq6FyjkWNGDMt97VYZGSZg,4433
10
+ praetorian_cli/handlers/delete.py,sha256=tUnuM_wFoKyckK4UqzN7CouD-26vsQcqqqh8lFhtZx0,4429
11
11
  praetorian_cli/handlers/enrich.py,sha256=KRvOAuW7mQdYg_k_XOTwtPmnf8rxOAtoL00Bb0e-N-s,485
12
- praetorian_cli/handlers/get.py,sha256=-_gfjPDN_H7tClHzKPN6jo-rtXsUMp7NaQ_YrdEajX4,9564
13
- praetorian_cli/handlers/imports.py,sha256=u1TK4w3eCMD5ASPFare2NgTX1_m0_F1ELCmvV7OF-PI,1653
12
+ praetorian_cli/handlers/get.py,sha256=2rMuv8F-pPo66PTLjQBoNpEsWIEMsTrrDE04FvcdT7s,9586
13
+ praetorian_cli/handlers/imports.py,sha256=UudGhvMBJg_yE2vWTAFFSgn0y6muEiNe_g8xJWJdtOw,1651
14
14
  praetorian_cli/handlers/link.py,sha256=7JjHoawFZbcfropHVp8IX3Ekci6theAlcYSTPXnrFHQ,1776
15
- praetorian_cli/handlers/list.py,sha256=bTPztFlyHHyCO5y5pDOw68CDxGN_Ps8DrhbStgSFgrc,13217
15
+ praetorian_cli/handlers/list.py,sha256=vpyJZNtUOwN2BgwBxHFg2Sc-XGvTPosG23DZUk8cJFA,13213
16
16
  praetorian_cli/handlers/script.py,sha256=x_nWTlv0_9dLrQ4KulzKX11QwJHdtm6hWtZYgKzKcs4,2040
17
- praetorian_cli/handlers/search.py,sha256=wPXiHrBx4NpNB8a79S9wE6TMArBjg5WsEFKzDoUAR-0,2633
17
+ praetorian_cli/handlers/search.py,sha256=juDemeZsD1reTHp73V7e10o52uleOg8AqF3olpkZC4E,2631
18
18
  praetorian_cli/handlers/ssh_utils.py,sha256=53Kke-iFH4sJoCcweiT8q4WVRlaA7SvR5CCqdGFxHps,5903
19
19
  praetorian_cli/handlers/test.py,sha256=uhARoRolaJf6DMRNX-1aj8SDYe1wAvhYDOBYWH39sqo,932
20
20
  praetorian_cli/handlers/unlink.py,sha256=nUTGXZ7JBXwuHy2nzvL79sSO95Vyc0PftM6rm-9YWt8,1725
21
- praetorian_cli/handlers/update.py,sha256=xOThuMQ2n9Zq2-UAtRa7-9MujpoACcGUnad85-X16zA,3340
21
+ praetorian_cli/handlers/update.py,sha256=YdxOp0O9-lB-yBYK3GZZE_dBcriCixyFly8Tplj6wzM,3338
22
22
  praetorian_cli/handlers/utils.py,sha256=PaHyDTF2uj6mMMIr1pP1Bfh22H3dMx_UWnJgXK7_yuY,2639
23
23
  praetorian_cli/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  praetorian_cli/scripts/utils.py,sha256=lGCf4trEpsfECa9U42pDJ-f48EimlS-hG6AjnKjNt4I,501
25
25
  praetorian_cli/scripts/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  praetorian_cli/scripts/commands/nmap-example.py,sha256=varKTkHKG4DAs9Ssf0c6SygP9GfuCG01aFxhfvixLM0,2727
27
27
  praetorian_cli/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- praetorian_cli/sdk/chariot.py,sha256=amMgs7FxX9DY0tWNoizg7XfrVYWyLixbqqcaBQsuAKg,14626
28
+ praetorian_cli/sdk/chariot.py,sha256=XRF0iWXw4ylGtlWouc6wr4g9oSR0KfzPfe8f5-3AdVY,14386
29
+ praetorian_cli/sdk/guard.py,sha256=ojyyr16MXMsuAmAL6RVqH3HtBKdedDnLQSm4nnkxnDo,121
29
30
  praetorian_cli/sdk/keychain.py,sha256=KCz2mOTv09jgg6mrZQooRg1VrnvF9W0_BjRlEQhbzqU,7468
30
31
  praetorian_cli/sdk/mcp_server.py,sha256=8UoTotD4UVl-tp1gqMjkOVpO__KeGCvy7mIpKXVc8Rg,8750
31
32
  praetorian_cli/sdk/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -42,12 +43,12 @@ praetorian_cli/sdk/entities/files.py,sha256=Gw9Yt_Cm2xR-Vu8vjaekMHbGldhe930WJjje
42
43
  praetorian_cli/sdk/entities/integrations.py,sha256=NVaW_dWbnMkMIs-EYr2W7QAeamPVwLhmM2ppdMJmsK0,3176
43
44
  praetorian_cli/sdk/entities/jobs.py,sha256=k4QFw4qR5MdVyMAYstfnRIWr_ZH4q1PwDyUEGC-qBSM,8269
44
45
  praetorian_cli/sdk/entities/keys.py,sha256=PgoGa3xyLMzWrIIQ8zgi7bfZiUFFumPtMDo64GjhdjE,6089
45
- praetorian_cli/sdk/entities/preseeds.py,sha256=SeSY4K6diJMQzsjCBxYK3N9Lz0fUz3B_LMBOAAcBSLg,8890
46
+ praetorian_cli/sdk/entities/preseeds.py,sha256=C_FdoUnU5afwEgd7TWpeh4DMMXgEdlaIVTVJGqPGqO8,9298
46
47
  praetorian_cli/sdk/entities/risks.py,sha256=D2A-Ikl91QeNiRrWwozLFD61uQ0LJ6oYeCW-8qy5iyo,8273
47
48
  praetorian_cli/sdk/entities/scanners.py,sha256=QCr5QlBy4jfBh8HRvZt9CoZTgNqLNnKNrI4sdfJf0jE,423
48
49
  praetorian_cli/sdk/entities/schema.py,sha256=CPVws1CdRHyOAI7oT9A20WGOCZozTFqZnfo5ox3v0HQ,807
49
50
  praetorian_cli/sdk/entities/search.py,sha256=9vTy9HZY2BTlqf5Zwpdl8HCRIfSEvWDRij2_-rAp2Ng,16938
50
- praetorian_cli/sdk/entities/seeds.py,sha256=eYDFtfgzIX_o9c5wuPiz9I2xDfTz7k9PZPzL7A7x1CM,5404
51
+ praetorian_cli/sdk/entities/seeds.py,sha256=4YMOOGDJHsSO4O7GMTm8p2nkTOdUTBxXr8V7y6e-Yjc,6010
51
52
  praetorian_cli/sdk/entities/settings.py,sha256=F-pRCA6UvbdtnjHOLpEG2lN9ws8dcnBNcep-DFlXeTY,2750
52
53
  praetorian_cli/sdk/entities/statistics.py,sha256=gtX-NN7r_RsNjDjlQ-zspmzG_0bzBqBFarCuM4NO-EA,7085
53
54
  praetorian_cli/sdk/entities/webhook.py,sha256=7Bqt20GlJFbZTlmQwYTuUadsUQvydym6S4kGn9zYa50,6220
@@ -72,14 +73,14 @@ praetorian_cli/sdk/test/test_file.py,sha256=ZpFBSKbfq9kzfQdy_tmwCH8rwYxW6GB4NlhT
72
73
  praetorian_cli/sdk/test/test_job.py,sha256=J7VqnVxRfvbpxNnYN9Rt3LvxmbNvSKwVqsSZxFEW1xc,1916
73
74
  praetorian_cli/sdk/test/test_key.py,sha256=yDrR0-JLwMB3eDx-tI-ss8GGbiJaJijE4dAK8-FUuzc,1425
74
75
  praetorian_cli/sdk/test/test_mcp.py,sha256=Ltg283j4Q12dcfCgUgDMKk6neRdDaThcndyywZl5XWs,938
75
- praetorian_cli/sdk/test/test_preseed.py,sha256=VhKSbSB6OmCYnVOrI6RDsYKBs1PekEuv0KOjbTt_k14,1186
76
+ praetorian_cli/sdk/test/test_preseed.py,sha256=ju82GVVcRguNcuGKxmCO6E5KoBXCdDHmPYs_2EEB8cA,1739
76
77
  praetorian_cli/sdk/test/test_risk.py,sha256=WuVTPxL9yj84nJx84oXVAlz0KshLxs8GG3tDeSe3QZU,3000
77
78
  praetorian_cli/sdk/test/test_search.py,sha256=SB9Tgo_N3CCpfvla898oLB9IZyGK9Dju1r9REK6Wmek,1996
78
- praetorian_cli/sdk/test/test_seed.py,sha256=WfnEPZwMXHFtt4jyVT-1JitIW1zTrl7rwlX8jXz22vY,1303
79
+ praetorian_cli/sdk/test/test_seed.py,sha256=nGyNsV5bKUGxm5AILY19zp-JNCw6q0IfmefRSLicgsQ,1785
79
80
  praetorian_cli/sdk/test/test_setting.py,sha256=hdPQj71rjSYxa-PODG2D-kJd8C9gkAg1jQXnqYU4P6A,1326
80
81
  praetorian_cli/sdk/test/test_webhook.py,sha256=FQJY76QQ6Yg2iLCGpxgKiXGI8TtmB4zTpMIM2SpYKCc,2228
81
82
  praetorian_cli/sdk/test/test_webpage.py,sha256=jgKrsobD3ONibDIbbOT-yy7V_NmC5-LwEZmEYdYu0LI,1779
82
- praetorian_cli/sdk/test/test_z_cli.py,sha256=jhpv65p0JRJU-_uSSbVo9SznKm_2iAhOlSPkx8E4Oq4,20703
83
+ praetorian_cli/sdk/test/test_z_cli.py,sha256=Ypsd8W4fac3sbOv9zPpcaywOLZVkI6UTwyT_hhCdnjY,21040
83
84
  praetorian_cli/sdk/test/ui_mocks.py,sha256=kiqAPxaM-_T0NQ-HgOZupNiUoJa5mE2CsyK2cXWiPws,4146
84
85
  praetorian_cli/sdk/test/utils.py,sha256=svxMpzlaW4FRCij05cPgJFrTUEELVdt8G7SPKEdsgPo,3526
85
86
  praetorian_cli/ui/__init__.py,sha256=wEgkrgIaoOguH1VVp2FndaGIxWmZ5CfAynXtNtZ6iTo,81
@@ -96,9 +97,9 @@ praetorian_cli/ui/aegis/commands/set.py,sha256=WJ0Qt30fBa_hyWEaawyA3h3rSeWHFPbJS
96
97
  praetorian_cli/ui/aegis/commands/ssh.py,sha256=KGsNlN0i-Cwp6gWyr-cjML9_L13oE7xFenysF2pC8Rc,3045
97
98
  praetorian_cli/ui/conversation/__init__.py,sha256=sNhNN_ZG1Va_7OLTaoXlIFL6ageKHWdufFVYw6F_aV8,90
98
99
  praetorian_cli/ui/conversation/textual_chat.py,sha256=gGgEs7HhNAto9rTVrGbz62mG10OqmtArI-aKxFLSfVs,24405
99
- praetorian_cli-2.2.16.dist-info/licenses/LICENSE,sha256=Zv97QripiVALv-WokW_Elsiz9vtOfbtNt1aLZhhk67I,1067
100
- praetorian_cli-2.2.16.dist-info/METADATA,sha256=k1QrG9U-1UBigFvfvrTmWtCuT7ixgJzRIuoNmAfone4,7752
101
- praetorian_cli-2.2.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
- praetorian_cli-2.2.16.dist-info/entry_points.txt,sha256=uJbDvZdkYaLiCh2DMvXPUGKFm2p5ZfzJCizUK3-PUEE,56
103
- praetorian_cli-2.2.16.dist-info/top_level.txt,sha256=QbUdRPGEj_TyHO-E7AD5BxFfR8ore37i273jP4Gn43c,15
104
- praetorian_cli-2.2.16.dist-info/RECORD,,
100
+ praetorian_cli-2.3.0.dist-info/licenses/LICENSE,sha256=Zv97QripiVALv-WokW_Elsiz9vtOfbtNt1aLZhhk67I,1067
101
+ praetorian_cli-2.3.0.dist-info/METADATA,sha256=gclKruB9L7Un3YVnsukLGzraX1AjaRYo5TCDDdHbTbg,8533
102
+ praetorian_cli-2.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
103
+ praetorian_cli-2.3.0.dist-info/entry_points.txt,sha256=WAL6whBPvLyjqnKLuRNjKU4hHP9vUqlemLB2vebnu_U,95
104
+ praetorian_cli-2.3.0.dist-info/top_level.txt,sha256=QbUdRPGEj_TyHO-E7AD5BxFfR8ore37i273jP4Gn43c,15
105
+ praetorian_cli-2.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ guard = praetorian_cli.main:guard_main
2
3
  praetorian = praetorian_cli.main:main