aac-cli 0.2.4__tar.gz → 0.2.5__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.
- {aac_cli-0.2.4 → aac_cli-0.2.5}/PKG-INFO +16 -3
- aac_cli-0.2.4/aac_cli.egg-info/PKG-INFO → aac_cli-0.2.5/README.md +14 -23
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/__init__.py +1 -1
- aac_cli-0.2.5/aac_cli/chain_list.py +100 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/cli.py +59 -1
- aac_cli-0.2.4/README.md → aac_cli-0.2.5/aac_cli.egg-info/PKG-INFO +36 -1
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli.egg-info/SOURCES.txt +1 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/pyproject.toml +4 -4
- {aac_cli-0.2.4 → aac_cli-0.2.5}/LICENSE +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/MANIFEST.in +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/NOTICE +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/THIRD_PARTY_NOTICES.md +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/__main__.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/__init__.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/cli.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/data/action-taken-v1.json +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/data/predicates-v1.json +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/data/renderer-source.json +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/from_sidecar.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/inputs.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/model.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/narrative.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/schemas.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/temporal.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/timeline_source.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/_aeg/visualizer.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/admin_key_pem.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/aeg_cli.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/agent_cli.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/agent_config.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/agent_health.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/agent_layout.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/agent_record.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/api_key_rotation_state.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/config.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/config_render.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/dev_material.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/idp_recovery.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/init_cli.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/material_cases.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/profiles.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/reference.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/registration_state.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/secure_files.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/sso_login.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/supplied_material.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli/trace_query.py +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli.egg-info/dependency_links.txt +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli.egg-info/requires.txt +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/aac_cli.egg-info/top_level.txt +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/launchers/aac +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/launchers/aeg +0 -0
- {aac_cli-0.2.4 → aac_cli-0.2.5}/setup.cfg +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aac-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: The aac platform CLI — headless operator interface to the AAC control plane (tenant registration, chain audit).
|
|
5
5
|
Author: Agent Authority Cloud Project
|
|
6
6
|
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: Documentation, https://cascadeauth.github.io/aac-starter-guide/aeg.html
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
License-File: NOTICE
|
|
@@ -59,7 +59,7 @@ pip install aac-cli
|
|
|
59
59
|
aac --version
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
Python 3.
|
|
62
|
+
Python 3.11 or newer is required.
|
|
63
63
|
|
|
64
64
|
> **Mind the name.** `pip install aac` installs an unrelated project that
|
|
65
65
|
> happens to share the acronym. The AAC package is **`aac-cli`**; the
|
|
@@ -973,6 +973,7 @@ Deactivation is terminal, and a deactivated SPIFFE id stays reserved.
|
|
|
973
973
|
```bash
|
|
974
974
|
aac trust-anchor list --profile prod --output table # every published key, every lifecycle state
|
|
975
975
|
aac trust-anchor describe --profile prod --kid starter-root-v1
|
|
976
|
+
aac chain list --profile prod --since 7d --output table
|
|
976
977
|
aac chain show --profile prod \
|
|
977
978
|
--token-id c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9 --output table
|
|
978
979
|
aac chain show --profile prod \
|
|
@@ -984,6 +985,18 @@ aac chain show --profile prod \
|
|
|
984
985
|
chain to any tenant that took part in it. The timeline carries metadata
|
|
985
986
|
only; the business content of each step stays in your own audit stream.
|
|
986
987
|
|
|
988
|
+
`chain list` discovers roots using central observations for your tenant. The
|
|
989
|
+
default is the last 24 hours; use `--since 7d` or timezone-qualified
|
|
990
|
+
`--from 2026-09-01T00:00Z --to 2026-09-08T00:00Z` for a different interval
|
|
991
|
+
(maximum 31 days). It reads no local files or business labels. JSON includes
|
|
992
|
+
the resolved interval and `next_page_token`; pass that token with
|
|
993
|
+
`--page-token` to continue the same query. Each invocation fetches one page
|
|
994
|
+
(default 50 rows, maximum 200). Tokens expire 15 minutes after the first page.
|
|
995
|
+
Central evidence may be incomplete and pages are live: late forwarding can
|
|
996
|
+
change summaries or add roots, including roots behind the current page.
|
|
997
|
+
Repeat the original interval to refresh. A returned `root_token_id` works
|
|
998
|
+
with `chain show --token-id` and `aeg render --root-token-id`.
|
|
999
|
+
|
|
987
1000
|
## Getting help
|
|
988
1001
|
|
|
989
1002
|
`aac --help` lists the command groups and `aac <command> --help` shows every
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: aac-cli
|
|
3
|
-
Version: 0.2.4
|
|
4
|
-
Summary: The aac platform CLI — headless operator interface to the AAC control plane (tenant registration, chain audit).
|
|
5
|
-
Author: Agent Authority Cloud Project
|
|
6
|
-
License-Expression: Apache-2.0
|
|
7
|
-
Project-URL: Documentation, https://cascadeauth.github.io/aac-starter-guide/aeg.html
|
|
8
|
-
Requires-Python: >=3.10
|
|
9
|
-
Description-Content-Type: text/markdown
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
License-File: NOTICE
|
|
12
|
-
License-File: THIRD_PARTY_NOTICES.md
|
|
13
|
-
Requires-Dist: httpx>=0.28
|
|
14
|
-
Requires-Dist: cryptography>=42.0
|
|
15
|
-
Requires-Dist: PyYAML>=6.0
|
|
16
|
-
Requires-Dist: pyvis<0.4,>=0.3.2
|
|
17
|
-
Requires-Dist: jsonschema>=4.18
|
|
18
|
-
Provides-Extra: test
|
|
19
|
-
Requires-Dist: pytest>=8.0; extra == "test"
|
|
20
|
-
Requires-Dist: pytest-httpx>=0.30; extra == "test"
|
|
21
|
-
Dynamic: license-file
|
|
22
|
-
|
|
23
1
|
# aac-cli — the `aac` command
|
|
24
2
|
|
|
25
3
|
`aac` is the command-line tool for tenants of Agent Authority Cloud (AAC).
|
|
@@ -59,7 +37,7 @@ pip install aac-cli
|
|
|
59
37
|
aac --version
|
|
60
38
|
```
|
|
61
39
|
|
|
62
|
-
Python 3.
|
|
40
|
+
Python 3.11 or newer is required.
|
|
63
41
|
|
|
64
42
|
> **Mind the name.** `pip install aac` installs an unrelated project that
|
|
65
43
|
> happens to share the acronym. The AAC package is **`aac-cli`**; the
|
|
@@ -973,6 +951,7 @@ Deactivation is terminal, and a deactivated SPIFFE id stays reserved.
|
|
|
973
951
|
```bash
|
|
974
952
|
aac trust-anchor list --profile prod --output table # every published key, every lifecycle state
|
|
975
953
|
aac trust-anchor describe --profile prod --kid starter-root-v1
|
|
954
|
+
aac chain list --profile prod --since 7d --output table
|
|
976
955
|
aac chain show --profile prod \
|
|
977
956
|
--token-id c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9 --output table
|
|
978
957
|
aac chain show --profile prod \
|
|
@@ -984,6 +963,18 @@ aac chain show --profile prod \
|
|
|
984
963
|
chain to any tenant that took part in it. The timeline carries metadata
|
|
985
964
|
only; the business content of each step stays in your own audit stream.
|
|
986
965
|
|
|
966
|
+
`chain list` discovers roots using central observations for your tenant. The
|
|
967
|
+
default is the last 24 hours; use `--since 7d` or timezone-qualified
|
|
968
|
+
`--from 2026-09-01T00:00Z --to 2026-09-08T00:00Z` for a different interval
|
|
969
|
+
(maximum 31 days). It reads no local files or business labels. JSON includes
|
|
970
|
+
the resolved interval and `next_page_token`; pass that token with
|
|
971
|
+
`--page-token` to continue the same query. Each invocation fetches one page
|
|
972
|
+
(default 50 rows, maximum 200). Tokens expire 15 minutes after the first page.
|
|
973
|
+
Central evidence may be incomplete and pages are live: late forwarding can
|
|
974
|
+
change summaries or add roots, including roots behind the current page.
|
|
975
|
+
Repeat the original interval to refresh. A returned `root_token_id` works
|
|
976
|
+
with `chain show --token-id` and `aeg render --root-token-id`.
|
|
977
|
+
|
|
987
978
|
## Getting help
|
|
988
979
|
|
|
989
980
|
`aac --help` lists the command groups and `aac <command> --help` shows every
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Public chain-list query preparation and table rendering; no server dependency."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from datetime import datetime, timedelta, timezone
|
|
7
|
+
|
|
8
|
+
MAX_WINDOW_SECONDS = 31 * 86400
|
|
9
|
+
MAX_LIMIT = 200
|
|
10
|
+
_TIME_RE = re.compile(
|
|
11
|
+
r"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}(?::[0-9]{2}(?:\.(?P<fraction>[0-9]{1,6}))?)?"
|
|
12
|
+
r"(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _time(value: str) -> datetime:
|
|
17
|
+
match = _TIME_RE.fullmatch(value)
|
|
18
|
+
if match is None:
|
|
19
|
+
raise ValueError("--from/--to require timezone-qualified RFC3339 timestamps")
|
|
20
|
+
fraction = match.group("fraction")
|
|
21
|
+
if fraction is not None:
|
|
22
|
+
# Pad exactly, without rounding: every accepted 1..6-digit fraction
|
|
23
|
+
# then parses identically on every supported interpreter.
|
|
24
|
+
value = (
|
|
25
|
+
value[: match.start("fraction")]
|
|
26
|
+
+ fraction.ljust(6, "0")
|
|
27
|
+
+ value[match.end("fraction") :]
|
|
28
|
+
)
|
|
29
|
+
try:
|
|
30
|
+
return datetime.fromisoformat(value.replace("Z", "+00:00")).astimezone(timezone.utc)
|
|
31
|
+
except (ValueError, OverflowError) as exc:
|
|
32
|
+
raise ValueError("--from/--to require valid RFC3339 timestamps") from exc
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def query_params(
|
|
36
|
+
*,
|
|
37
|
+
since: str | None,
|
|
38
|
+
start: str | None,
|
|
39
|
+
end: str | None,
|
|
40
|
+
limit: int | None,
|
|
41
|
+
page_token: str | None,
|
|
42
|
+
now: datetime | None = None,
|
|
43
|
+
) -> dict[str, str]:
|
|
44
|
+
if limit is not None and not 1 <= limit <= MAX_LIMIT:
|
|
45
|
+
raise ValueError("--limit must be between 1 and 200")
|
|
46
|
+
if (start is None) != (end is None):
|
|
47
|
+
raise ValueError("--from and --to must be supplied together")
|
|
48
|
+
if since is not None and (start is not None or page_token is not None):
|
|
49
|
+
raise ValueError("--since cannot be combined with --from/--to or --page-token")
|
|
50
|
+
params = {}
|
|
51
|
+
if limit is not None:
|
|
52
|
+
params["limit"] = str(limit)
|
|
53
|
+
if page_token is not None:
|
|
54
|
+
if not page_token or len(page_token) > 2048:
|
|
55
|
+
raise ValueError("--page-token must contain 1 to 2048 characters")
|
|
56
|
+
params["cursor"] = page_token
|
|
57
|
+
if start is not None and end is not None:
|
|
58
|
+
from_time, to_time = _time(start), _time(end)
|
|
59
|
+
elif page_token is not None:
|
|
60
|
+
return params # Server reuses the original resolved interval/limit.
|
|
61
|
+
else:
|
|
62
|
+
duration = since or "24h"
|
|
63
|
+
match = re.fullmatch(r"([0-9]{1,4})([hd])", duration)
|
|
64
|
+
if match is None:
|
|
65
|
+
raise ValueError("--since requires positive integer hours or days, such as 24h or 7d")
|
|
66
|
+
seconds = int(match[1]) * (3600 if match[2] == "h" else 86400)
|
|
67
|
+
if not 0 < seconds <= MAX_WINDOW_SECONDS:
|
|
68
|
+
raise ValueError("--since must be greater than zero and at most 31 days")
|
|
69
|
+
to_time = now or datetime.now(timezone.utc)
|
|
70
|
+
from_time = to_time - timedelta(seconds=seconds)
|
|
71
|
+
if not timedelta(0) < to_time - from_time <= timedelta(seconds=MAX_WINDOW_SECONDS):
|
|
72
|
+
raise ValueError("--from must precede --to by at most 31 days")
|
|
73
|
+
params.update(
|
|
74
|
+
{
|
|
75
|
+
"from": from_time.isoformat().replace("+00:00", "Z"),
|
|
76
|
+
"to": to_time.isoformat().replace("+00:00", "Z"),
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
return params
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def render_table(body: dict) -> str:
|
|
83
|
+
lines = [
|
|
84
|
+
"Central observations may be incomplete (best-effort forwarding).",
|
|
85
|
+
f"Activity interval: [{body['from']}, {body['to']}) — live pagination",
|
|
86
|
+
"Times, token counts and hop indexes are observed, not execution totals.",
|
|
87
|
+
"",
|
|
88
|
+
"root_token_id first_event last_event tokens max_hop outcomes",
|
|
89
|
+
]
|
|
90
|
+
for row in body["chains"]:
|
|
91
|
+
lines.append(
|
|
92
|
+
f"{row['root_token_id']} {row['first_event_unix_seconds']:<12} "
|
|
93
|
+
f"{row['last_event_unix_seconds']:<12} {row['observed_token_count']:<6} "
|
|
94
|
+
f"{row['max_observed_hop']:<7} {','.join(row['outcomes'])}"
|
|
95
|
+
)
|
|
96
|
+
if body["has_more"]:
|
|
97
|
+
lines.append(f"\nMore results: repeat with --page-token {body['next_page_token']}")
|
|
98
|
+
else:
|
|
99
|
+
lines.append("\nNo more rows in this query; late observations can change a repeat query.")
|
|
100
|
+
return "\n".join(lines)
|
|
@@ -3020,6 +3020,27 @@ def _cmd_chain_show(args: argparse.Namespace) -> int:
|
|
|
3020
3020
|
return 0
|
|
3021
3021
|
|
|
3022
3022
|
|
|
3023
|
+
def _cmd_chain_list(args: argparse.Namespace) -> int:
|
|
3024
|
+
from .chain_list import query_params, render_table
|
|
3025
|
+
|
|
3026
|
+
try:
|
|
3027
|
+
params = query_params(
|
|
3028
|
+
since=args.since,
|
|
3029
|
+
start=args.from_time,
|
|
3030
|
+
end=args.to_time,
|
|
3031
|
+
limit=args.limit,
|
|
3032
|
+
page_token=args.page_token,
|
|
3033
|
+
)
|
|
3034
|
+
except ValueError as exc:
|
|
3035
|
+
raise CliUsageError(str(exc)) from exc
|
|
3036
|
+
code, body = _data_plane_get(args, "/v1/trace/chains", params)
|
|
3037
|
+
if code:
|
|
3038
|
+
return code
|
|
3039
|
+
assert body is not None
|
|
3040
|
+
print(json.dumps(body, indent=2) if args.output == "json" else render_table(body))
|
|
3041
|
+
return 0
|
|
3042
|
+
|
|
3043
|
+
|
|
3023
3044
|
# ---------------------------------------------------------------------------
|
|
3024
3045
|
# aac trust-anchor list / describe / ingest-history (B130) / revoke (B201)
|
|
3025
3046
|
# ---------------------------------------------------------------------------
|
|
@@ -5280,8 +5301,45 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
5280
5301
|
)
|
|
5281
5302
|
ta_history.set_defaults(handler=_cmd_trust_anchor_ingest_history)
|
|
5282
5303
|
|
|
5283
|
-
chain = nouns.add_parser("chain", help="
|
|
5304
|
+
chain = nouns.add_parser("chain", help="Discover chains and inspect their audit observations.")
|
|
5284
5305
|
chain_verbs = chain.add_subparsers(dest="verb", required=True)
|
|
5306
|
+
chain_list = chain_verbs.add_parser(
|
|
5307
|
+
"list",
|
|
5308
|
+
help="List observed chains visible to your tenant.",
|
|
5309
|
+
description="Query central observations only; no local files are read. Central evidence may be incomplete because forwarding is best effort.",
|
|
5310
|
+
epilog="Each invocation fetches one page. Continue using --page-token alone to preserve the resolved interval and page size. Pagination is live: late arrivals can change rows or be missed before the last returned root. Repeat the original interval to refresh. Connected composite roots remain distinct rows. Times, outcomes and counts are observations, not chain completion or execution totals.",
|
|
5311
|
+
)
|
|
5312
|
+
_add_common_flags(chain_list)
|
|
5313
|
+
chain_list.add_argument("--tenant-id", default=None, help="Credential to present.")
|
|
5314
|
+
chain_list.add_argument(
|
|
5315
|
+
"--since",
|
|
5316
|
+
default=None,
|
|
5317
|
+
help="Positive integer hours or days (default 24h; maximum 31d). Cannot accompany a page token or explicit interval.",
|
|
5318
|
+
)
|
|
5319
|
+
chain_list.add_argument(
|
|
5320
|
+
"--from",
|
|
5321
|
+
dest="from_time",
|
|
5322
|
+
default=None,
|
|
5323
|
+
help="Inclusive RFC3339 activity time with timezone; requires --to.",
|
|
5324
|
+
)
|
|
5325
|
+
chain_list.add_argument(
|
|
5326
|
+
"--to",
|
|
5327
|
+
dest="to_time",
|
|
5328
|
+
default=None,
|
|
5329
|
+
help="Exclusive RFC3339 activity time with timezone; requires --from. Maximum interval 31 days.",
|
|
5330
|
+
)
|
|
5331
|
+
chain_list.add_argument(
|
|
5332
|
+
"--limit",
|
|
5333
|
+
type=int,
|
|
5334
|
+
default=None,
|
|
5335
|
+
help="Rows per page (default 50, maximum 200; continuation preserves original size).",
|
|
5336
|
+
)
|
|
5337
|
+
chain_list.add_argument(
|
|
5338
|
+
"--page-token",
|
|
5339
|
+
default=None,
|
|
5340
|
+
help="Opaque continuation from next_page_token (expires after 15 minutes).",
|
|
5341
|
+
)
|
|
5342
|
+
chain_list.set_defaults(handler=_cmd_chain_list)
|
|
5285
5343
|
show = chain_verbs.add_parser(
|
|
5286
5344
|
"show", help="Chronological cross-org timeline (participant tenants only)."
|
|
5287
5345
|
)
|
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aac-cli
|
|
3
|
+
Version: 0.2.5
|
|
4
|
+
Summary: The aac platform CLI — headless operator interface to the AAC control plane (tenant registration, chain audit).
|
|
5
|
+
Author: Agent Authority Cloud Project
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Documentation, https://cascadeauth.github.io/aac-starter-guide/aeg.html
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
License-File: NOTICE
|
|
12
|
+
License-File: THIRD_PARTY_NOTICES.md
|
|
13
|
+
Requires-Dist: httpx>=0.28
|
|
14
|
+
Requires-Dist: cryptography>=42.0
|
|
15
|
+
Requires-Dist: PyYAML>=6.0
|
|
16
|
+
Requires-Dist: pyvis<0.4,>=0.3.2
|
|
17
|
+
Requires-Dist: jsonschema>=4.18
|
|
18
|
+
Provides-Extra: test
|
|
19
|
+
Requires-Dist: pytest>=8.0; extra == "test"
|
|
20
|
+
Requires-Dist: pytest-httpx>=0.30; extra == "test"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
1
23
|
# aac-cli — the `aac` command
|
|
2
24
|
|
|
3
25
|
`aac` is the command-line tool for tenants of Agent Authority Cloud (AAC).
|
|
@@ -37,7 +59,7 @@ pip install aac-cli
|
|
|
37
59
|
aac --version
|
|
38
60
|
```
|
|
39
61
|
|
|
40
|
-
Python 3.
|
|
62
|
+
Python 3.11 or newer is required.
|
|
41
63
|
|
|
42
64
|
> **Mind the name.** `pip install aac` installs an unrelated project that
|
|
43
65
|
> happens to share the acronym. The AAC package is **`aac-cli`**; the
|
|
@@ -951,6 +973,7 @@ Deactivation is terminal, and a deactivated SPIFFE id stays reserved.
|
|
|
951
973
|
```bash
|
|
952
974
|
aac trust-anchor list --profile prod --output table # every published key, every lifecycle state
|
|
953
975
|
aac trust-anchor describe --profile prod --kid starter-root-v1
|
|
976
|
+
aac chain list --profile prod --since 7d --output table
|
|
954
977
|
aac chain show --profile prod \
|
|
955
978
|
--token-id c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9c3d5e7f9 --output table
|
|
956
979
|
aac chain show --profile prod \
|
|
@@ -962,6 +985,18 @@ aac chain show --profile prod \
|
|
|
962
985
|
chain to any tenant that took part in it. The timeline carries metadata
|
|
963
986
|
only; the business content of each step stays in your own audit stream.
|
|
964
987
|
|
|
988
|
+
`chain list` discovers roots using central observations for your tenant. The
|
|
989
|
+
default is the last 24 hours; use `--since 7d` or timezone-qualified
|
|
990
|
+
`--from 2026-09-01T00:00Z --to 2026-09-08T00:00Z` for a different interval
|
|
991
|
+
(maximum 31 days). It reads no local files or business labels. JSON includes
|
|
992
|
+
the resolved interval and `next_page_token`; pass that token with
|
|
993
|
+
`--page-token` to continue the same query. Each invocation fetches one page
|
|
994
|
+
(default 50 rows, maximum 200). Tokens expire 15 minutes after the first page.
|
|
995
|
+
Central evidence may be incomplete and pages are live: late forwarding can
|
|
996
|
+
change summaries or add roots, including roots behind the current page.
|
|
997
|
+
Repeat the original interval to refresh. A returned `root_token_id` works
|
|
998
|
+
with `chain show --token-id` and `aeg render --root-token-id`.
|
|
999
|
+
|
|
965
1000
|
## Getting help
|
|
966
1001
|
|
|
967
1002
|
`aac --help` lists the command groups and `aac <command> --help` shows every
|
|
@@ -32,10 +32,10 @@ build-backend = "setuptools.build_meta"
|
|
|
32
32
|
|
|
33
33
|
[project]
|
|
34
34
|
name = "aac-cli"
|
|
35
|
-
version = "0.2.
|
|
35
|
+
version = "0.2.5"
|
|
36
36
|
description = "The aac platform CLI — headless operator interface to the AAC control plane (tenant registration, chain audit)."
|
|
37
37
|
readme = "README.md"
|
|
38
|
-
requires-python = ">=3.
|
|
38
|
+
requires-python = ">=3.11"
|
|
39
39
|
license = "Apache-2.0"
|
|
40
40
|
# PEP 639: the license FILE ships in the wheel's dist-info/licenses/
|
|
41
41
|
# (B119 — required for the PyPI channel; same pattern as
|
|
@@ -46,8 +46,8 @@ authors = [{ name = "Agent Authority Cloud Project" }]
|
|
|
46
46
|
dependencies = [
|
|
47
47
|
# HTTP client (same floor as the workspace).
|
|
48
48
|
# Config is stdlib configparser (INI — the AWS-CLI idiom,
|
|
49
|
-
# user-ratified Week 13 over TOML/YAML: zero-dep
|
|
50
|
-
#
|
|
49
|
+
# user-ratified Week 13 over TOML/YAML: zero-dep; the floor at
|
|
50
|
+
# ratification, 3.10, predated stdlib tomllib).
|
|
51
51
|
"httpx>=0.28",
|
|
52
52
|
# B144: local Ed25519 recovery-key generation, proof signing, and
|
|
53
53
|
# public-key fingerprint derivation. Private material never leaves the CLI.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|