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
|
|
@ -8,14 +8,12 @@
|
|||
//! store, and its grant already covers exactly the objects written here
|
||||
//! (`swarm-bao.nix`'s `controllerPolicyText`: `create/update` on
|
||||
//! `secret/data/swarm/agents/*`, on `sys/policies/acl/hive-*`, and on
|
||||
//! `auth/cert/certs/hive-*`). No new authority is asked for anywhere — the
|
||||
//! agent's queue secret lives under the same `swarm/agents/<agent>` prefix the
|
||||
//! certificate does, which is why adding it costs no grant on either side.
|
||||
//! `auth/cert/certs/hive-*`). No new authority is asked for anywhere.
|
||||
//!
|
||||
//! **Two credentials, deliberately unrelated.** The certificate is how the
|
||||
//! agent reaches the store; the queue secret is how it identifies itself to the
|
||||
//! swarm queue. The second is not derived from the first, so renewing either is
|
||||
//! a question that can be answered without reference to the other.
|
||||
//! **Two credentials, deliberately unrelated.** The certificate reaches the
|
||||
//! store; the queue secret identifies the agent to the swarm queue. Both sit
|
||||
//! under `swarm/agents/<agent>`, so neither costs a grant — but the second is
|
||||
//! not derived from the first, so either renews without reference to the other.
|
||||
//!
|
||||
//! Four separate strings have to agree before an agent can authenticate: the
|
||||
//! policy's name, the cert-auth role's name, the certificate's common name,
|
||||
|
|
@ -247,14 +245,12 @@ fn generate_queue_secret() -> Result<String> {
|
|||
/// names the policy, so the other order leaves a window in which it points at
|
||||
/// nothing.
|
||||
///
|
||||
/// ⚠️ **Step 3 is idempotent and step 2 is not.** Re-running this function
|
||||
/// re-mints the agent's certificate — a fresh leaf the agent picks up on its
|
||||
/// next boot — but leaves an existing queue secret exactly as it is. The
|
||||
/// asymmetry is deliberate: an agent holds its queue secret in a live
|
||||
/// connection, so replacing it would drop that agent off the queue until it
|
||||
/// reconnected, and this function is re-run deliberately (by the backfill
|
||||
/// route) against agents that are already running. Nothing here rotates a
|
||||
/// queue secret; revoking one means deleting the path.
|
||||
/// ⚠️ **Step 3 is idempotent and step 2 is not.** Re-running re-mints the
|
||||
/// certificate — a fresh leaf the agent picks up on its next boot — but leaves
|
||||
/// an existing queue secret alone. An agent holds that secret in a live
|
||||
/// connection, and this function is re-run deliberately against agents that
|
||||
/// are already running, so replacing it would drop them off the queue.
|
||||
/// Nothing here rotates one; revoking means deleting the path.
|
||||
///
|
||||
/// # Errors
|
||||
/// Anything that stops one of those five steps, with the step named. A
|
||||
|
|
|
|||
Loading…
Reference in a new issue