First step of milestone 461 (MCP server). A token is the credential an
MCP client presents as `Authorization: Bearer stw_…` to act as its user.
- api_tokens table (0026): sha256 hash only, display prefix, role
ceiling, expiry, revocation, throttled last_used_at.
- steward/core/api_tokens.py: mint, list, revoke, resolve. Resolution
re-reads the user's current role and acts with the lower of that and
the token's ceiling, so demoting or disabling a user weakens or kills
their tokens with nothing to revoke by hand.
- /ai-access/ (sidebar → Automation → AI access): every user manages
their own tokens, can't grant above their own role, sees the token
once. Session-only: a share-link viewer is refused. Create and revoke
are audited.
- Integration tests drive the routes against real Postgres so their
transactions run for real (#884 escaped CI behind a mocked session).
Task #4965 "MCP-1 — Personal API tokens".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>