swarmctl: re-mint an existing agent's store identity
Agent creation at swarm level is event-driven and nothing sweeps for
agents missing a credential, so an agent created before a credential
joined the mint never receives one -- nothing comes back around to it.
Without a way to re-run the mint by hand, the only route to giving an
existing agent its queue credential would be to delete and recreate the
agent.
POST /api/agents/{name}/identity enqueues the same MintAgentIdentity
node POST /api/agents declares, rather than writing inline: a second
code path that mints an identity is a second place for the four strings
that have to agree to disagree. swarmctl agent mint-identity is the
operator end, the same POST-and-print-the-node-id shape agent create
already has.
--hive is required on both ends. Neither the CLI nor the controller
keeps a roster of which agent runs where, and the credentials this mints
name a hive, so a default would be a guess that hands an agent subjects
on a hive it does not run on.
Documents the backfill as a runbook step, and fills in the renewal cell
the credential matrix requires for the new row.
This commit is contained in:
parent
ffd5018b18
commit
1442168715
6 changed files with 332 additions and 37 deletions
|
|
@ -54,15 +54,16 @@ strategy for every credential, including the mTLS leaf.
|
|||
|
||||
<!-- vale write-good.Passive = NO -->
|
||||
|
||||
| store path | minter | reader — pulls at runtime, holds in memory | renewal |
|
||||
| -------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- |
|
||||
| `swarm/agents/<agent>/matrix/<account>` | `swarm-controller` | the agent container itself, under the certificate its hive passed in | must be stated |
|
||||
| `swarm/agents/<agent>/bao-mtls` | `swarm-controller`, at agent creation | `hive-c0re`, under the hive's own certificate, when it writes the agent's container config | must be stated |
|
||||
| `swarm/hives/<hive>/matrix/appservice-token` | one minter, on the authelia host | the hive process that presents the token to its homeserver, under the hive's own certificate | must be stated |
|
||||
| `swarm/hives/<hive>/matrix/sender-token` | `swarm-matrix-ctl`, in the `hive-matrix` container | `swarm-matrix-ctl` itself, under its own certificate, before it decides whether to mint, and hive-c0re's `stored_sender_token()`, under the hive's own certificate | must be stated |
|
||||
| `swarm/hives/<hive>/queue/agent` | authelia | the agent container presenting the OIDC client to the swarm queue, under its own certificate | must be stated |
|
||||
| `swarm/services/<clientId>/oidc/client` | authelia | the service process that presents the client secret, under the certificate of the host it runs on | must be stated |
|
||||
| _(not in the store)_ a hive's mTLS leaf | the store's own PKI, or an operator placing it by hand | its own client, off disk — the exception above, because it's what makes every other row's pull possible | must be stated |
|
||||
| store path | minter | reader — pulls at runtime, holds in memory | renewal |
|
||||
| -------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `swarm/agents/<agent>/matrix/<account>` | `swarm-controller` | the agent container itself, under the certificate its hive passed in | must be stated |
|
||||
| `swarm/agents/<agent>/bao-mtls` | `swarm-controller`, at agent creation | `hive-c0re`, under the hive's own certificate, when it writes the agent's container config | must be stated |
|
||||
| `swarm/agents/<agent>/queue` | `swarm-controller`, at agent creation | the agent container itself, under its own certificate — the identity it presents to the swarm queue, naming that one agent rather than its hive | none: the secret is fixed for the life of the agent and is revoked by deleting the path. A rotation mechanism is tracked as separate work, because rotating this credential needs a reconnect path — a queue client holding a revoked secret does not find out until it reconnects |
|
||||
| `swarm/hives/<hive>/matrix/appservice-token` | one minter, on the authelia host | the hive process that presents the token to its homeserver, under the hive's own certificate | must be stated |
|
||||
| `swarm/hives/<hive>/matrix/sender-token` | `swarm-matrix-ctl`, in the `hive-matrix` container | `swarm-matrix-ctl` itself, under its own certificate, before it decides whether to mint, and hive-c0re's `stored_sender_token()`, under the hive's own certificate | must be stated |
|
||||
| `swarm/hives/<hive>/queue/agent` | authelia | the agent container presenting the OIDC client to the swarm queue, under its own certificate | must be stated |
|
||||
| `swarm/services/<clientId>/oidc/client` | authelia | the service process that presents the client secret, under the certificate of the host it runs on | must be stated |
|
||||
| _(not in the store)_ a hive's mTLS leaf | the store's own PKI, or an operator placing it by hand | its own client, off disk — the exception above, because it's what makes every other row's pull possible | must be stated |
|
||||
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
|
|
@ -76,6 +77,29 @@ carries it, and no hive ever needs the capability to mint an identity.
|
|||
`swarm-controller` proves the leaf it publishes before the creation job
|
||||
reports success, by logging in with it and reading the row back.
|
||||
|
||||
**Backfilling an agent that predates a credential.** Agent creation at swarm
|
||||
level is purely event-driven — `swarm-controller` mints an agent's store
|
||||
identity on the job graph `POST /api/agents` inserts, and nothing sweeps for
|
||||
agents that already exist. So an agent created before a credential joined that
|
||||
mint never receives one, and nothing will ever come back around to it. Re-run
|
||||
the mint for one agent with:
|
||||
|
||||
```sh
|
||||
swarmctl agent mint-identity <agent> --hive <hive>
|
||||
```
|
||||
|
||||
`--hive` is required: neither the CLI nor the controller keeps a roster of
|
||||
which agent runs where, and the credentials this mints name a hive. The queue
|
||||
secret half is idempotent — an agent that already has one keeps exactly the
|
||||
value it has, so running this against an already-migrated agent does not drop
|
||||
its queue connection. The certificate half is not: the agent gets a fresh leaf
|
||||
and picks it up on its next boot.
|
||||
|
||||
⚠️ **Run this for every existing agent before deploying a hive-side change
|
||||
that makes a container require a credential it may not have.** A container
|
||||
whose credential is absent does not start — that is deliberate, and it is what
|
||||
makes the backfill a step rather than a suggestion.
|
||||
|
||||
**Who reads that row, and what happens to it.** `hive-c0re` reads it every
|
||||
time it writes an agent's container configuration
|
||||
(`lifecycle::agent_identity`), stages the certificate and its key `0600`
|
||||
|
|
|
|||
Loading…
Reference in a new issue