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.
Files changed (58) hide show
  1. {aac_cli-0.2.12/aac_cli.egg-info → aac_cli-0.2.13}/PKG-INFO +21 -18
  2. {aac_cli-0.2.12 → aac_cli-0.2.13}/README.md +20 -17
  3. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/__init__.py +1 -1
  4. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_cli.py +4 -3
  5. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_health.py +5 -1
  6. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_layout.py +6 -4
  7. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/dev_material.py +47 -8
  8. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/init_cli.py +5 -1
  9. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/material_cases.py +3 -2
  10. {aac_cli-0.2.12 → aac_cli-0.2.13/aac_cli.egg-info}/PKG-INFO +21 -18
  11. {aac_cli-0.2.12 → aac_cli-0.2.13}/pyproject.toml +1 -1
  12. {aac_cli-0.2.12 → aac_cli-0.2.13}/LICENSE +0 -0
  13. {aac_cli-0.2.12 → aac_cli-0.2.13}/MANIFEST.in +0 -0
  14. {aac_cli-0.2.12 → aac_cli-0.2.13}/NOTICE +0 -0
  15. {aac_cli-0.2.12 → aac_cli-0.2.13}/THIRD_PARTY_NOTICES.md +0 -0
  16. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/__main__.py +0 -0
  17. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/__init__.py +0 -0
  18. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/cli.py +0 -0
  19. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/data/action-taken-v1.json +0 -0
  20. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/data/predicates-v1.json +0 -0
  21. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/data/renderer-source.json +0 -0
  22. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/from_sidecar.py +0 -0
  23. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/inputs.py +0 -0
  24. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/model.py +0 -0
  25. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/narrative.py +0 -0
  26. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/provenance.py +0 -0
  27. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/schemas.py +0 -0
  28. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/temporal.py +0 -0
  29. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/theme.py +0 -0
  30. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/timeline_source.py +0 -0
  31. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/_aeg/visualizer.py +0 -0
  32. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/admin_key_pem.py +0 -0
  33. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/aeg_cli.py +0 -0
  34. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/aeg_list.py +0 -0
  35. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_config.py +0 -0
  36. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/agent_record.py +0 -0
  37. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/api_key_rotation_state.py +0 -0
  38. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/chain_list.py +0 -0
  39. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/cli.py +0 -0
  40. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/config.py +0 -0
  41. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/config_render.py +0 -0
  42. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/idp_recovery.py +0 -0
  43. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/interrupts.py +0 -0
  44. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/profiles.py +0 -0
  45. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/reference.py +0 -0
  46. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/registration_state.py +0 -0
  47. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/safe_output.py +0 -0
  48. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/secure_files.py +0 -0
  49. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/sso_login.py +0 -0
  50. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/supplied_material.py +0 -0
  51. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli/trace_query.py +0 -0
  52. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/SOURCES.txt +0 -0
  53. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/dependency_links.txt +0 -0
  54. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/requires.txt +0 -0
  55. {aac_cli-0.2.12 → aac_cli-0.2.13}/aac_cli.egg-info/top_level.txt +0 -0
  56. {aac_cli-0.2.12 → aac_cli-0.2.13}/launchers/aac +0 -0
  57. {aac_cli-0.2.12 → aac_cli-0.2.13}/launchers/aeg +0 -0
  58. {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.12
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 seven days and the leaf certificates one day. Nothing
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 short-lived certificates
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 7-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`.
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 | 7 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 | 1 day; `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 | 1 day; `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 | 1 day; `aac agent renew` | No. reissue |
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 short-lived certificates; old ones archived
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 one-day
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 a day of expiry (or when `--ca` is given); a new CA is
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: six hours ahead for the one-day certificates, a day
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 | 1 day | 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 |
587
- | Development CA | 7 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 a day 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
+ | 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 once
594
- a week that renewal also replaces the development CA (`renew` then reports
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 seven days and the leaf certificates one day. Nothing
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 short-lived certificates
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 7-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`.
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 | 7 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 | 1 day; `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 | 1 day; `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 | 1 day; `aac agent renew` | No. reissue |
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 short-lived certificates; old ones archived
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 one-day
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 a day of expiry (or when `--ca` is given); a new CA is
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: six hours ahead for the one-day certificates, a day
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 | 1 day | 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 |
560
- | Development CA | 7 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 a day 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
+ | 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 once
567
- a week that renewal also replaces the development CA (`renew` then reports
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
@@ -10,4 +10,4 @@ entrypoint (`aac_cli.cli:entrypoint`).
10
10
  # test in bin/tests/test_cli_version_parity.py. A literal keeps the
11
11
  # shipped code free of import-time metadata lookups (and their
12
12
  # not-installed failure mode).
13
- __version__ = "0.2.12"
13
+ __version__ = "0.2.13"
@@ -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 one-day
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 short-lived certificates; archive the old material.",
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 one day of expiry, or with --ca, and a new CA needs the "
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
- (ca_report_label(material_source), agent.ca_certificate, dev_material.CA_RENEWAL_WINDOW),
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="1 day" if not supplied else "your issuer decides",
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="1 day" if not supplied else "your issuer decides",
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="1 day" if not supplied else "your issuer decides",
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="7 days",
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
- and lifetimes as the public starter guide's OpenSSL recipe:
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 seven-day CA and one-day leaf certificates.
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=7)
38
- LEAF_VALIDITY = timedelta(days=1)
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
- LEAF_RENEWAL_WINDOW = timedelta(hours=6)
42
- CA_RENEWAL_WINDOW = timedelta(days=1)
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 one-day SVID-style certificate: empty subject, critical SPIFFE URI SAN.
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 one-day TLS server certificate for the configured connection names."""
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
- (ca_report_label(material_source), agent.ca_certificate, dev_material.CA_RENEWAL_WINDOW),
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 7-day certificate authority and keeps its private key in the agent's keep/ folder",
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.12
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 seven days and the leaf certificates one day. Nothing
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 short-lived certificates
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 7-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`.
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 | 7 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 | 1 day; `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 | 1 day; `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 | 1 day; `aac agent renew` | No. reissue |
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 short-lived certificates; old ones archived
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 one-day
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 a day of expiry (or when `--ca` is given); a new CA is
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: six hours ahead for the one-day certificates, a day
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 | 1 day | 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 |
587
- | Development CA | 7 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 a day 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
+ | 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 once
594
- a week that renewal also replaces the development CA (`renew` then reports
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.12"
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