diff --git a/implementation-plan-api-dashboards.md b/implementation-plan-api-dashboards.md index 4191f6f..a1acf25 100644 --- a/implementation-plan-api-dashboards.md +++ b/implementation-plan-api-dashboards.md @@ -154,8 +154,12 @@ Member (browser) ──SSO──▶ Member Dashboard (new Cloudron app, "members ### Step 3 — Broker (Phase 2) -- Add token-protected `create-key` / `revoke-key` endpoints in the portal, scoped to a member's team, rate-limited. -- **Gate:** mint a key for a test member, confirm it draws from their team budget and appears under their team; revoke works. +**COMPLETED (2026-09-13).** The portal now serves as the broker for member-managed API keys. + +- Added `member_api_keys` table (email + name → sk_token + hash) and three endpoints under `/broker/keys` (GET list, POST create, DELETE revoke). +- Authentication: the member dashboard passes `X-Broker-Secret` (shared secret, `BROKER_SECRET` env) + `X-Member-Email`. The portal verifies the secret and that the email is an active member. Fail-closed: missing/wrong secret → 401, non-member → 403. +- Each API key is a LiteLLM virtual key under the member's team (`alias: api::`), so it draws from the same $15 team budget as chat. The `sk-` token is returned once and stored; the hash is kept for revoke. +- Verified: create/list/revoke all work; the API key completes real inference; security boundaries hold (wrong secret 401, non-member 403, no-secret 401). ### Step 4 — Member dashboard (Phase 3)