feat(mosaic-as): agent registration + scoped/revocable tokens (US-007) #541

Merged
jason.woltje merged 1 commits from feat/us007-agent-registration into main 2026-06-16 01:10:45 +00:00
Owner

Closes #540. Implements US-007 (M-AGENT-REG) from the mosaic-comms PRD.

Endpoints (all host-token gated)

  • → mints/ensures , returns .
  • → manual revoke from day one; returns .
  • → lists agents with ≥1 active token (reconciliation; never advertises revoked/phantom agents).

Security

  • Per-agent tokens are -prefixed high-entropy random; only sha256 hashes are persisted (plaintext returned exactly once, never stored/logged).
  • Constant-time token lookup (timingSafeEqual over equal-length hash buffers, no early-out).
  • Scoped: a per-agent token may only act as its own agent on (403 otherwise); host bridgeTokens stay unscoped. Register/revoke/list are host-only.
  • Fail-closed auth (empty/garbage/non-magt_ bearer or homeserver error → denied).

Persistence (no new infra)

  • Token registry lives in Matrix account_data on the AS sender user () — survives pod restart with zero PVC/volume/env. Known v1 limit (Synapse ~100KB account_data cap) documented in-code.

Review

  • Independent opus adversarial security review: PASS (no critical/high). Remediated the one MEDIUM (agent-slug collision where distinct alias/host pairs join to the same Matrix id — now rejected instead of silently overwriting) + regression test. LOW/INFO items (CAS on multi-replica, registry shape-validation, verifyToken-error→clean-403) documented as non-blocking follow-ups.

Gates

typecheck + lint green; 39 tests pass (21 + 18 ).

Fixes #540

Closes #540. Implements US-007 (M-AGENT-REG) from the mosaic-comms PRD. ## Endpoints (all host-token gated) - → mints/ensures , returns . - → manual revoke from day one; returns . - → lists agents with ≥1 active token (reconciliation; never advertises revoked/phantom agents). ## Security - Per-agent tokens are -prefixed high-entropy random; only sha256 hashes are persisted (plaintext returned exactly once, never stored/logged). - Constant-time token lookup (timingSafeEqual over equal-length hash buffers, no early-out). - **Scoped**: a per-agent token may only act as its own agent on (403 otherwise); host bridgeTokens stay unscoped. Register/revoke/list are host-only. - Fail-closed auth (empty/garbage/non-magt_ bearer or homeserver error → denied). ## Persistence (no new infra) - Token registry lives in Matrix **account_data** on the AS sender user () — survives pod restart with zero PVC/volume/env. Known v1 limit (Synapse ~100KB account_data cap) documented in-code. ## Review - Independent opus adversarial security review: **PASS** (no critical/high). Remediated the one MEDIUM (agent-slug collision where distinct alias/host pairs join to the same Matrix id — now rejected instead of silently overwriting) + regression test. LOW/INFO items (CAS on multi-replica, registry shape-validation, verifyToken-error→clean-403) documented as non-blocking follow-ups. ## Gates typecheck + lint green; 39 tests pass (21 + 18 ). Fixes #540
jason.woltje added 1 commit 2026-06-16 00:57:13 +00:00
feat(mosaic-as): agent registration endpoint + scoped/revocable tokens (US-007)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
5a11e3c121
POST /bridge/v1/agents mints/ensures @agent-<alias>-<host> and returns a
scoped, revocable per-agent bridge token. Adds POST /bridge/v1/agents/revoke
(manual revoke from day one) and GET /bridge/v1/agents (reconciliation source
that never advertises revoked/phantom agents).

Persistence: per-agent token sha256 hashes stored in Matrix account_data on the
AS sender user (org.uscllc.mosaic_as.agents) — no new infra, survives restart.
Tokens are magt_-prefixed high-entropy random; plaintext is never persisted and
returned exactly once. Per-agent tokens are scoped: usable only to act as their
own agent on /bridge/v1/messages|typing; host bridgeTokens stay unscoped.
Registration/revoke/list are host-token-only.

Independent opus security review: PASS (no critical/high). Remediated the one
MEDIUM (agent-slug collision: distinct alias/host pairs joining to the same
Matrix id now rejected instead of silently overwriting) + regression test.

Closes #540

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jason.woltje merged commit c461380a4a into main 2026-06-16 01:10:45 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#541