Operate Vouch with the admin UI and CLI
Everything an operator does goes through the /admin/* API, which requires an
account with is_admin. There are two front ends for it: the admin area of
the web client (#/admin/…, shown only to admins) and the vouch CLI
(server/: uv run vouch …). They expose the same information; use whichever
is at hand.
Become an admin
Section titled “Become an admin”Register with the bootstrap token (VOUCH_ADMIN_BOOTSTRAP_TOKEN; in
production it lives in AWS Secrets Manager under vouch/app):
uv run vouch register <name> --admin-token <token> --adult --accept-notice --url https://api.<domain>Or promote nobody: the token is the only way to mint an admin, on purpose.
Sessions in the CLI
Section titled “Sessions in the CLI”vouch login / vouch register store a refresh cookie for one API URL in
$XDG_CONFIG_HOME/vouch/cli.json; every command exchanges it for a fresh
access token (and a rotated cookie), so revoking that session from the web
client’s account tab locks the CLI out too. vouch logout revokes it.
--url or VOUCH_URL selects the deployment.
What to look at
Section titled “What to look at”| Question | Web | CLI |
|---|---|---|
| Is the service healthy? Counts, matcher, migration, settings | #/admin/overview |
vouch admin overview |
| Who is this user? | #/admin/users → row |
vouch admin users --q name, vouch admin user <id> |
| Why is a pair stuck? | #/admin/pairs → row |
vouch admin pairs --state awaiting_one, vouch admin pair <id> |
| Anything reported? | #/admin/reports |
vouch admin reports |
| What code was texted (dev only)? | #/admin/sms |
vouch admin sms-outbox |
| Run a full matcher pass now | #/admin/system |
vouch admin run-matcher |
| Who did what as an admin | #/admin/audit |
vouch api GET /admin/audit |
| Anything the UI does not have | /docs (Swagger) |
vouch api GET /admin/… |
Moderation
Section titled “Moderation”- A user files a report from a match (
POST /me/reports). It appears in the reports queue with both usernames. - Decide.
vouch admin ban <user-id> "<reason>"(or the button in the user drawer) setsbanned_at, revokes every session, and makes each of the user’s requests answer403 account_banned.unbanlifts it.delete-userremoves the account and everything attached. vouch admin resolve <report-id> "<what you did>"closes the report.
Reports survive a ban; deleting either account removes them, and resolved
reports are purged after VOUCH_REPORT_RETENTION_DAYS. Every admin write
(ban, unban, delete, resolve, run matcher) is recorded in the audit log with
the admin’s id and username.
The matcher
Section titled “The matcher”Pairs are created inline when a user publishes or changes preferences (one
query against every compatible user). The background loop, every
VOUCH_MATCHER_INTERVAL_SECONDS, does the whole-userbase safety-net pass in
one replica: the one holding a Postgres advisory lock. The overview shows
runs, skipped (this replica lost the election) and the last result or
error. “Run matcher” forces a full pass from the request path.
The SMS outbox
Section titled “The SMS outbox”With VOUCH_SMS_BACKEND=log the API keeps the last 50 codes it “sent” in
memory (numbers masked to two digits). That is how local development, the
test suite, vouch sim demo and scripts/demo_e2e.py complete phone
verification. With sns the endpoint answers 404 outbox_unavailable; codes
only exist on the recipient’s phone.
Data requests
Section titled “Data requests”- Access / portability: the user’s account tab → download my data, or
vouch api GET /me/exportas that user. - Erasure: the user deletes their own account, or an admin runs
vouch admin delete-user <id>.