aac-cli 0.2.0__tar.gz → 0.2.2__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.0/aac_cli.egg-info → aac_cli-0.2.2}/PKG-INFO +225 -41
- {aac_cli-0.2.0 → aac_cli-0.2.2}/README.md +224 -40
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/__init__.py +1 -1
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/agent_cli.py +17 -8
- aac_cli-0.2.2/aac_cli/agent_config.py +462 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/agent_layout.py +8 -6
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/agent_record.py +26 -5
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/cli.py +58 -4
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/config_render.py +69 -54
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/dev_material.py +31 -16
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/init_cli.py +116 -33
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/material_cases.py +3 -3
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/supplied_material.py +4 -4
- {aac_cli-0.2.0 → aac_cli-0.2.2/aac_cli.egg-info}/PKG-INFO +225 -41
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli.egg-info/SOURCES.txt +1 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/pyproject.toml +2 -2
- {aac_cli-0.2.0 → aac_cli-0.2.2}/LICENSE +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/MANIFEST.in +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/__main__.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/admin_key_pem.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/agent_health.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/api_key_rotation_state.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/config.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/idp_recovery.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/profiles.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/reference.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/registration_state.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/secure_files.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli/sso_login.py +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli.egg-info/dependency_links.txt +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli.egg-info/entry_points.txt +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli.egg-info/requires.txt +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/aac_cli.egg-info/top_level.txt +0 -0
- {aac_cli-0.2.0 → aac_cli-0.2.2}/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.2
|
|
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
|
|
@@ -24,6 +24,9 @@ which tenant they belong to and what they were authorised to do. A
|
|
|
24
24
|
runs beside an AAC sidecar that signs outgoing requests and verifies
|
|
25
25
|
incoming ones against public trust material the tenant publishes.
|
|
26
26
|
|
|
27
|
+
New to AAC? [What AAC is for](https://cascadeauth.github.io/aac-sidecar-go/#what-aac-is-for)
|
|
28
|
+
explains what delegated authority between agents buys you, and what it does not.
|
|
29
|
+
|
|
27
30
|
The `aac` command is how a tenant's operator does everything that is not
|
|
28
31
|
done by the sidecar itself: register the tenant, sign in, manage keys,
|
|
29
32
|
workloads and domains, and prepare a runnable local workload. Everything
|
|
@@ -60,20 +63,21 @@ Python 3.10 or newer is required.
|
|
|
60
63
|
registers the agent's identity with AAC and creates the keys, certificates
|
|
61
64
|
and configuration its sidecar needs. The agent itself is yours. The first
|
|
62
65
|
run also creates your profile and registers your tenant; run it again with
|
|
63
|
-
a new `--agent` and `--
|
|
64
|
-
`--idp`, for each further agent.
|
|
66
|
+
a new `--agent` and its own `--agent-config` file, and the same `--trust-url`
|
|
67
|
+
and `--idp`, for each further agent.
|
|
65
68
|
|
|
66
69
|
Along the way it signs you in, registers a developer tenant (or reuses the
|
|
67
70
|
one your profile is already bound to), takes the trust domain AAC assigns to the
|
|
68
|
-
tenant, registers
|
|
71
|
+
tenant, registers your workload, generates development keys and
|
|
69
72
|
certificates, and writes a complete sidecar configuration together with the
|
|
70
73
|
files the trust-anchor publisher and Docker Compose need.
|
|
71
74
|
|
|
72
75
|
Point it at the endpoints your AAC environment gives you. The example below
|
|
73
|
-
uses the AAC stage environment
|
|
76
|
+
uses the AAC stage environment. First save the YAML example in “Agent configuration”
|
|
77
|
+
below as `orders.yaml`:
|
|
74
78
|
|
|
75
79
|
```bash
|
|
76
|
-
aac init --profile stage \
|
|
80
|
+
aac init --profile stage --agent orders --agent-config orders.yaml \
|
|
77
81
|
--admin-url https://api.stage.cascadeauth.dev \
|
|
78
82
|
--data-plane-url https://api.stage.cascadeauth.dev \
|
|
79
83
|
--trust-url https://trust.stage.cascadeauth.dev \
|
|
@@ -85,7 +89,7 @@ tenant, because a tenant is permanent. In a script, where there is no
|
|
|
85
89
|
terminal to answer the question, pass `--create-tenant`:
|
|
86
90
|
|
|
87
91
|
```bash
|
|
88
|
-
aac init --profile stage \
|
|
92
|
+
aac init --profile stage --agent orders --agent-config orders.yaml \
|
|
89
93
|
--admin-url https://api.stage.cascadeauth.dev \
|
|
90
94
|
--data-plane-url https://api.stage.cascadeauth.dev \
|
|
91
95
|
--trust-url https://trust.stage.cascadeauth.dev \
|
|
@@ -117,8 +121,7 @@ never asks you to pick between GitHub and Google again.
|
|
|
117
121
|
|
|
118
122
|
### What it creates, and where
|
|
119
123
|
|
|
120
|
-
* `~/.aac/agents/<agent>/` holds the files **one sidecar** needs
|
|
121
|
-
name `starter`), in folders named for where each file goes. `sidecar/` is
|
|
124
|
+
* `~/.aac/agents/<agent>/` holds the files **one sidecar** needs, in folders named for where each file goes. `sidecar/` is
|
|
122
125
|
what you mount or copy into the sidecar: the workload, receipt and HTTPS
|
|
123
126
|
key pairs, this agent's root-signing key, the CA certificate and the
|
|
124
127
|
outbound CA bundle. `agent/` is what the paired application reads: the
|
|
@@ -153,23 +156,27 @@ settings files written for them. It also records how far setup got, so
|
|
|
153
156
|
rerunning `aac init` resumes where it stopped.
|
|
154
157
|
|
|
155
158
|
Use one agent per workload. `aac init --agent <name>` creates an agent
|
|
156
|
-
(with `--trust-url`) or resumes it
|
|
159
|
+
(with `--agent-config` and `--trust-url`) or resumes it. There is no default agent;
|
|
157
160
|
three commands look after it:
|
|
158
161
|
|
|
159
162
|
```bash
|
|
160
|
-
aac agent status --agent
|
|
161
|
-
aac agent renew --agent
|
|
163
|
+
aac agent status --agent orders # what exists, what is due, and the next step
|
|
164
|
+
aac agent renew --agent orders # replace the short-lived certificates
|
|
162
165
|
aac agent list # every agent on this machine
|
|
163
166
|
```
|
|
164
167
|
|
|
168
|
+
`agent list` reports an unreadable or unsupported record in that agent's
|
|
169
|
+
`state` and continues listing the others. `agent status --agent <name>` still
|
|
170
|
+
returns a local-state error for that individual agent.
|
|
171
|
+
|
|
165
172
|
There is no separate command for the settings files. Running setup again —
|
|
166
173
|
with the profile the agent belongs to — writes `sidecar-config.yaml`,
|
|
167
174
|
`compose.env` and the tenant's `publisher.env` from what the agent already
|
|
168
175
|
records, without touching a single key:
|
|
169
176
|
|
|
170
177
|
```bash
|
|
171
|
-
aac init --profile stage --agent
|
|
172
|
-
aac init --profile stage --agent
|
|
178
|
+
aac init --profile stage --agent orders # write them again
|
|
179
|
+
aac init --profile stage --agent orders --layout container # and change the layout
|
|
173
180
|
```
|
|
174
181
|
|
|
175
182
|
That is how you rebuild a settings file you lost and how you move between
|
|
@@ -181,7 +188,7 @@ whenever it is the next step.
|
|
|
181
188
|
A second workload is a second agent with its own workload path:
|
|
182
189
|
|
|
183
190
|
```bash
|
|
184
|
-
aac init --profile stage --agent worker --
|
|
191
|
+
aac init --profile stage --agent worker --agent-config worker.yaml \
|
|
185
192
|
--idp github --trust-url https://trust.stage.cascadeauth.dev
|
|
186
193
|
```
|
|
187
194
|
|
|
@@ -192,14 +199,177 @@ settings files never changes that file's endpoints, so an agent created with
|
|
|
192
199
|
a different trust URL stops at its last step and has to be set up again
|
|
193
200
|
under a new name.
|
|
194
201
|
|
|
195
|
-
`--agent` names the local files
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
`--agent` names the local files and must match the file's `agent_name`.
|
|
203
|
+
The file's required `workload_path` supplies the path at the end of the SPIFFE ID.
|
|
204
|
+
An optional `--workload-path` must match the file or saved identity; omission
|
|
205
|
+
on refresh reuses that identity. Missing or conflicting identities are refused. Two agents with the same workload path are the same
|
|
198
206
|
workload holding different keys: that is what a replacement computer wants,
|
|
199
207
|
and what a second workload does not. The agent name is permanent, because
|
|
200
208
|
the root key id is made from it. `aac init` needs the profile the agent was
|
|
201
209
|
created with; the `aac agent` commands read it from the agent itself.
|
|
202
210
|
|
|
211
|
+
### Agent configuration
|
|
212
|
+
|
|
213
|
+
The operator writes one YAML file. `aac init --agent-config PATH` validates and
|
|
214
|
+
explicitly applies it. The profile remains INI; this file describes one agent,
|
|
215
|
+
not its profile or the hosted service. For example, save this as `orders.yaml`:
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
agent_name: orders
|
|
219
|
+
workload_path: fulfilment/orders
|
|
220
|
+
tls_server_names: [orders.internal.example, localhost, 127.0.0.1]
|
|
221
|
+
sidecar:
|
|
222
|
+
agent_invoke_url: http://127.0.0.1:8000/invoke
|
|
223
|
+
external_bind_address: 127.0.0.1
|
|
224
|
+
telemetry:
|
|
225
|
+
sink: orders.jsonl
|
|
226
|
+
central_forward: false
|
|
227
|
+
classes_of_action:
|
|
228
|
+
fulfil_order:
|
|
229
|
+
predicates:
|
|
230
|
+
action: reserve_inventory
|
|
231
|
+
amount_max: 10000
|
|
232
|
+
originator_reference: "PO #4143"
|
|
233
|
+
valid_for: +8m
|
|
234
|
+
destinations: {}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This declares the tenant's permission; AAC does not invent one. The application
|
|
238
|
+
chooses `fulfil_order` when starting a chain and checks that its business action
|
|
239
|
+
matches the authorized context. Units and business meaning belong to the
|
|
240
|
+
application. Empty classes and destinations are allowed for registration before
|
|
241
|
+
peer identities are known. No self destination is added.
|
|
242
|
+
|
|
243
|
+
**Chain-start boundary:** restrict `/v1/agent/delegations` and
|
|
244
|
+
`/v1/agent/mint-root` to the authorized originating application at the
|
|
245
|
+
network/ingress boundary. Sidecar **v0.4.0 and later** also require the existing
|
|
246
|
+
pair's AAC1-HMAC-SHA256 signature over the exact alias and raw request body.
|
|
247
|
+
Older releases do not authenticate these callers, so sharing a private network
|
|
248
|
+
with peers is insufficient. An authorized separate originator may hold the pair
|
|
249
|
+
secret only inside the same trusted tenant-application boundary; it gains
|
|
250
|
+
callback-signing capability too. Never share secrets across pairs or tenants.
|
|
251
|
+
Pairing freshness is not idempotent chain creation; do not automatically retry
|
|
252
|
+
an uncertain mint. Development certificates do not require `dev_mode`.
|
|
253
|
+
|
|
254
|
+
Applications using v0.4.0 can supply per-request `obligations` for T1. Equal
|
|
255
|
+
configured/request values combine once; differing values refuse rather than
|
|
256
|
+
override or intersect. Put dynamic limits in the request instead of also
|
|
257
|
+
configuring a different class value. Native request `valid_until` is reserved;
|
|
258
|
+
remove it and use class `valid_for`. For signed correlation, normally supply a
|
|
259
|
+
`task_ref` obligation per request: top-level `task_ref` alone is correlation
|
|
260
|
+
metadata, while a static class predicate deliberately shares one convergence
|
|
261
|
+
key across that class's chains. Omitted/null metadata inherits a configured or
|
|
262
|
+
obligation predicate; an explicit conflicting value refuses before minting.
|
|
263
|
+
|
|
264
|
+
The following is the complete input schema. Unknown fields, duplicate mapping
|
|
265
|
+
keys, YAML aliases/merge keys, object tags and files over 64 KiB are refused.
|
|
266
|
+
Null is not an omitted value. Strings must be nonempty and have no surrounding
|
|
267
|
+
whitespace or control characters. Lists allow at most 128 unique values; class
|
|
268
|
+
and destination maps allow at most 128 entries each.
|
|
269
|
+
|
|
270
|
+
| Field | Type and meaning | Default when omitted |
|
|
271
|
+
|---|---|---|
|
|
272
|
+
| `agent_name` | Required local name, 3–15 characters under the same name rules as `--agent`; must match it. | None |
|
|
273
|
+
| `workload_path` | Required concrete SPIFFE path, 3–150 ASCII characters; slash-separated letters/digits/`._~-`, no empty or dot segments, wildcard, query or escaped character. Fixed once the agent exists. | None |
|
|
274
|
+
| `tls_server_names` | Required nonempty list of DNS names/IP addresses callers use for HTTPS, including the originating application. No URLs, wildcards or unspecified bind addresses. | None |
|
|
275
|
+
| `sidecar.dev_mode` | Boolean enabling the runtime's development exceptions; independent of certificate source and replay profile. | `false` |
|
|
276
|
+
| `sidecar.loopback_bind_address` | Must be exactly `127.0.0.1` when `dev_mode: false`; another loopback IP address requires `dev_mode: true`. Non-loopback addresses are not accepted by this input. | `127.0.0.1` |
|
|
277
|
+
| `sidecar.external_bind_address` | IP bind address for the peer listener; choose the reachability your ingress allows. | `127.0.0.1` |
|
|
278
|
+
| `sidecar.loopback_port`, `sidecar.external_port` | Distinct integer ports, 1–65535. | `8080`, `9443` |
|
|
279
|
+
| `sidecar.agent_invoke_url` | Absolute HTTP(S) URL of your application's invoke endpoint. | `http://127.0.0.1:8000/invoke` |
|
|
280
|
+
| `sidecar.log_level` | `debug`, `info`, `warn` or `error`. | `info` |
|
|
281
|
+
| `sidecar.telemetry.sink` | Filename within managed `state/` (letters/digits/`_.-`, starting with a letter/digit), or `stdout` / `none`. `a2a-egress.db` is reserved for managed database state, regardless of case or whether A2A is enabled. Host/container paths are generated. | `telemetry.jsonl` |
|
|
282
|
+
| `sidecar.telemetry.central_forward` | Boolean opt-in for asynchronous metadata-only forwarding. The endpoint and tenant API-key file come from the selected profile/agent binding, never another tenant's file. | `false` |
|
|
283
|
+
| `replay_protection.backend` | `memory` or `valkey`. | `memory` |
|
|
284
|
+
| `replay_protection.deployment_profile` | `basic` with memory; `ha-retained-write-safe` with Valkey. No fallback. | The matching profile |
|
|
285
|
+
| `replay_protection.url` | Required absolute `valkeys://` URL for Valkey, with an optional numeric database path. No query, fragment or embedded credentials. Not valid with memory. | None |
|
|
286
|
+
| `replay_protection.memory_max_entries` | Integer 1–1000000. | `100000` |
|
|
287
|
+
| `replay_protection.connect_timeout_ms` | Integer 1–100. | Runtime default `100` |
|
|
288
|
+
| `replay_protection.operation_timeout_ms` | Integer 1–250. | Runtime default `50` |
|
|
289
|
+
| `replay_protection.max_connections` | Integer 1–4096. | Runtime default `32` |
|
|
290
|
+
| `replay_protection.cold_start_quarantine_seconds` | Integer 120–3600. | Runtime default `120` |
|
|
291
|
+
| `trust_anchors.tenant_ids` | Additional canonical `tnt-<UUID>` tenant IDs whose root signatures you trust. | Empty; own tenant is always included |
|
|
292
|
+
| `spiffe_bundles.trust_domains` | Additional lowercase trust domains whose workload certificates you trust. | Empty; own assigned domain is always included |
|
|
293
|
+
| `https_trust.ca_files` | Paths to public PEM CA certificate files, relative to the input file or absolute; up to 256 KiB each and 1 MiB total. Certificate-only PEM is saved; refresh/renewal do not reread the source files. No private keys. | Empty; own CA is always included |
|
|
294
|
+
| `https_trust.system_roots` | Boolean adding the current machine's system public HTTPS roots, with certifi fallback. With `false`, every outbound TLS service—including the control plane, trust URL, peer and Valkey—must chain to the own CA or a CA listed in `ca_files`. | `true` |
|
|
295
|
+
| `classes_of_action.<name>.predicates` | Mapping of registered predicate names to supported values, described below. The class entry's `<name>` uses letters/digits/`_.-`, starting with a letter/digit, up to 128 characters; predicate names come only from the closed registry. | Empty mapping |
|
|
296
|
+
| `classes_of_action.<name>.valid_for` | Required positive duration, 1 second–24 hours: digits with optional `+`, then `s`, `m`, `h` or `d`. The CLI supplies the registered `audience_self`. | None |
|
|
297
|
+
| `destinations.<name>.url` | Required absolute HTTPS recipient URL, for native receive or A2A. | None |
|
|
298
|
+
| `destinations.<name>.audience_pattern` | Required exact registered SPIFFE identity; no wildcard. | None |
|
|
299
|
+
| `destinations.<name>.predicates`, `.valid_for` | Same value/duration contract as classes. | Empty predicates; duration required |
|
|
300
|
+
| `destinations.<name>.timeout_ms` | Integer 1–2147483647 without A2A; 1–60000 for every destination when A2A is enabled, matching its generated deadline. | `10000` |
|
|
301
|
+
| `a2a.public_base_url`, `a2a.local_handler_url` | Optional A2A block; both required if present. Public URL is HTTPS with no path except optional `/`; the HTTP(S) local handler path must be exactly `/a2a/v1`, with no escaped spelling. Neither URL permits query or fragment markers, even empty ones. Managed A2A state paths and a 60-second deadline are generated. No A2A self-route is added. | A2A disabled |
|
|
302
|
+
|
|
303
|
+
URL hosts are ASCII DNS names or IP addresses; URL fields reject whitespace,
|
|
304
|
+
backslashes, embedded credentials and fragments. Basic replay history
|
|
305
|
+
is process-local: restarting loses it, and replicas do not share it. Selecting
|
|
306
|
+
Shared durable declares that the operator has qualified the Valkey service; the
|
|
307
|
+
CLI does not establish durability. This configuration interface does not accept
|
|
308
|
+
credential-bearing replay URLs.
|
|
309
|
+
|
|
310
|
+
The three kinds of trust above are separate checks. Obtain peer tenant IDs,
|
|
311
|
+
assigned trust domains and exact workload identities from their public status
|
|
312
|
+
or registration output. Exchange public CA certificates only. After registering
|
|
313
|
+
both agents, explicitly apply their peer configurations with the same command:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
aac init --profile stage --agent orders --agent-config orders.yaml
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The closed predicate registry accepts `action`, `amount_max`, `amount_min`,
|
|
320
|
+
`amount`, `valid_from`, `beneficiary_account`, `beneficiary_class`, `currency`,
|
|
321
|
+
`data_scope`, `purpose`, `human_authorization_class`, `task_ref`,
|
|
322
|
+
`min_account_age_days`, `max_authority_amount`, `assessed_damage_amount`,
|
|
323
|
+
`assessment_outcome`, `surveyor_findings`, `payout_amount`, `program_reference`,
|
|
324
|
+
`reporting_quarter`, `claim_ref`, `hours`, `quantity_units`, `beneficiary`,
|
|
325
|
+
`unit_price_usd`, `account`, `esg_scope3_co2e_kg`, `conflict_minerals_clear`,
|
|
326
|
+
`originator_reference`, `scope`, `composite_payout_amount`,
|
|
327
|
+
`composite_payout_total`, `composite_units_total`,
|
|
328
|
+
`composite_esg_scope3_co2e_kg_total` and `composite_conflict_minerals_clear`.
|
|
329
|
+
`amount_max`, `amount_min` and `valid_from` accept nonnegative integers or
|
|
330
|
+
canonical decimal strings (`0` or a nonzero digit followed by digits), at most
|
|
331
|
+
9223372036854775807. Enforced numbers are checked before YAML integer conversion:
|
|
332
|
+
spellings such as `010`, `0x10`, `1_000` and `+10` are refused, quoted or unquoted,
|
|
333
|
+
so the loader cannot silently reinterpret a limit. Other values must be strings. Commas are refused because
|
|
334
|
+
they separate wire predicates. The combined mapping has a 7900-byte UTF-8
|
|
335
|
+
budget, leaving room for the generated expiry.
|
|
336
|
+
|
|
337
|
+
`valid_until` is generated authority data, so it is refused in static input:
|
|
338
|
+
use `valid_for`. Registry membership alone does not give business labels new
|
|
339
|
+
monotonic enforcement. The current HTTP mint route uses the selected class's
|
|
340
|
+
static first limits; it accepts no per-request obligations. Your application
|
|
341
|
+
remains responsible for its policy decision.
|
|
342
|
+
|
|
343
|
+
Applying a file rewrites the generated configuration; restart the sidecar to
|
|
344
|
+
load it. Ordinary refresh and certificate renewal use the saved accepted values,
|
|
345
|
+
even if the original file is edited, moved or removed. Public CA file changes
|
|
346
|
+
also require explicit reapplication. The source file is never rewritten. Keep
|
|
347
|
+
the agent directory, credentials and keys; the input file is not their backup.
|
|
348
|
+
Generated files are disposable outputs and should not be hand-edited.
|
|
349
|
+
|
|
350
|
+
HTTPS certificates must authenticate every configured connection name. The CLI
|
|
351
|
+
issues them for those names or checks supplied certificates against them; renewal
|
|
352
|
+
keeps those names. Applying a different name set requires the installed certificate
|
|
353
|
+
to cover it already: supplied issuers can issue a certificate covering both sets
|
|
354
|
+
before the change. A CLI-issued agent needing new names must be created under a
|
|
355
|
+
new name with the intended configuration. No old agent-record format is migrated.
|
|
356
|
+
|
|
357
|
+
Central forwarding retains the local sink and sends only permitted metadata.
|
|
358
|
+
It is asynchronous and best-effort; a local event does not prove central delivery.
|
|
359
|
+
It excludes business predicates, task references, raw tokens/proofs and receipts.
|
|
360
|
+
`AAC_TELEMETRY_SINK` and `AAC_AGENT_STATE_DIR` in `compose.env` identify the local
|
|
361
|
+
file and mount; `AAC_API_KEY_FILE` identifies this tenant's credential. Mount it
|
|
362
|
+
at `/run/secrets/tenant-api-key` in the container layout. Do not read private
|
|
363
|
+
`record.json` from consumers.
|
|
364
|
+
|
|
365
|
+
For a CA change: stop the affected sidecar/application; renew or install the
|
|
366
|
+
issuer's replacement certificates; restart the publisher and verify publication
|
|
367
|
+
with `aac agent status --agent <name> --remote`; exchange the new public CA with
|
|
368
|
+
each intended peer and explicitly reapply that peer's configuration; then restart
|
|
369
|
+
the sidecars/applications and verify traffic in both directions. A peer's files
|
|
370
|
+
are never changed implicitly. Old published CA anchors remain until deliberately
|
|
371
|
+
retired. Leaf-only renewal needs a sidecar restart, without changing peer trust.
|
|
372
|
+
|
|
203
373
|
### Two ways to get your agent's certificates
|
|
204
374
|
|
|
205
375
|
Find your situation here and use the flags it lists. Nothing is inferred:
|
|
@@ -227,13 +397,13 @@ The laptop case. The CLI creates a certificate authority on this machine and sig
|
|
|
227
397
|
|
|
228
398
|
#### I bring my own CA
|
|
229
399
|
|
|
230
|
-
|
|
400
|
+
Your own issuer has signed the agent's certificates, and your CA private key never reaches this machine. Certificate source alone does not qualify a production deployment.
|
|
231
401
|
|
|
232
402
|
**Flags.** All seven together: `--workload-cert-file`, `--terminal-cert-file` and `--tls-cert-file`, each with its key file (`--workload-key-file`, `--terminal-key-file`, `--tls-key-file`), plus `--ca-cert-file`. Never `--ca-key-file`: the CLI does not want your CA key.
|
|
233
403
|
|
|
234
404
|
**Keys and signatures.** Your CA's key must be Ed25519 or EC P-256, and it must have signed each certificate with Ed25519 or ECDSA-with-SHA-256. The two identity keys may be Ed25519 or EC P-256; the HTTPS key must be EC P-256. RSA is not supported: the sidecar cannot verify against it.
|
|
235
405
|
|
|
236
|
-
**The CLI** checks each certificate against its key, its issuer and its validity window; registers the workload and writes the settings files and the pairing secret; publishes your CA certificate as a trust anchor named `<agent>-ca`.
|
|
406
|
+
**The CLI** checks each certificate against its key, its issuer and its validity window, and HTTPS certificates against every configured connection name; registers the workload and writes the settings files and the pairing secret; publishes your CA certificate as a trust anchor named `<agent>-ca`.
|
|
237
407
|
|
|
238
408
|
**The CLI does not** create a certificate authority; issue any certificate; ask for, read or store your CA private key.
|
|
239
409
|
|
|
@@ -288,8 +458,13 @@ profile (~/.aac/config) ── bound to ──> tenant
|
|
|
288
458
|
### What each file is for, and what to back up
|
|
289
459
|
|
|
290
460
|
The table lists every file the CLI creates, what it is for, how long it
|
|
291
|
-
lives and whether to back it up. `<agent>` is
|
|
292
|
-
|
|
461
|
+
lives and whether to back it up. `<agent>` is your explicitly selected agent
|
|
462
|
+
name and `<tenant-id>` the tenant id AAC allocated.
|
|
463
|
+
|
|
464
|
+
For what each of these proves, who else ever gets a copy, what never leaves you
|
|
465
|
+
and how the pieces fit together — including when your own certificate authority
|
|
466
|
+
signs instead of this tool — see
|
|
467
|
+
[Keys and certificates](https://cascadeauth.github.io/aac-sidecar-go/keys-and-certificates.html).
|
|
293
468
|
|
|
294
469
|
<!-- inventory-table:start -->
|
|
295
470
|
| No. | Material | Where | Used for | Lifetime | Back up? |
|
|
@@ -300,9 +475,9 @@ lives and whether to back it up. `<agent>` is the agent name
|
|
|
300
475
|
| 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 |
|
|
301
476
|
| 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` |
|
|
302
477
|
| 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 |
|
|
303
|
-
| 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;
|
|
304
|
-
| 8 |
|
|
305
|
-
| 9 | outbound_ca_bundle | `~/.aac/agents/<agent>/sidecar/outbound-ca.pem` | the sidecar verifies TLS to AAC and
|
|
478
|
+
| 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 |
|
|
479
|
+
| 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 |
|
|
480
|
+
| 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 |
|
|
306
481
|
| 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 |
|
|
307
482
|
| 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) |
|
|
308
483
|
| 12 | published_public_inputs | `~/.aac/tenants/<tenant-id>/root-keys`, `~/.aac/tenants/<tenant-id>/spiffe-bundle` | the publisher's input directories: every root public key and CA certificate this tenant has published, across all agents | for the life of the tenant | **Recommended.** back up with the tenant directory: a replacement agent must publish its new root key alongside a still-ACTIVE previous one (the control plane refuses a root-key set that drops every ACTIVE key at once) |
|
|
@@ -315,11 +490,11 @@ the machine is healthy. Everything else is regenerated.
|
|
|
315
490
|
### Inspect and maintain an agent
|
|
316
491
|
|
|
317
492
|
```bash
|
|
318
|
-
aac agent status --agent
|
|
319
|
-
aac agent status --agent
|
|
320
|
-
aac agent renew --agent
|
|
493
|
+
aac agent status --agent orders --output table # what exists, expiry, permissions, next command
|
|
494
|
+
aac agent status --agent orders --remote # also: is the public trust material visible?
|
|
495
|
+
aac agent renew --agent orders # replace the short-lived certificates; old ones archived
|
|
321
496
|
aac agent list # every agent on this machine, with its case
|
|
322
|
-
aac init --profile stage --agent
|
|
497
|
+
aac init --profile stage --agent orders --layout container # write the settings again, container paths
|
|
323
498
|
```
|
|
324
499
|
|
|
325
500
|
`status` works offline by default and exits with code 3 when material is
|
|
@@ -363,7 +538,7 @@ ahead for the development CA.
|
|
|
363
538
|
|
|
364
539
|
| Material | Lasts | When it runs out | What to do |
|
|
365
540
|
|---|---|---|---|
|
|
366
|
-
| Workload, terminal-attestation and
|
|
541
|
+
| 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 |
|
|
367
542
|
| 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` |
|
|
368
543
|
| Tenant-admin session | hours | administration commands ask you to sign in again | `aac sso login` |
|
|
369
544
|
| 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" |
|
|
@@ -376,10 +551,9 @@ a week that renewal also replaces the development CA (`renew` then reports
|
|
|
376
551
|
agent, and anything else that trusted the old CA. Renewing is safe to
|
|
377
552
|
repeat, but it is not a no-op: every run issues fresh keys and moves the old
|
|
378
553
|
files to the agent's `archive/` directory, so whatever reads them must
|
|
379
|
-
reload.
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
does not renew anything itself.
|
|
554
|
+
reload. Recreate or restart the affected processes with your deployment's
|
|
555
|
+
normal commands after publishing and explicitly refreshing each peer's public
|
|
556
|
+
trust. Restarting a process does not renew its certificates.
|
|
383
557
|
|
|
384
558
|
All of this is development material. In production, certificates come from
|
|
385
559
|
your own issuer and follow its renewal process.
|
|
@@ -454,12 +628,13 @@ profile; `aac profile show` prints it, and the example below uses
|
|
|
454
628
|
directory the publisher runs from. Then run step 3 with
|
|
455
629
|
`--tenant-admin-key-file tenant-admin.pem` added.
|
|
456
630
|
|
|
457
|
-
3.
|
|
631
|
+
3. Prepare `laptop-2.yaml` with the new `agent_name` and the original
|
|
632
|
+
workload path, deployment and trust choices. Run setup with that **new agent name**. A developer tenant
|
|
458
633
|
passes its sign-in choice, so an expired session is renewed without a
|
|
459
634
|
prompt:
|
|
460
635
|
|
|
461
636
|
```bash
|
|
462
|
-
aac init --profile stage --agent laptop-2 --idp github \
|
|
637
|
+
aac init --profile stage --agent laptop-2 --agent-config laptop-2.yaml --idp github \
|
|
463
638
|
--trust-url https://trust.stage.cascadeauth.dev
|
|
464
639
|
```
|
|
465
640
|
|
|
@@ -469,7 +644,7 @@ profile; `aac profile show` prints it, and the example below uses
|
|
|
469
644
|
the `aac sso login --idp-url …` command from step 1 first:
|
|
470
645
|
|
|
471
646
|
```bash
|
|
472
|
-
aac init --profile stage --agent laptop-2 \
|
|
647
|
+
aac init --profile stage --agent laptop-2 --agent-config laptop-2.yaml \
|
|
473
648
|
--trust-url https://trust.stage.cascadeauth.dev
|
|
474
649
|
```
|
|
475
650
|
|
|
@@ -731,10 +906,19 @@ aac tenant reissue-api-key --profile prod
|
|
|
731
906
|
|
|
732
907
|
### Domains and workloads
|
|
733
908
|
|
|
734
|
-
Every tenant gets
|
|
735
|
-
the
|
|
736
|
-
|
|
737
|
-
|
|
909
|
+
Every tenant gets an AAC-assigned trust domain: the tenant id plus a suffix
|
|
910
|
+
the control plane selects for its environment,
|
|
911
|
+
`<tenant_id>.tenants.stage.cascadeauth.dev` on stage and
|
|
912
|
+
`<tenant_id>.tenants.cascadeauth.com` on production. No DNS record or proof
|
|
913
|
+
of ownership is needed; the first call allocates the name permanently and
|
|
914
|
+
every later call returns the same one, so use the name the command returns
|
|
915
|
+
rather than building it yourself. Registration saves it in the profile as
|
|
916
|
+
`hosted_trust_domain`. Signing in with `aac sso login` does not write it:
|
|
917
|
+
`aac tenant assign-hosted-domain` requests the same allocation and saves it
|
|
918
|
+
into the profile bound to that tenant, as `aac init` does during setup. To
|
|
919
|
+
use a custom domain you own as a trust domain instead, prove control of it
|
|
920
|
+
with a DNS TXT record, then bind it; a domain you own is recorded on the
|
|
921
|
+
server and never written to the profile:
|
|
738
922
|
|
|
739
923
|
```bash
|
|
740
924
|
aac tenant issue-domain-challenge --profile prod --domain example.com
|