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`
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ This document contains the help content for the `swarmctl` command-line program.
|
|||
* [`swarmctl`↴](#swarmctl)
|
||||
* [`swarmctl agent`↴](#swarmctl-agent)
|
||||
* [`swarmctl agent create`↴](#swarmctl-agent-create)
|
||||
* [`swarmctl agent mint-identity`↴](#swarmctl-agent-mint-identity)
|
||||
* [`swarmctl user`↴](#swarmctl-user)
|
||||
* [`swarmctl user add`↴](#swarmctl-user-add)
|
||||
* [`swarmctl user update`↴](#swarmctl-user-update)
|
||||
|
|
@ -43,6 +44,7 @@ Manage agents across the swarm
|
|||
###### **Subcommands:**
|
||||
|
||||
* `create` — Queue creation of a new agent on a hive in this swarm
|
||||
* `mint-identity` — Queue a re-mint of an existing agent's identity at the swarm's secret store
|
||||
|
||||
|
||||
|
||||
|
|
@ -75,6 +77,33 @@ No approval gate guards this: running this binary already means being root on th
|
|||
|
||||
|
||||
|
||||
## `swarmctl agent mint-identity`
|
||||
|
||||
Queue a re-mint of an existing agent's identity at the swarm's secret store.
|
||||
|
||||
**The backfill verb.** Agent creation is event-driven and nothing at swarm level sweeps for agents that are missing a credential, so an agent created before a credential joined the mint never receives one. This re-runs the mint for one agent that already exists.
|
||||
|
||||
⚠️ **It re-mints the agent's store certificate**, which that agent picks up the next time its container boots. The agent's queue secret is left exactly as it is if it already has one, so running this against an already-migrated agent does not disturb its queue connection.
|
||||
|
||||
Queues and returns, the same way `agent create` does — watch the swarm UI's job view for the outcome.
|
||||
|
||||
**Usage:** `swarmctl agent mint-identity [OPTIONS] --hive <HIVE> <NAME>`
|
||||
|
||||
###### **Arguments:**
|
||||
|
||||
* `<NAME>` — Name of an agent that already exists
|
||||
|
||||
###### **Options:**
|
||||
|
||||
* `--hive <HIVE>` — The hive that agent runs on.
|
||||
|
||||
Required, and deliberately not defaulted: the credentials this mints name a hive, and neither this CLI nor the controller keeps a roster of which agent is on which hive. Naming the wrong one gives the agent an identity scoped to a hive it does not run on. The controller checks the value against the swarm's hive roster and names the known hives if it misses.
|
||||
* `--controller-socket <PATH>` — swarm-controller's unix socket.
|
||||
|
||||
Supplied by the nix module that installs this binary, from the same `socketPath` option the daemon binds; falls back to `SWARM_CONTROLLER_SOCKET`.
|
||||
|
||||
|
||||
|
||||
## `swarmctl user`
|
||||
|
||||
Manage subjects in the swarm's SSO provider
|
||||
|
|
|
|||
Loading…
Reference in a new issue