Dashboard
The tenant dashboard at /dashboard is the web UI for everything the CLI
does, minus the typing. Open it, paste your API key when asked — the key is
kept in the browser, and the sponsor token is never stored.
What it’s for:
- Usage — checks, decisions, and receipt volume for the tenant.
- Billing — the free-tier meter (1,000 receipts/month), billing status,
and whether a payment method is on file. Sign in with your API key, or
click Email me a sign-in link for a one-time 15-minute link — no key
pasting. Add payment method opens Stripe’s hosted billing portal (card
details never touch Writ); Stripe returns you to the dashboard, which
confirms the card and lifts the
402 payment_requiredgate. - Policy editor — set per-verb modes (
allow,deny,require_grant,step_up) without the CLI. Changes take effect immediately. - Team invites — create invite codes; see who holds a key on the tenant.
- Live audit log — the same stream as
./writ stream, in the browser. Filter by verb, decision, or principal. - Kill switch — revoke or reinstate a principal. Revocation takes effect on the next check.
The API behind it: POST /v1/auth/magic-link ({email}) emails the
single-use link and always returns 200 for unknown emails; GET /v1/auth/verify?token=... burns the token and sets an HttpOnly signed
session cookie (24h) bound to the tenant; POST /v1/billing/portal accepts
the API key or that session cookie and returns the Stripe portal URL.
Anything the dashboard can do, the API and CLI can do — it’s a convenience layer, not a separate system. Grants and revocations still require the sponsor token, which you paste per action.