docs(systems): document approval token mechanism

federation.md: new 'Approval Token Verification' subsection covering
issuance (queue path generates token, returns in 202), storage on
initiator (federation_peers.approval_token), forwarding from /approve,
verification on receiver's awaiting_approval branch, single-use lifecycle,
backward compatibility, and threat-model boundary (sender-side outbound
gating tracked separately).

database.md: approval_token column documented on both federation_peers
and peer_approval_requests with cross-references to federation.md.

api.md: /peer/accept request + 202 response now show optional
approvalToken field with pointer to the federation spec.
This commit is contained in:
Jannis Braun
2026-04-26 11:53:54 +02:00
parent fa7a5f831d
commit 94294c64b9
3 changed files with 27 additions and 2 deletions
+3 -1
View File
@@ -217,7 +217,7 @@ DELETE /admin/users/:id → { success }
## Federation (`routes/federation.ts`)
```
POST /federation/peer/initiate (admin) { remoteOrigin } → peer created
POST /federation/peer/accept (public, IP rate-limited 10/min) { sourceOrigin, challenge, hmacSecret } → accepted
POST /federation/peer/accept (public, IP rate-limited 10/min) { sourceOrigin, challenge, hmacSecret, instanceName?, approvalToken? } → accepted (200) | queued (202 + { approvalToken })
GET /federation/peers (admin) → { peers[] } (no secrets)
DELETE /federation/peers/:id (admin) → { success } + outbox cleanup
POST /federation/relay (HMAC-signed S2S) FederationRelayRequest → { accepted[], rejected[] }
@@ -225,6 +225,8 @@ POST /federation/sync (HMAC-signed S2S) { sinceTimestamp, limit?,
POST /federation/users/lookup (HMAC-signed S2S, rate-limited 60/min/peer) { username } → { found, user? }
```
**`POST /api/federation/peer/accept`** — public, IP-rate-limited. Optional `approvalToken` (64-hex) on the request body proves mutual admin approval; required to promote an `awaiting_approval` row to `active` when the receiver has `autoAcceptPeering=0`. The receiver returns it in the 202 body when queueing the request for admin review (`{ queued: true, message, approvalToken }`); the initiator stores it and the receiver's `/approve` later forwards it back. See `federation.md` §1 "Approval Token Verification" for the full lifecycle and threat model.
**`POST /api/federation/users/lookup`** — HMAC-authenticated S2S endpoint. Resolves a username on this instance to its canonical `(homeUserId, profile snapshot)`. Used by the cross-instance friend-add flow on the sender's home server before queuing a `friend_request_create` event. Responds to native, non-deleted users only; ignores `discoverable`. Returns `{ found: false, code: 'user_not_found' }` for stubs, tombstoned users, or unknown handles. See `federation.md` §1 "S2S User Lookup" for the full contract.
## Utilities (`routes/utils.ts`) — auth required