diff --git a/implementation-plan-api-dashboards.md b/implementation-plan-api-dashboards.md index 59423bb..ea0c470 100644 --- a/implementation-plan-api-dashboards.md +++ b/implementation-plan-api-dashboards.md @@ -17,6 +17,8 @@ Give members direct API access to the cooperative's models (alongside chat), a d ## Verified facts (from research) - **LiteLLM Teams** (open-source) provide: per-team budget, per-team spend tracking, and key attribution to both user and team. This is the abstraction layer for "unified account + multiple keys." +- **Clarification on "teams":** we use LiteLLM's open-source **team budget** feature (a budget container, referenced as `team_id`). We do **not** use the Premium **`team_admin` role / team-member permissions** — those are the paid features that would let members self-manage keys. We act as the "team admin" ourselves via the broker/master key instead. +- **Member-facing vocabulary:** members see "your account" / "your budget" / "your API keys" — never "team" (that's an internal implementation term). - **Spend endpoints** are live on our gateway: `/global/spend`, `/spend/logs`, `/user/info`, `/team/list` (all return 200). - **LiteLLM is v1.74.0, with Postgres** — so budgets and teams are fully supported. - **Key self-serve requires Premium.** The `team_admin` role and "team member can create keys" permission are both **✨ Premium Features**. On the OSS build, only the master key can mint keys. Hence the broker. @@ -109,3 +111,50 @@ The invariant: **a member's session can only ever (a) read their own team's data - **Broker is a new attack surface** — must be narrowly scoped and rate-limited. - **Migration touches existing members** — needs careful idempotency (reuse existing keys by alias). - **Spend-log scoping** — must verify `/spend/logs` can be filtered per-key/per-team so the member dashboard can't see others' usage. + +## Stepwise development process + +Build order with dependencies and verification gates. Each step must be verified in isolation before the next begins — no batching that obscures which step broke. + +### Step 1 — Confirm spend-log scoping (the riskiest unknown) + +*Resolves the "Risks" item that could invalidate the whole member dashboard.* + +- Query `/spend/logs` and `/user/info` filtered by a single key/team; confirm a team-scoped request returns **only that member's** rows, not everyone's. +- Also confirm the broker can read *only* the target member's team (no cross-team enumeration). +- **Gate:** if scoping isn't clean, the member dashboard must go through the broker for *reads too*, which changes the architecture. Resolve before any build. + +### Step 2 — Teams migration (Phase 1) + +- Extend the portal: create a team per member, move/create the chat key under it, keep `provision_member()` idempotent. +- Write a one-off migration script; dry-run it against the DB, then run against live members (Nathan, Liz, Dan, Ed, Lee). +- **Gate:** chat works end-to-end for a test member; `/team/list` shows one team per member; spend attributes per-team. + +### 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. + +### Step 4 — Member dashboard (Phase 3) + +- New Cloudron app in the "members" group (SSO-gated). Read-only (spend/keys/usage) + broker calls for create/revoke. +- **Gate:** a member logs in, sees only their own data, creates and revokes a key end-to-end, and the app holds no master key (verify via env inspection). + +### Step 5 — Admin dashboard (Phase 4) + +- Co-op-wide view, admin-gated. Build after the member dashboard stabilizes (lower urgency — LiteLLM's UI covers some of it). +- **Gate:** admins see all members + aggregate spend; members cannot reach it. + +### Step 6 — Documentation (Phase 5) + +- API endpoint + format + budget-sharing note; member dashboard how-to; add the budget-split open question. +- **Gate:** a brand-new member could follow the docs to retrieve a key and make an API call without help. + +### Rollback + +- Every phase is additive; a failed phase can be reverted by re-pointing the injector at the prior key scheme (Step 2) or removing the new app (Steps 4–5). No data loss: keys are re-creatable, teams are idempotent by alias. + +### Definition of done + +- A member can: chat, retrieve an API key, make a direct `curl` call to `gateway.inference.coop/v1`, see their own usage, and create/revoke keys — all within one $15 budget, with no member path touching the master key. +- An admin can see co-op-wide membership, spend, and per-model breakdown.