aac-cli 0.2.12__tar.gz → 0.2.13__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.12/aac_cli.egg-info → aac_cli-0.2.13}/PKG-INFO +21 -18
- {aac_cli-0.2.12 → aac_cli-0.2.13}/README.md +20 -17
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/__init__.py +1 -1
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_cli.py +4 -3
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_health.py +5 -1
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_layout.py +6 -4
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/dev_material.py +47 -8
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/init_cli.py +5 -1
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/material_cases.py +3 -2
- {aac_cli-0.2.12 → aac_cli-0.2.13/aac_cli.egg-info}/PKG-INFO +21 -18
- {aac_cli-0.2.12 → aac_cli-0.2.13}/pyproject.toml +1 -1
- {aac_cli-0.2.12 → aac_cli-0.2.13}/LICENSE +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/MANIFEST.in +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/NOTICE +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/THIRD_PARTY_NOTICES.md +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/__main__.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/__init__.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/cli.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/data/action-taken-v1.json +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/data/predicates-v1.json +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/data/renderer-source.json +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/from_sidecar.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/inputs.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/model.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/narrative.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/provenance.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/schemas.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/temporal.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/theme.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/timeline_source.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/visualizer.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/admin_key_pem.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/aeg_cli.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/aeg_list.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_config.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_record.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/api_key_rotation_state.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/chain_list.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/cli.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/config.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/config_render.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/idp_recovery.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/interrupts.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/profiles.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/reference.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/registration_state.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/safe_output.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/secure_files.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/sso_login.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/supplied_material.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/trace_query.py +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/SOURCES.txt +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/dependency_links.txt +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/requires.txt +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/top_level.txt +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/launchers/aac +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/launchers/aeg +0 -0
- {aac_cli-0.2.12 → aac_cli-0.2.13}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aac-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.13
|
|
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
|
|
@@ -184,7 +184,7 @@ never asks you to pick between GitHub and Google again.
|
|
|
184
184
|
configuration references it by path.
|
|
185
185
|
|
|
186
186
|
**By default everything `aac init` generates is development material.** The
|
|
187
|
-
development CA lives
|
|
187
|
+
development CA lives 365 days and the leaf certificates 90 days. Nothing
|
|
188
188
|
there qualifies for production, whatever the tenant's domain. If your own
|
|
189
189
|
issuer signs your agent's certificates instead, see "Two ways to get your
|
|
190
190
|
agent's certificates" below; moving to production also means a tenant-admin
|
|
@@ -206,7 +206,7 @@ three commands look after it:
|
|
|
206
206
|
|
|
207
207
|
```bash
|
|
208
208
|
aac agent status --agent orders # what exists, what is due, and the next step
|
|
209
|
-
aac agent renew --agent orders # replace the
|
|
209
|
+
aac agent renew --agent orders # replace the certificates
|
|
210
210
|
aac agent list # every agent on this machine
|
|
211
211
|
```
|
|
212
212
|
|
|
@@ -430,11 +430,11 @@ tell you later and `aac agent renew` behaves accordingly.
|
|
|
430
430
|
|
|
431
431
|
The laptop case. The CLI creates a certificate authority on this machine and signs the agent's identity, receipt and HTTPS certificates with it.
|
|
432
432
|
|
|
433
|
-
**Flags.** No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` and `--ca-cert-file` together; neither one alone.
|
|
433
|
+
**Flags.** No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` and `--ca-cert-file` together; neither one alone. A CA that expires before the certificates it would sign is refused.
|
|
434
434
|
|
|
435
435
|
**Keys and signatures.** The CA and the two identity keys are Ed25519; the HTTPS key is EC P-256.
|
|
436
436
|
|
|
437
|
-
**The CLI** creates a
|
|
437
|
+
**The CLI** creates a 365-day certificate authority and keeps its private key in the agent's keep/ folder; issues the workload, receipt and HTTPS certificates; publishes the CA certificate as a trust anchor named `<agent>-dev-ca`.
|
|
438
438
|
|
|
439
439
|
**The CLI does not** ask you for anything from your own certificate authority.
|
|
440
440
|
|
|
@@ -518,10 +518,10 @@ signs instead of this tool — see
|
|
|
518
518
|
| 2 | tenant_admin_session | `~/.aac/credentials/<tenant-id>.session` | CLI admin calls | hours; `aac sso login` | No. sign in again |
|
|
519
519
|
| 3 | tenant_admin_signing_key | `~/.aac/tenants/<tenant-id>/tenant-admin.pem`, `~/.aac/tenants/<tenant-id>/tenant-admin.pub.pem` | the publisher signs trust-material uploads; the public half is registered with AAC | until rotated; `aac tenant rotate-admin-key` | **Recommended.** recommended for developer tenants (loss needs `aac tenant rotate-admin-key`; a lost public half is derived from the private key); production custody belongs in an HSM/KMS, not a password manager |
|
|
520
520
|
| 4 | root_signing_key | `~/.aac/agents/<agent>/sidecar/root.pem`, `~/.aac/agents/<agent>/sidecar/root.pub.pem`, `~/.aac/tenants/<tenant-id>/root-keys/<agent>-root-v1.pub.pem` | the sidecar mints authority chains; the public half is published under the key id | until you retire its key id (root key ids are fixed per agent name) | No. never restore the private key: a replacement agent gets a new name and therefore a new key id, published alongside the old one until the old one is retired; its public copies are recreated from it |
|
|
521
|
-
| 5 | development_ca | `~/.aac/agents/<agent>/keep/ca.key`, `~/.aac/agents/<agent>/sidecar/ca.crt`, `~/.aac/agents/<agent>/agent/ca.crt`, `~/.aac/tenants/<tenant-id>/spiffe-bundle/<agent>-dev-ca.ca.pem` | signs the workload, terminal and TLS certificates; peers trust it via the published bundle |
|
|
522
|
-
| 6 | workload_svid | `~/.aac/agents/<agent>/sidecar/workload.key`, `~/.aac/agents/<agent>/sidecar/workload.crt` | the sidecar's SPIFFE identity: proves on every live request that this workload holds the key behind its certificate |
|
|
523
|
-
| 7 | terminal_attestation | `~/.aac/agents/<agent>/sidecar/terminal.key`, `~/.aac/agents/<agent>/sidecar/terminal.crt` | signs the receipt (terminal attestation) the sidecar issues when this workload completes a delegated request; auditors verify it offline against your published CA; setup gives it its own key so the two signing jobs stay separate, but a receipt is verified against your published CA and the expected agent identity, which the workload certificate also satisfies — treat both keys as one blast radius |
|
|
524
|
-
| 8 | https_tls | `~/.aac/agents/<agent>/sidecar/server.key`, `~/.aac/agents/<agent>/sidecar/server.crt` | the sidecar's HTTPS listener |
|
|
521
|
+
| 5 | development_ca | `~/.aac/agents/<agent>/keep/ca.key`, `~/.aac/agents/<agent>/sidecar/ca.crt`, `~/.aac/agents/<agent>/agent/ca.crt`, `~/.aac/tenants/<tenant-id>/spiffe-bundle/<agent>-dev-ca.ca.pem` | signs the workload, terminal and TLS certificates; peers trust it via the published bundle | 365 days; `aac agent renew --ca` | No. development only; reissue; a lost copy of the certificate is copied back from `sidecar/ca.crt` |
|
|
522
|
+
| 6 | workload_svid | `~/.aac/agents/<agent>/sidecar/workload.key`, `~/.aac/agents/<agent>/sidecar/workload.crt` | the sidecar's SPIFFE identity: proves on every live request that this workload holds the key behind its certificate | 90 days; `aac agent renew` | No. reissue |
|
|
523
|
+
| 7 | terminal_attestation | `~/.aac/agents/<agent>/sidecar/terminal.key`, `~/.aac/agents/<agent>/sidecar/terminal.crt` | signs the receipt (terminal attestation) the sidecar issues when this workload completes a delegated request; auditors verify it offline against your published CA; setup gives it its own key so the two signing jobs stay separate, but a receipt is verified against your published CA and the expected agent identity, which the workload certificate also satisfies — treat both keys as one blast radius | 90 days; `aac agent renew` | No. reissue |
|
|
524
|
+
| 8 | https_tls | `~/.aac/agents/<agent>/sidecar/server.key`, `~/.aac/agents/<agent>/sidecar/server.crt` | the sidecar's HTTPS listener | 90 days; `aac agent renew` | No. reissue |
|
|
525
525
|
| 9 | outbound_ca_bundle | `~/.aac/agents/<agent>/sidecar/outbound-ca.pem` | the sidecar verifies TLS to AAC and configured peers | rebuilt by renew; `aac agent renew` | No. derived |
|
|
526
526
|
| 10 | pairing_secret | `~/.aac/agents/<agent>/agent/pairing.secret` | the sidecar and its agent authenticate each other (same bytes in both) | until regenerated | No. regenerable; both processes must read the same file |
|
|
527
527
|
| 11 | agent_record | `~/.aac/agents/<agent>/record.json` | the agent's identities and progress; every `aac agent` verb reads it first | for the life of the agent | **Recommended.** cannot be recreated by any command; without it start a new agent under a new name (see the new-computer setup procedure) |
|
|
@@ -537,15 +537,15 @@ the machine is healthy. Everything else is regenerated.
|
|
|
537
537
|
```bash
|
|
538
538
|
aac agent status --agent orders --output table # what exists, expiry, permissions, next command
|
|
539
539
|
aac agent status --agent orders --remote # also: is the public trust material visible?
|
|
540
|
-
aac agent renew --agent orders # replace the
|
|
540
|
+
aac agent renew --agent orders # replace the certificates; old ones archived
|
|
541
541
|
aac agent list # every agent on this machine, with its case
|
|
542
542
|
aac init --profile stage --agent orders --layout container # write the settings again, container paths
|
|
543
543
|
```
|
|
544
544
|
|
|
545
545
|
`status` works offline by default and exits with code 3 when material is
|
|
546
|
-
missing, expired or unsafely permissioned. `renew` reissues the
|
|
546
|
+
missing, expired or unsafely permissioned. `renew` reissues the 90-day
|
|
547
547
|
certificates with fresh keys, and reissues the development CA only when it
|
|
548
|
-
is expired or within
|
|
548
|
+
is expired or within 90 days of expiry (or when `--ca` is given); a new CA is
|
|
549
549
|
published under the next anchor id and needs the publisher restarted. For an
|
|
550
550
|
agent whose own issuer signed its certificates, `renew` cannot reissue
|
|
551
551
|
anything: it takes the replacements your issuer produced, through the same
|
|
@@ -578,20 +578,23 @@ id.
|
|
|
578
578
|
|
|
579
579
|
It is the certificates that expire, and renewing replaces their keys with
|
|
580
580
|
them. `aac agent status` shows when each certificate runs out and flags
|
|
581
|
-
it before it does:
|
|
582
|
-
ahead for the development CA.
|
|
581
|
+
it before it does: seven days ahead for the 90-day certificates, 90 days
|
|
582
|
+
ahead for the development CA. That CA window covers a whole leaf lifetime, so
|
|
583
|
+
a renewal never issues a certificate that would outlive its CA. Certificates
|
|
584
|
+
your own issuer signed get the seven-day heads-up for the CA as well.
|
|
583
585
|
|
|
584
586
|
| Material | Lasts | When it runs out | What to do |
|
|
585
587
|
|---|---|---|---|
|
|
586
|
-
| Workload, terminal-attestation and HTTPS certificates |
|
|
587
|
-
| Development CA |
|
|
588
|
+
| Workload, terminal-attestation and HTTPS certificates | 90 days | the sidecar can no longer prove its identity, sign receipts or serve HTTPS | `aac agent renew --agent <name>`, then restart the sidecar so it loads them |
|
|
589
|
+
| Development CA | 365 days | certificates it signed stop being trusted, and no new ones can be issued | `renew` also replaces the CA when it is expired or within 90 days of expiry, or when `--ca` is given, and then reissues every certificate under it: restart the publisher so the new CA is published, restart the sidecar and anything else that trusted the old CA, and confirm with `aac agent status --agent <name> --remote` |
|
|
588
590
|
| Tenant-admin session | hours | administration commands ask you to sign in again | `aac sso login` |
|
|
589
591
|
| Tenant API key, tenant-admin signing key, root signing key | do not expire | — | replaced only on purpose: see "Keys" and "Setting up aac-cli on a new computer" |
|
|
590
592
|
|
|
591
593
|
A simple routine: when you start work, run
|
|
592
594
|
`aac agent status --agent <name>`, and when it names renewal, run
|
|
593
|
-
`aac agent renew --agent <name>` and restart the sidecar. About
|
|
594
|
-
|
|
595
|
+
`aac agent renew --agent <name>` and restart the sidecar. About every nine
|
|
596
|
+
months, once the CA is within 90 days of expiry, that renewal also replaces
|
|
597
|
+
the development CA (`renew` then reports
|
|
595
598
|
`republication_required: true`): restart the publisher, the sidecar and the
|
|
596
599
|
agent, and anything else that trusted the old CA. Renewing is safe to
|
|
597
600
|
repeat, but it is not a no-op: every run issues fresh keys and moves the old
|
|
@@ -157,7 +157,7 @@ never asks you to pick between GitHub and Google again.
|
|
|
157
157
|
configuration references it by path.
|
|
158
158
|
|
|
159
159
|
**By default everything `aac init` generates is development material.** The
|
|
160
|
-
development CA lives
|
|
160
|
+
development CA lives 365 days and the leaf certificates 90 days. Nothing
|
|
161
161
|
there qualifies for production, whatever the tenant's domain. If your own
|
|
162
162
|
issuer signs your agent's certificates instead, see "Two ways to get your
|
|
163
163
|
agent's certificates" below; moving to production also means a tenant-admin
|
|
@@ -179,7 +179,7 @@ three commands look after it:
|
|
|
179
179
|
|
|
180
180
|
```bash
|
|
181
181
|
aac agent status --agent orders # what exists, what is due, and the next step
|
|
182
|
-
aac agent renew --agent orders # replace the
|
|
182
|
+
aac agent renew --agent orders # replace the certificates
|
|
183
183
|
aac agent list # every agent on this machine
|
|
184
184
|
```
|
|
185
185
|
|
|
@@ -403,11 +403,11 @@ tell you later and `aac agent renew` behaves accordingly.
|
|
|
403
403
|
|
|
404
404
|
The laptop case. The CLI creates a certificate authority on this machine and signs the agent's identity, receipt and HTTPS certificates with it.
|
|
405
405
|
|
|
406
|
-
**Flags.** No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` and `--ca-cert-file` together; neither one alone.
|
|
406
|
+
**Flags.** No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` and `--ca-cert-file` together; neither one alone. A CA that expires before the certificates it would sign is refused.
|
|
407
407
|
|
|
408
408
|
**Keys and signatures.** The CA and the two identity keys are Ed25519; the HTTPS key is EC P-256.
|
|
409
409
|
|
|
410
|
-
**The CLI** creates a
|
|
410
|
+
**The CLI** creates a 365-day certificate authority and keeps its private key in the agent's keep/ folder; issues the workload, receipt and HTTPS certificates; publishes the CA certificate as a trust anchor named `<agent>-dev-ca`.
|
|
411
411
|
|
|
412
412
|
**The CLI does not** ask you for anything from your own certificate authority.
|
|
413
413
|
|
|
@@ -491,10 +491,10 @@ signs instead of this tool — see
|
|
|
491
491
|
| 2 | tenant_admin_session | `~/.aac/credentials/<tenant-id>.session` | CLI admin calls | hours; `aac sso login` | No. sign in again |
|
|
492
492
|
| 3 | tenant_admin_signing_key | `~/.aac/tenants/<tenant-id>/tenant-admin.pem`, `~/.aac/tenants/<tenant-id>/tenant-admin.pub.pem` | the publisher signs trust-material uploads; the public half is registered with AAC | until rotated; `aac tenant rotate-admin-key` | **Recommended.** recommended for developer tenants (loss needs `aac tenant rotate-admin-key`; a lost public half is derived from the private key); production custody belongs in an HSM/KMS, not a password manager |
|
|
493
493
|
| 4 | root_signing_key | `~/.aac/agents/<agent>/sidecar/root.pem`, `~/.aac/agents/<agent>/sidecar/root.pub.pem`, `~/.aac/tenants/<tenant-id>/root-keys/<agent>-root-v1.pub.pem` | the sidecar mints authority chains; the public half is published under the key id | until you retire its key id (root key ids are fixed per agent name) | No. never restore the private key: a replacement agent gets a new name and therefore a new key id, published alongside the old one until the old one is retired; its public copies are recreated from it |
|
|
494
|
-
| 5 | development_ca | `~/.aac/agents/<agent>/keep/ca.key`, `~/.aac/agents/<agent>/sidecar/ca.crt`, `~/.aac/agents/<agent>/agent/ca.crt`, `~/.aac/tenants/<tenant-id>/spiffe-bundle/<agent>-dev-ca.ca.pem` | signs the workload, terminal and TLS certificates; peers trust it via the published bundle |
|
|
495
|
-
| 6 | workload_svid | `~/.aac/agents/<agent>/sidecar/workload.key`, `~/.aac/agents/<agent>/sidecar/workload.crt` | the sidecar's SPIFFE identity: proves on every live request that this workload holds the key behind its certificate |
|
|
496
|
-
| 7 | terminal_attestation | `~/.aac/agents/<agent>/sidecar/terminal.key`, `~/.aac/agents/<agent>/sidecar/terminal.crt` | signs the receipt (terminal attestation) the sidecar issues when this workload completes a delegated request; auditors verify it offline against your published CA; setup gives it its own key so the two signing jobs stay separate, but a receipt is verified against your published CA and the expected agent identity, which the workload certificate also satisfies — treat both keys as one blast radius |
|
|
497
|
-
| 8 | https_tls | `~/.aac/agents/<agent>/sidecar/server.key`, `~/.aac/agents/<agent>/sidecar/server.crt` | the sidecar's HTTPS listener |
|
|
494
|
+
| 5 | development_ca | `~/.aac/agents/<agent>/keep/ca.key`, `~/.aac/agents/<agent>/sidecar/ca.crt`, `~/.aac/agents/<agent>/agent/ca.crt`, `~/.aac/tenants/<tenant-id>/spiffe-bundle/<agent>-dev-ca.ca.pem` | signs the workload, terminal and TLS certificates; peers trust it via the published bundle | 365 days; `aac agent renew --ca` | No. development only; reissue; a lost copy of the certificate is copied back from `sidecar/ca.crt` |
|
|
495
|
+
| 6 | workload_svid | `~/.aac/agents/<agent>/sidecar/workload.key`, `~/.aac/agents/<agent>/sidecar/workload.crt` | the sidecar's SPIFFE identity: proves on every live request that this workload holds the key behind its certificate | 90 days; `aac agent renew` | No. reissue |
|
|
496
|
+
| 7 | terminal_attestation | `~/.aac/agents/<agent>/sidecar/terminal.key`, `~/.aac/agents/<agent>/sidecar/terminal.crt` | signs the receipt (terminal attestation) the sidecar issues when this workload completes a delegated request; auditors verify it offline against your published CA; setup gives it its own key so the two signing jobs stay separate, but a receipt is verified against your published CA and the expected agent identity, which the workload certificate also satisfies — treat both keys as one blast radius | 90 days; `aac agent renew` | No. reissue |
|
|
497
|
+
| 8 | https_tls | `~/.aac/agents/<agent>/sidecar/server.key`, `~/.aac/agents/<agent>/sidecar/server.crt` | the sidecar's HTTPS listener | 90 days; `aac agent renew` | No. reissue |
|
|
498
498
|
| 9 | outbound_ca_bundle | `~/.aac/agents/<agent>/sidecar/outbound-ca.pem` | the sidecar verifies TLS to AAC and configured peers | rebuilt by renew; `aac agent renew` | No. derived |
|
|
499
499
|
| 10 | pairing_secret | `~/.aac/agents/<agent>/agent/pairing.secret` | the sidecar and its agent authenticate each other (same bytes in both) | until regenerated | No. regenerable; both processes must read the same file |
|
|
500
500
|
| 11 | agent_record | `~/.aac/agents/<agent>/record.json` | the agent's identities and progress; every `aac agent` verb reads it first | for the life of the agent | **Recommended.** cannot be recreated by any command; without it start a new agent under a new name (see the new-computer setup procedure) |
|
|
@@ -510,15 +510,15 @@ the machine is healthy. Everything else is regenerated.
|
|
|
510
510
|
```bash
|
|
511
511
|
aac agent status --agent orders --output table # what exists, expiry, permissions, next command
|
|
512
512
|
aac agent status --agent orders --remote # also: is the public trust material visible?
|
|
513
|
-
aac agent renew --agent orders # replace the
|
|
513
|
+
aac agent renew --agent orders # replace the certificates; old ones archived
|
|
514
514
|
aac agent list # every agent on this machine, with its case
|
|
515
515
|
aac init --profile stage --agent orders --layout container # write the settings again, container paths
|
|
516
516
|
```
|
|
517
517
|
|
|
518
518
|
`status` works offline by default and exits with code 3 when material is
|
|
519
|
-
missing, expired or unsafely permissioned. `renew` reissues the
|
|
519
|
+
missing, expired or unsafely permissioned. `renew` reissues the 90-day
|
|
520
520
|
certificates with fresh keys, and reissues the development CA only when it
|
|
521
|
-
is expired or within
|
|
521
|
+
is expired or within 90 days of expiry (or when `--ca` is given); a new CA is
|
|
522
522
|
published under the next anchor id and needs the publisher restarted. For an
|
|
523
523
|
agent whose own issuer signed its certificates, `renew` cannot reissue
|
|
524
524
|
anything: it takes the replacements your issuer produced, through the same
|
|
@@ -551,20 +551,23 @@ id.
|
|
|
551
551
|
|
|
552
552
|
It is the certificates that expire, and renewing replaces their keys with
|
|
553
553
|
them. `aac agent status` shows when each certificate runs out and flags
|
|
554
|
-
it before it does:
|
|
555
|
-
ahead for the development CA.
|
|
554
|
+
it before it does: seven days ahead for the 90-day certificates, 90 days
|
|
555
|
+
ahead for the development CA. That CA window covers a whole leaf lifetime, so
|
|
556
|
+
a renewal never issues a certificate that would outlive its CA. Certificates
|
|
557
|
+
your own issuer signed get the seven-day heads-up for the CA as well.
|
|
556
558
|
|
|
557
559
|
| Material | Lasts | When it runs out | What to do |
|
|
558
560
|
|---|---|---|---|
|
|
559
|
-
| Workload, terminal-attestation and HTTPS certificates |
|
|
560
|
-
| Development CA |
|
|
561
|
+
| Workload, terminal-attestation and HTTPS certificates | 90 days | the sidecar can no longer prove its identity, sign receipts or serve HTTPS | `aac agent renew --agent <name>`, then restart the sidecar so it loads them |
|
|
562
|
+
| Development CA | 365 days | certificates it signed stop being trusted, and no new ones can be issued | `renew` also replaces the CA when it is expired or within 90 days of expiry, or when `--ca` is given, and then reissues every certificate under it: restart the publisher so the new CA is published, restart the sidecar and anything else that trusted the old CA, and confirm with `aac agent status --agent <name> --remote` |
|
|
561
563
|
| Tenant-admin session | hours | administration commands ask you to sign in again | `aac sso login` |
|
|
562
564
|
| Tenant API key, tenant-admin signing key, root signing key | do not expire | — | replaced only on purpose: see "Keys" and "Setting up aac-cli on a new computer" |
|
|
563
565
|
|
|
564
566
|
A simple routine: when you start work, run
|
|
565
567
|
`aac agent status --agent <name>`, and when it names renewal, run
|
|
566
|
-
`aac agent renew --agent <name>` and restart the sidecar. About
|
|
567
|
-
|
|
568
|
+
`aac agent renew --agent <name>` and restart the sidecar. About every nine
|
|
569
|
+
months, once the CA is within 90 days of expiry, that renewal also replaces
|
|
570
|
+
the development CA (`renew` then reports
|
|
568
571
|
`republication_required: true`): restart the publisher, the sidecar and the
|
|
569
572
|
agent, and anything else that trusted the old CA. Renewing is safe to
|
|
570
573
|
repeat, but it is not a no-op: every run issues fresh keys and moves the old
|
|
@@ -8,7 +8,7 @@ tenants:
|
|
|
8
8
|
domain, which of the two certificate cases the agent uses, and the single
|
|
9
9
|
next command. ``--remote`` adds trust-publication visibility through the
|
|
10
10
|
public trust endpoints.
|
|
11
|
-
* ``renew`` — in "The CLI creates a development CA" mode, reissues the
|
|
11
|
+
* ``renew`` — in "The CLI creates a development CA" mode, reissues the
|
|
12
12
|
workload, receipt and HTTPS certificates with fresh keys, and the CA only
|
|
13
13
|
when it is expired or inside its renewal window. With supplied certificates
|
|
14
14
|
it cannot reissue what it did not sign: it takes replacements from your
|
|
@@ -698,11 +698,12 @@ def add_agent_parser(nouns: argparse._SubParsersAction) -> None:
|
|
|
698
698
|
|
|
699
699
|
renew = verbs.add_parser(
|
|
700
700
|
"renew",
|
|
701
|
-
help="Replace the
|
|
701
|
+
help="Replace the agent's certificates; archive the old material.",
|
|
702
702
|
description=(
|
|
703
703
|
f'In "{case_for(MATERIAL_ISSUED_HERE).name}" mode, reissues the workload, receipt and '
|
|
704
704
|
"HTTPS certificates with new keys; the development CA is reissued only when "
|
|
705
|
-
"expired or within
|
|
705
|
+
f"expired or within {dev_material.describe_lifetime(dev_material.CA_RENEWAL_WINDOW)} "
|
|
706
|
+
"of expiry, or with --ca, and a new CA needs the "
|
|
706
707
|
f'publisher to publish the new anchor. In "{case_for(MATERIAL_SUPPLIED).name}" mode nothing is '
|
|
707
708
|
"reissued: pass the replacement certificates your issuer produced, each with its "
|
|
708
709
|
"key file, and --ca-cert-file if your CA certificate changed too."
|
|
@@ -100,7 +100,11 @@ def _certificate_reports(
|
|
|
100
100
|
) -> dict[str, CertificateReport]:
|
|
101
101
|
reports: dict[str, CertificateReport] = {}
|
|
102
102
|
for label, path, window in (
|
|
103
|
-
(
|
|
103
|
+
(
|
|
104
|
+
ca_report_label(material_source),
|
|
105
|
+
agent.ca_certificate,
|
|
106
|
+
dev_material.ca_renewal_window(material_source),
|
|
107
|
+
),
|
|
104
108
|
("workload", agent.workload_certificate, dev_material.LEAF_RENEWAL_WINDOW),
|
|
105
109
|
("terminal", agent.terminal_certificate, dev_material.LEAF_RENEWAL_WINDOW),
|
|
106
110
|
("tls_server", agent.server_certificate, dev_material.LEAF_RENEWAL_WINDOW),
|
|
@@ -25,6 +25,7 @@ from aac_cli.config import (
|
|
|
25
25
|
CliUsageError,
|
|
26
26
|
cli_home,
|
|
27
27
|
)
|
|
28
|
+
from aac_cli.dev_material import DEV_CA_VALIDITY, LEAF_VALIDITY, describe_lifetime
|
|
28
29
|
from aac_cli.material_cases import MATERIAL_ISSUED_HERE, MATERIAL_SUPPLIED
|
|
29
30
|
|
|
30
31
|
TENANTS_DIRECTORY = "tenants"
|
|
@@ -303,6 +304,7 @@ def material_inventory(
|
|
|
303
304
|
if supplied
|
|
304
305
|
else "aac agent renew"
|
|
305
306
|
)
|
|
307
|
+
leaf_lifetime = describe_lifetime(LEAF_VALIDITY)
|
|
306
308
|
return (
|
|
307
309
|
InventoryItem(
|
|
308
310
|
role="tenant_api_key",
|
|
@@ -364,7 +366,7 @@ def material_inventory(
|
|
|
364
366
|
"the sidecar's SPIFFE identity: proves on every live request that this workload "
|
|
365
367
|
"holds the key behind its certificate"
|
|
366
368
|
),
|
|
367
|
-
lifetime=
|
|
369
|
+
lifetime=leaf_lifetime if not supplied else "your issuer decides",
|
|
368
370
|
backup=BACKUP_NO,
|
|
369
371
|
backup_note="reissue" if not supplied else "your issuer holds the original",
|
|
370
372
|
renew_with=leaf_renewal,
|
|
@@ -382,7 +384,7 @@ def material_inventory(
|
|
|
382
384
|
"which the workload certificate also satisfies — treat both keys as one blast "
|
|
383
385
|
"radius"
|
|
384
386
|
),
|
|
385
|
-
lifetime=
|
|
387
|
+
lifetime=leaf_lifetime if not supplied else "your issuer decides",
|
|
386
388
|
backup=BACKUP_NO,
|
|
387
389
|
backup_note="reissue" if not supplied else "your issuer holds the original",
|
|
388
390
|
renew_with=leaf_renewal,
|
|
@@ -393,7 +395,7 @@ def material_inventory(
|
|
|
393
395
|
kind="certificate",
|
|
394
396
|
paths=(agent.server_key, agent.server_certificate),
|
|
395
397
|
used_for="the sidecar's HTTPS listener",
|
|
396
|
-
lifetime=
|
|
398
|
+
lifetime=leaf_lifetime if not supplied else "your issuer decides",
|
|
397
399
|
backup=BACKUP_NO,
|
|
398
400
|
backup_note="reissue" if not supplied else "your issuer holds the original",
|
|
399
401
|
renew_with=leaf_renewal,
|
|
@@ -496,7 +498,7 @@ def _ca_inventory_item(
|
|
|
496
498
|
tenant.published_ca_certificate(anchor_id),
|
|
497
499
|
),
|
|
498
500
|
used_for="signs the workload, terminal and TLS certificates; peers trust it via the published bundle",
|
|
499
|
-
lifetime=
|
|
501
|
+
lifetime=describe_lifetime(DEV_CA_VALIDITY),
|
|
500
502
|
backup=BACKUP_NO,
|
|
501
503
|
backup_note=(
|
|
502
504
|
"development only; reissue; a lost copy of the certificate is copied back "
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
Everything here is DEVELOPMENT material for a local workload whose sidecar,
|
|
4
4
|
publisher and CLI run on one machine. It is generated in-process with the
|
|
5
5
|
`cryptography` dependency the CLI already carries, with the same algorithms
|
|
6
|
-
|
|
6
|
+
as the public starter guide's OpenSSL recipe:
|
|
7
7
|
|
|
8
8
|
* Ed25519 for the development CA, the workload SVID key, the terminal
|
|
9
9
|
attestation key, the root-signing key and the tenant-admin key;
|
|
10
10
|
* P-256 for the configured HTTPS server key (browsers and Go's TLS stack both
|
|
11
11
|
accept it without configuration);
|
|
12
|
-
* a
|
|
12
|
+
* a 365-day CA and 90-day leaf certificates (B337), long enough that an
|
|
13
|
+
evaluator who comes back weeks later finds the agent still usable; the
|
|
14
|
+
guide's hand-built OpenSSL recipe keeps its own shorter figures.
|
|
13
15
|
|
|
14
16
|
None of this qualifies for production regardless of the tenant's hosted
|
|
15
17
|
domain (CLI Config+Profile Spec, B241 amendment §B). Production promotion is
|
|
@@ -32,14 +34,17 @@ from cryptography.hazmat.primitives.asymmetric import ec, ed25519
|
|
|
32
34
|
from cryptography.x509.oid import ExtendedKeyUsageOID, NameOID
|
|
33
35
|
|
|
34
36
|
from aac_cli.config import CliConfigError
|
|
37
|
+
from aac_cli.material_cases import MATERIAL_ISSUED_HERE
|
|
35
38
|
from aac_cli.secure_files import read_private_file, write_private_file
|
|
36
39
|
|
|
37
|
-
DEV_CA_VALIDITY = timedelta(days=
|
|
38
|
-
LEAF_VALIDITY = timedelta(days=
|
|
40
|
+
DEV_CA_VALIDITY = timedelta(days=365)
|
|
41
|
+
LEAF_VALIDITY = timedelta(days=90)
|
|
39
42
|
# Renewal windows: `agent renew` reissues material that is expired or
|
|
40
43
|
# expires within these windows; `agent status` warns at the same point.
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
# The CA window is at least the leaf lifetime (test_readme_facts asserts it),
|
|
45
|
+
# so a renewal that is about to issue leaves replaces a CA they would outlive.
|
|
46
|
+
LEAF_RENEWAL_WINDOW = timedelta(days=7)
|
|
47
|
+
CA_RENEWAL_WINDOW = timedelta(days=90)
|
|
43
48
|
# Certificates are backdated slightly so a sidecar whose clock trails the
|
|
44
49
|
# workstation by a few seconds does not reject a just-issued certificate.
|
|
45
50
|
CLOCK_SKEW_ALLOWANCE = timedelta(minutes=5)
|
|
@@ -54,6 +59,25 @@ def now_utc() -> datetime:
|
|
|
54
59
|
return datetime.now(timezone.utc)
|
|
55
60
|
|
|
56
61
|
|
|
62
|
+
def describe_lifetime(duration: timedelta) -> str:
|
|
63
|
+
"""A whole-day lifetime as the README and the inventory state it: '1 day', '90 days'."""
|
|
64
|
+
assert duration % timedelta(days=1) == timedelta(0), duration
|
|
65
|
+
return "1 day" if duration.days == 1 else f"{duration.days} days"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def ca_renewal_window(material_source: str) -> timedelta:
|
|
69
|
+
"""How far ahead of expiry a CA counts as due.
|
|
70
|
+
|
|
71
|
+
The CLI's own development CA is replaced a whole leaf lifetime ahead, so the
|
|
72
|
+
leaves `renew` is about to issue never outlive it. A supplied CA signs leaves
|
|
73
|
+
whose lifetime the CLI does not know and cannot reissue; it gets the same
|
|
74
|
+
heads-up as the leaves themselves.
|
|
75
|
+
"""
|
|
76
|
+
if material_source == MATERIAL_ISSUED_HERE:
|
|
77
|
+
return CA_RENEWAL_WINDOW
|
|
78
|
+
return LEAF_RENEWAL_WINDOW
|
|
79
|
+
|
|
80
|
+
|
|
57
81
|
# --- keys -----------------------------------------------------------------
|
|
58
82
|
|
|
59
83
|
|
|
@@ -184,6 +208,9 @@ def _leaf_builder(
|
|
|
184
208
|
ca_certificate: x509.Certificate, subject_key: PrivateKey, subject: x509.Name
|
|
185
209
|
) -> x509.CertificateBuilder:
|
|
186
210
|
not_before, not_after = _validity(LEAF_VALIDITY)
|
|
211
|
+
# A leaf never outlives its CA, whatever the clock did between the CA check and
|
|
212
|
+
# this issuance (external review S1): the encoded expiry is bounded by the CA's.
|
|
213
|
+
not_after = min(not_after, ca_certificate.not_valid_after_utc)
|
|
187
214
|
return (
|
|
188
215
|
x509.CertificateBuilder()
|
|
189
216
|
.subject_name(subject)
|
|
@@ -228,7 +255,7 @@ def issue_identity_certificate(
|
|
|
228
255
|
subject_key: IdentityKey,
|
|
229
256
|
spiffe_id: str,
|
|
230
257
|
) -> x509.Certificate:
|
|
231
|
-
"""A
|
|
258
|
+
"""A `LEAF_VALIDITY` SVID-style certificate: empty subject, critical SPIFFE URI SAN.
|
|
232
259
|
|
|
233
260
|
Only the CA key has to be Ed25519 (the development CA signs with it); the
|
|
234
261
|
subject key may be either type the sidecar accepts.
|
|
@@ -255,7 +282,7 @@ def issue_server_certificate(
|
|
|
255
282
|
server_key: ec.EllipticCurvePrivateKey,
|
|
256
283
|
names: list[str],
|
|
257
284
|
) -> x509.Certificate:
|
|
258
|
-
"""A
|
|
285
|
+
"""A `LEAF_VALIDITY` TLS server certificate for the configured connection names."""
|
|
259
286
|
subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "AAC HTTPS listener")])
|
|
260
287
|
sans: list[x509.GeneralName] = []
|
|
261
288
|
for name in names:
|
|
@@ -435,6 +462,10 @@ def issuer_unfitness_reasons(
|
|
|
435
462
|
|
|
436
463
|
|
|
437
464
|
def validate_supplied_ca(key: ed25519.Ed25519PrivateKey, certificate: x509.Certificate) -> None:
|
|
465
|
+
"""A reused development CA (`aac init --ca-key-file --ca-cert-file`) must be able to
|
|
466
|
+
sign now AND outlast the leaves `init` is about to issue under it; a leaf that
|
|
467
|
+
outlives its CA loses its chain long before its own expiry (external review M1).
|
|
468
|
+
"""
|
|
438
469
|
if certificate.public_key() != key.public_key():
|
|
439
470
|
raise CliConfigError("--ca-cert-file does not match the key in --ca-key-file")
|
|
440
471
|
reasons = ca_unfitness_reasons(certificate)
|
|
@@ -443,6 +474,14 @@ def validate_supplied_ca(key: ed25519.Ed25519PrivateKey, certificate: x509.Certi
|
|
|
443
474
|
"--ca-cert-file cannot issue development certificates: "
|
|
444
475
|
+ "; ".join(reason.text for reason in reasons)
|
|
445
476
|
)
|
|
477
|
+
_, leaf_not_after = _validity(LEAF_VALIDITY)
|
|
478
|
+
if certificate.not_valid_after_utc < leaf_not_after:
|
|
479
|
+
raise CliConfigError(
|
|
480
|
+
f"--ca-cert-file expires at {certificate.not_valid_after_utc.isoformat()}, before "
|
|
481
|
+
f"the {describe_lifetime(LEAF_VALIDITY)} the certificates it would sign now last "
|
|
482
|
+
f"(until {leaf_not_after.isoformat()}); pass a CA that lasts at least that long, "
|
|
483
|
+
"or leave both CA flags off and let aac init create one"
|
|
484
|
+
)
|
|
446
485
|
|
|
447
486
|
|
|
448
487
|
def validate_pairing_secret(secret: bytes, *, source: str) -> bytes:
|
|
@@ -1391,7 +1391,11 @@ def certificate_expiries(
|
|
|
1391
1391
|
) -> dict[str, str]:
|
|
1392
1392
|
expiries = {}
|
|
1393
1393
|
for label, path, window in (
|
|
1394
|
-
(
|
|
1394
|
+
(
|
|
1395
|
+
ca_report_label(material_source),
|
|
1396
|
+
agent.ca_certificate,
|
|
1397
|
+
dev_material.ca_renewal_window(material_source),
|
|
1398
|
+
),
|
|
1395
1399
|
("workload", agent.workload_certificate, dev_material.LEAF_RENEWAL_WINDOW),
|
|
1396
1400
|
("terminal", agent.terminal_certificate, dev_material.LEAF_RENEWAL_WINDOW),
|
|
1397
1401
|
("tls_server", agent.server_certificate, dev_material.LEAF_RENEWAL_WINDOW),
|
|
@@ -52,11 +52,12 @@ ISSUED_HERE = MaterialCase(
|
|
|
52
52
|
flags=("--ca-key-file", "--ca-cert-file"),
|
|
53
53
|
flags_note=(
|
|
54
54
|
"No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` "
|
|
55
|
-
"and `--ca-cert-file` together; neither one alone."
|
|
55
|
+
"and `--ca-cert-file` together; neither one alone. A CA that expires before the "
|
|
56
|
+
"certificates it would sign is refused."
|
|
56
57
|
),
|
|
57
58
|
key_profile="The CA and the two identity keys are Ed25519; the HTTPS key is EC P-256.",
|
|
58
59
|
cli_does=(
|
|
59
|
-
"creates a
|
|
60
|
+
"creates a 365-day certificate authority and keeps its private key in the agent's keep/ folder",
|
|
60
61
|
"issues the workload, receipt and HTTPS certificates",
|
|
61
62
|
"publishes the CA certificate as a trust anchor named `<agent>-dev-ca`",
|
|
62
63
|
),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aac-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.13
|
|
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
|
|
@@ -184,7 +184,7 @@ never asks you to pick between GitHub and Google again.
|
|
|
184
184
|
configuration references it by path.
|
|
185
185
|
|
|
186
186
|
**By default everything `aac init` generates is development material.** The
|
|
187
|
-
development CA lives
|
|
187
|
+
development CA lives 365 days and the leaf certificates 90 days. Nothing
|
|
188
188
|
there qualifies for production, whatever the tenant's domain. If your own
|
|
189
189
|
issuer signs your agent's certificates instead, see "Two ways to get your
|
|
190
190
|
agent's certificates" below; moving to production also means a tenant-admin
|
|
@@ -206,7 +206,7 @@ three commands look after it:
|
|
|
206
206
|
|
|
207
207
|
```bash
|
|
208
208
|
aac agent status --agent orders # what exists, what is due, and the next step
|
|
209
|
-
aac agent renew --agent orders # replace the
|
|
209
|
+
aac agent renew --agent orders # replace the certificates
|
|
210
210
|
aac agent list # every agent on this machine
|
|
211
211
|
```
|
|
212
212
|
|
|
@@ -430,11 +430,11 @@ tell you later and `aac agent renew` behaves accordingly.
|
|
|
430
430
|
|
|
431
431
|
The laptop case. The CLI creates a certificate authority on this machine and signs the agent's identity, receipt and HTTPS certificates with it.
|
|
432
432
|
|
|
433
|
-
**Flags.** No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` and `--ca-cert-file` together; neither one alone.
|
|
433
|
+
**Flags.** No flags are needed. To reuse a development CA across agents, pass `--ca-key-file` and `--ca-cert-file` together; neither one alone. A CA that expires before the certificates it would sign is refused.
|
|
434
434
|
|
|
435
435
|
**Keys and signatures.** The CA and the two identity keys are Ed25519; the HTTPS key is EC P-256.
|
|
436
436
|
|
|
437
|
-
**The CLI** creates a
|
|
437
|
+
**The CLI** creates a 365-day certificate authority and keeps its private key in the agent's keep/ folder; issues the workload, receipt and HTTPS certificates; publishes the CA certificate as a trust anchor named `<agent>-dev-ca`.
|
|
438
438
|
|
|
439
439
|
**The CLI does not** ask you for anything from your own certificate authority.
|
|
440
440
|
|
|
@@ -518,10 +518,10 @@ signs instead of this tool — see
|
|
|
518
518
|
| 2 | tenant_admin_session | `~/.aac/credentials/<tenant-id>.session` | CLI admin calls | hours; `aac sso login` | No. sign in again |
|
|
519
519
|
| 3 | tenant_admin_signing_key | `~/.aac/tenants/<tenant-id>/tenant-admin.pem`, `~/.aac/tenants/<tenant-id>/tenant-admin.pub.pem` | the publisher signs trust-material uploads; the public half is registered with AAC | until rotated; `aac tenant rotate-admin-key` | **Recommended.** recommended for developer tenants (loss needs `aac tenant rotate-admin-key`; a lost public half is derived from the private key); production custody belongs in an HSM/KMS, not a password manager |
|
|
520
520
|
| 4 | root_signing_key | `~/.aac/agents/<agent>/sidecar/root.pem`, `~/.aac/agents/<agent>/sidecar/root.pub.pem`, `~/.aac/tenants/<tenant-id>/root-keys/<agent>-root-v1.pub.pem` | the sidecar mints authority chains; the public half is published under the key id | until you retire its key id (root key ids are fixed per agent name) | No. never restore the private key: a replacement agent gets a new name and therefore a new key id, published alongside the old one until the old one is retired; its public copies are recreated from it |
|
|
521
|
-
| 5 | development_ca | `~/.aac/agents/<agent>/keep/ca.key`, `~/.aac/agents/<agent>/sidecar/ca.crt`, `~/.aac/agents/<agent>/agent/ca.crt`, `~/.aac/tenants/<tenant-id>/spiffe-bundle/<agent>-dev-ca.ca.pem` | signs the workload, terminal and TLS certificates; peers trust it via the published bundle |
|
|
522
|
-
| 6 | workload_svid | `~/.aac/agents/<agent>/sidecar/workload.key`, `~/.aac/agents/<agent>/sidecar/workload.crt` | the sidecar's SPIFFE identity: proves on every live request that this workload holds the key behind its certificate |
|
|
523
|
-
| 7 | terminal_attestation | `~/.aac/agents/<agent>/sidecar/terminal.key`, `~/.aac/agents/<agent>/sidecar/terminal.crt` | signs the receipt (terminal attestation) the sidecar issues when this workload completes a delegated request; auditors verify it offline against your published CA; setup gives it its own key so the two signing jobs stay separate, but a receipt is verified against your published CA and the expected agent identity, which the workload certificate also satisfies — treat both keys as one blast radius |
|
|
524
|
-
| 8 | https_tls | `~/.aac/agents/<agent>/sidecar/server.key`, `~/.aac/agents/<agent>/sidecar/server.crt` | the sidecar's HTTPS listener |
|
|
521
|
+
| 5 | development_ca | `~/.aac/agents/<agent>/keep/ca.key`, `~/.aac/agents/<agent>/sidecar/ca.crt`, `~/.aac/agents/<agent>/agent/ca.crt`, `~/.aac/tenants/<tenant-id>/spiffe-bundle/<agent>-dev-ca.ca.pem` | signs the workload, terminal and TLS certificates; peers trust it via the published bundle | 365 days; `aac agent renew --ca` | No. development only; reissue; a lost copy of the certificate is copied back from `sidecar/ca.crt` |
|
|
522
|
+
| 6 | workload_svid | `~/.aac/agents/<agent>/sidecar/workload.key`, `~/.aac/agents/<agent>/sidecar/workload.crt` | the sidecar's SPIFFE identity: proves on every live request that this workload holds the key behind its certificate | 90 days; `aac agent renew` | No. reissue |
|
|
523
|
+
| 7 | terminal_attestation | `~/.aac/agents/<agent>/sidecar/terminal.key`, `~/.aac/agents/<agent>/sidecar/terminal.crt` | signs the receipt (terminal attestation) the sidecar issues when this workload completes a delegated request; auditors verify it offline against your published CA; setup gives it its own key so the two signing jobs stay separate, but a receipt is verified against your published CA and the expected agent identity, which the workload certificate also satisfies — treat both keys as one blast radius | 90 days; `aac agent renew` | No. reissue |
|
|
524
|
+
| 8 | https_tls | `~/.aac/agents/<agent>/sidecar/server.key`, `~/.aac/agents/<agent>/sidecar/server.crt` | the sidecar's HTTPS listener | 90 days; `aac agent renew` | No. reissue |
|
|
525
525
|
| 9 | outbound_ca_bundle | `~/.aac/agents/<agent>/sidecar/outbound-ca.pem` | the sidecar verifies TLS to AAC and configured peers | rebuilt by renew; `aac agent renew` | No. derived |
|
|
526
526
|
| 10 | pairing_secret | `~/.aac/agents/<agent>/agent/pairing.secret` | the sidecar and its agent authenticate each other (same bytes in both) | until regenerated | No. regenerable; both processes must read the same file |
|
|
527
527
|
| 11 | agent_record | `~/.aac/agents/<agent>/record.json` | the agent's identities and progress; every `aac agent` verb reads it first | for the life of the agent | **Recommended.** cannot be recreated by any command; without it start a new agent under a new name (see the new-computer setup procedure) |
|
|
@@ -537,15 +537,15 @@ the machine is healthy. Everything else is regenerated.
|
|
|
537
537
|
```bash
|
|
538
538
|
aac agent status --agent orders --output table # what exists, expiry, permissions, next command
|
|
539
539
|
aac agent status --agent orders --remote # also: is the public trust material visible?
|
|
540
|
-
aac agent renew --agent orders # replace the
|
|
540
|
+
aac agent renew --agent orders # replace the certificates; old ones archived
|
|
541
541
|
aac agent list # every agent on this machine, with its case
|
|
542
542
|
aac init --profile stage --agent orders --layout container # write the settings again, container paths
|
|
543
543
|
```
|
|
544
544
|
|
|
545
545
|
`status` works offline by default and exits with code 3 when material is
|
|
546
|
-
missing, expired or unsafely permissioned. `renew` reissues the
|
|
546
|
+
missing, expired or unsafely permissioned. `renew` reissues the 90-day
|
|
547
547
|
certificates with fresh keys, and reissues the development CA only when it
|
|
548
|
-
is expired or within
|
|
548
|
+
is expired or within 90 days of expiry (or when `--ca` is given); a new CA is
|
|
549
549
|
published under the next anchor id and needs the publisher restarted. For an
|
|
550
550
|
agent whose own issuer signed its certificates, `renew` cannot reissue
|
|
551
551
|
anything: it takes the replacements your issuer produced, through the same
|
|
@@ -578,20 +578,23 @@ id.
|
|
|
578
578
|
|
|
579
579
|
It is the certificates that expire, and renewing replaces their keys with
|
|
580
580
|
them. `aac agent status` shows when each certificate runs out and flags
|
|
581
|
-
it before it does:
|
|
582
|
-
ahead for the development CA.
|
|
581
|
+
it before it does: seven days ahead for the 90-day certificates, 90 days
|
|
582
|
+
ahead for the development CA. That CA window covers a whole leaf lifetime, so
|
|
583
|
+
a renewal never issues a certificate that would outlive its CA. Certificates
|
|
584
|
+
your own issuer signed get the seven-day heads-up for the CA as well.
|
|
583
585
|
|
|
584
586
|
| Material | Lasts | When it runs out | What to do |
|
|
585
587
|
|---|---|---|---|
|
|
586
|
-
| Workload, terminal-attestation and HTTPS certificates |
|
|
587
|
-
| Development CA |
|
|
588
|
+
| Workload, terminal-attestation and HTTPS certificates | 90 days | the sidecar can no longer prove its identity, sign receipts or serve HTTPS | `aac agent renew --agent <name>`, then restart the sidecar so it loads them |
|
|
589
|
+
| Development CA | 365 days | certificates it signed stop being trusted, and no new ones can be issued | `renew` also replaces the CA when it is expired or within 90 days of expiry, or when `--ca` is given, and then reissues every certificate under it: restart the publisher so the new CA is published, restart the sidecar and anything else that trusted the old CA, and confirm with `aac agent status --agent <name> --remote` |
|
|
588
590
|
| Tenant-admin session | hours | administration commands ask you to sign in again | `aac sso login` |
|
|
589
591
|
| Tenant API key, tenant-admin signing key, root signing key | do not expire | — | replaced only on purpose: see "Keys" and "Setting up aac-cli on a new computer" |
|
|
590
592
|
|
|
591
593
|
A simple routine: when you start work, run
|
|
592
594
|
`aac agent status --agent <name>`, and when it names renewal, run
|
|
593
|
-
`aac agent renew --agent <name>` and restart the sidecar. About
|
|
594
|
-
|
|
595
|
+
`aac agent renew --agent <name>` and restart the sidecar. About every nine
|
|
596
|
+
months, once the CA is within 90 days of expiry, that renewal also replaces
|
|
597
|
+
the development CA (`renew` then reports
|
|
595
598
|
`republication_required: true`): restart the publisher, the sidecar and the
|
|
596
599
|
agent, and anything else that trusted the old CA. Renewing is safe to
|
|
597
600
|
repeat, but it is not a no-op: every run issues fresh keys and moves the old
|
|
@@ -32,7 +32,7 @@ build-backend = "setuptools.build_meta"
|
|
|
32
32
|
|
|
33
33
|
[project]
|
|
34
34
|
name = "aac-cli"
|
|
35
|
-
version = "0.2.
|
|
35
|
+
version = "0.2.13"
|
|
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
38
|
requires-python = ">=3.11"
|
|
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
|
|
File without changes
|
|
File without changes
|