swarm UI: delete linked accounts
Each row of an agent's linked accounts, except its own `main` matrix
account, gets a delete action. swarm-controller serves DELETE beside each
PUT (matrix-accounts/{account}, forge-accounts/{label}, github-account),
answers 404 for an account the store does not hold, refuses `main`, and
removes every version through `delete_all_versions`.
The matrix confirmation has a revoke checkbox, off by default: the
controller logs the stored token out at its homeserver first, and keeps
the account when that fails or no homeserver is stored.
The controller's policy gains `delete` on each agent's
`metadata/.../matrix/+`, `forge/+` and `github-token`, pinned in
bao-grants.nix.
Refs #4855
This commit is contained in:
parent
ed9c0f53ed
commit
bbf931207f
7 changed files with 705 additions and 35 deletions
|
|
@ -365,7 +365,7 @@ let
|
|||
# back before writing so a re-run keeps the value a live agent already holds
|
||||
# instead of rotating it. `metadata/` is the revocation half: `delete` on
|
||||
# `data/` only soft-deletes the newest version, and `+` being one path segment
|
||||
# keeps this to the queue leaf alone.
|
||||
# keeps this to the queue leaf alone, and each linked account to its one leaf.
|
||||
# Each hive's matrix sender token (`matrix_account::hive_sender`) grants `read`
|
||||
# for the same keep-if-live reason, and `+` for the same glob-only-as-last-segment reason.
|
||||
#
|
||||
|
|
@ -408,6 +408,18 @@ let
|
|||
capabilities = ["list"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/metadata/swarm/agents/+/matrix/+" {
|
||||
capabilities = ["delete"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/metadata/swarm/agents/+/forge/+" {
|
||||
capabilities = ["delete"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/metadata/swarm/agents/+/github-token" {
|
||||
capabilities = ["delete"]
|
||||
}
|
||||
|
||||
path "${credentialMountPath}/data/swarm/hives/+/matrix/sender-token" {
|
||||
capabilities = ["create", "read", "update"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1201,7 +1201,8 @@ let
|
|||
# itself, so each stanza reaches that one directory: not the agent's
|
||||
# other keys, not `agents/` itself, not anything below. Pinned as whole
|
||||
# stanzas, and as the only metadata stanzas under `agents/` beside the
|
||||
# queue revocation, so a widened path or an added capability fails.
|
||||
# queue revocation and the account deletes, so a widened path or an added
|
||||
# capability fails.
|
||||
name = "the controller may list each agent's matrix and forge accounts, and nothing else under agents";
|
||||
ok =
|
||||
let
|
||||
|
|
@ -1210,7 +1211,22 @@ let
|
|||
in
|
||||
lib.hasInfix "path \"secret/metadata/swarm/agents/+/matrix\" {\n capabilities = [\"list\"]\n}" s
|
||||
&& lib.hasInfix "path \"secret/metadata/swarm/agents/+/forge\" {\n capabilities = [\"list\"]\n}" s
|
||||
&& stanzas == 3;
|
||||
&& stanzas == 6;
|
||||
}
|
||||
{
|
||||
# `linked_accounts` deletes one matrix account, forge account or GitHub
|
||||
# token through `delete_all_versions`, which addresses its metadata path.
|
||||
# A trailing `+` is one segment, so each stanza reaches the accounts
|
||||
# directly in that directory and nothing deeper. Pinned as whole stanzas,
|
||||
# so `list` or `read` here, which would expose version history, fails.
|
||||
name = "the controller may delete each agent's linked accounts, and nothing else of theirs";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantHere.systemd.services.swarm-bao-controller-policy.script;
|
||||
in
|
||||
lib.hasInfix "path \"secret/metadata/swarm/agents/+/matrix/+\" {\n capabilities = [\"delete\"]\n}" s
|
||||
&& lib.hasInfix "path \"secret/metadata/swarm/agents/+/forge/+\" {\n capabilities = [\"delete\"]\n}" s
|
||||
&& lib.hasInfix "path \"secret/metadata/swarm/agents/+/github-token\" {\n capabilities = [\"delete\"]\n}" s;
|
||||
}
|
||||
{
|
||||
# The swarm appservice token is a homeserver-admin credential. The
|
||||
|
|
|
|||
Loading…
Reference in a new issue