swarm-matrix-ctl: one control binary for the matrix container, not one per job
Renames `swarm-matrix-minter` and reshapes it around subcommands. Minting is now `swarm-matrix-ctl mint`. Running rust inside `containers.hive-matrix` is not free: it needs its own store identity, its own cert role and its own bind mounts, and every one of those is per-*container*, not per-task. A second single-purpose crate would have had to duplicate that plumbing to add one action, so the next thing that has to run in there should be a verb here rather than a new crate. The old name guaranteed the opposite. `main.rs` is clap dispatch; the minting logic moves to `mint.rs` unchanged. A bare invocation is refused: `mint` writes a credential, so "no verb" defaulting to it would make a typo in the unit mint rather than fail. The environment prefix moves with it, `MATRIX_MINTER_*` → `MATRIX_MINT_*`. Scoped to the verb and not to the binary, because a binary-scoped prefix is one the next verb has to share or widen, and a widened one never narrows again. A test asserts every variable carries the verb's prefix. The principal renames too. The cert role, bao policy, granting unit, leaf filename and `certAuthCns` entry all have to spell one string the same way, so leaving them as `swarm-matrix-minter` would have rebuilt the naming split this branch exists to remove. Renaming the nix options alongside is free here: every one of them is introduced by this PR and has never been released, so no operator config names them yet. `ExecStart` now names the verb, which is a contract between a nix string and a clap enum that fails at deploy time with no local signal. Both ends assert it: `mint_is_spelled_the_way_the_unit_invokes_it` in the crate, and a new module-eval arm reading the rendered `ExecStart`. docs/getting-started/setup.md drops the sender token from its "live on the host" list: setup does not touch this credential, so a setup guide has no reason to name it.
This commit is contained in:
parent
fb9c6122df
commit
67ba28448f
23 changed files with 319 additions and 172 deletions
|
|
@ -152,10 +152,10 @@ let
|
|||
# `Kind::label`, which renders the singular for error text. The singular
|
||||
# spelling evaluates, deploys, and 403s every read with "permission
|
||||
# denied" and nothing else.
|
||||
name = "the matrix minter's grant is the sender token's path and nothing else";
|
||||
name = "matrix-ctl's grant is the sender token's path and nothing else";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantHere.systemd.services.swarm-bao-matrix-minter-policy.script;
|
||||
s = baoGrantHere.systemd.services.swarm-bao-matrix-ctl-policy.script;
|
||||
in
|
||||
lib.hasInfix "path \"secret/data/swarm/services/matrix/sender-token\" {" s
|
||||
&& !(lib.hasInfix "secret/data/swarm/services/*" s)
|
||||
|
|
@ -165,30 +165,30 @@ let
|
|||
}
|
||||
{
|
||||
# 🩸 `read` is load-bearing here and is the one capability neither
|
||||
# sibling has. The minter's first act is to read this path back and stop
|
||||
# sibling has. matrix-ctl's first act is to read this path back and stop
|
||||
# if something is there — that read IS "and only once", so without the
|
||||
# capability every container restart would mint a second access token and
|
||||
# invalidate the hive's.
|
||||
name = "the matrix minter may read back the one path it writes";
|
||||
name = "matrix-ctl may read back the one path it writes";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantHere.systemd.services.swarm-bao-matrix-minter-policy.script;
|
||||
s = baoGrantHere.systemd.services.swarm-bao-matrix-ctl-policy.script;
|
||||
in
|
||||
lib.hasInfix "capabilities = [\"create\", \"update\", \"read\"]" s
|
||||
&& lib.hasInfix "auth/cert/certs/swarm-matrix-minter" s
|
||||
&& lib.hasInfix "allowed_common_names=swarm-matrix-minter" s;
|
||||
&& lib.hasInfix "auth/cert/certs/swarm-matrix-ctl" s
|
||||
&& lib.hasInfix "allowed_common_names=swarm-matrix-ctl" s;
|
||||
}
|
||||
{
|
||||
# Same two controls its siblings carry: ordered after the unit that makes
|
||||
# the mounts it writes into, and rendered on the HOST rather than inside
|
||||
# the store's container, where it would have neither an identity nor a
|
||||
# route to the store.
|
||||
name = "the minter's granting unit is ordered after the mounts and rendered on the host";
|
||||
name = "matrix-ctl's granting unit is ordered after the mounts and rendered on the host";
|
||||
ok =
|
||||
lib.elem "swarm-bao-controller-policy.service" (
|
||||
baoGrantHere.systemd.services.swarm-bao-matrix-minter-policy.after
|
||||
baoGrantHere.systemd.services.swarm-bao-matrix-ctl-policy.after
|
||||
)
|
||||
&& !(baoGrantHere.containers.swarm-bao.config.systemd.services ? swarm-bao-matrix-minter-policy);
|
||||
&& !(baoGrantHere.containers.swarm-bao.config.systemd.services ? swarm-bao-matrix-ctl-policy);
|
||||
}
|
||||
{
|
||||
# The policy authorising this route lives in another file, and nothing
|
||||
|
|
|
|||
Loading…
Reference in a new issue