Skip to content

Runbook — set up a group's AI key

Goal: give a class / cohort its own AI budget, so its projects’ analyses run on its key. Two steps: mint a LiteLLM key, then record it on the group in your identity provider. rvmc does the rest automatically.

When to run: onboarding a new class/cohort, or rotating a group’s key.

Why it exists: rvmc maps project → its IdP group → the group's litellm_key and hands that key to the autopsy analysis. All budget/model scope lives on the key in LiteLLM. Without this setup a group’s projects fall back to the server-default key.

This runbook uses Authentik (the reference deployment’s IdP) for the concrete steps; any OIDC provider whose groups can hold a readable custom attribute works the same way — see AI configuration → Your OIDC provider.

Prerequisites

  • The LiteLLM master key (admin) for your LiteLLM proxy.
  • IdP admin (to edit the group’s attributes).
  • The group the class uses already exists and is granted to the group’s projects (the groups field at POST /admin/provision).

1. Mint the group’s LiteLLM key

Create a virtual key scoped to the models the group may use, with its budget. Name it after the group so it’s findable later.

Terminal window
curl -sS -X POST https://your-litellm.example/key/generate \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"key_alias": "media-art-2026",
"models": ["your-provider/model-a", "your-provider/model-b"],
"max_budget": 200,
"budget_duration": "30d",
"metadata": {"group": "media-art-2026"}
}'

The response contains "key": "sk-…"this is the only time LiteLLM returns the plaintext. Copy it now; you record it on the group in step 2. (Budget/models are enforced by LiteLLM; rvmc never sees them.)

2. Record it on the Authentik group

Set the key as the group’s litellm_key attribute. In the Authentik admin UI:

  1. Directory → Groups → media-art-2026 → Edit.
  2. In Attributes (YAML), add:
    litellm_key: sk-…
  3. Save.

Or via the Authentik API:

Terminal window
curl -sS -X PATCH "$AUTHENTIK_URL/api/v3/core/groups/$GROUP_PK/" \
-H "Authorization: Bearer $AUTHENTIK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"attributes": {"litellm_key": "sk-…"}}'

Note: this puts a (scoped, budget-capped) key in the directory as a group attribute — the accepted trade-off for managing the whole mapping in one pane. It is a LiteLLM virtual key, not a raw provider secret.

Other OIDC providers: the equivalent in Keycloak is a group attribute named litellm_key, exposed via a group-membership + attribute mapper so the controller can read it; any IdP with readable group attributes works the same way.

3. Verify

  • rvmc caches the attribute for ~5 minutes; a new/rotated key is picked up on the next dispatch after the TTL (or a controller restart).
  • Start an analysis on a project owned by that group and confirm the run uses the key — LiteLLM’s spend for key_alias=media-art-2026 should increase (GET /key/info / the LiteLLM /ui).
  • Self-host / no Authentik: skip this entirely — autopsy uses AUTOPSY_LLM__*.

Rotating a key

  1. Mint a new key (step 1), or POST /key/regenerate in LiteLLM.
  2. Update the group’s litellm_key attribute (step 2).
  3. Wait out the cache TTL (~5 min) or restart the controller.

What can go wrong

  • Group has no litellm_key → its projects use the server-default key (not an error; just not group-billed). Check the attribute name is exactly litellm_key.
  • Project resolves to the wrong group → provisioning always leaves a project with at least one group (an explicit groups grant, or the seeded convention group proj-<pid>), so resolution never fails outright — but if the cohort group with the key is not in the project’s groups, rvmc walks proj-<pid> instead, finds no litellm_key there, and the run silently falls back to the server-default key. Diagnosis: no spend on the cohort key while runs succeed. Fix: grant the cohort group to the project (groups at provision), or put the litellm_key attribute on the group the project actually resolves to.
  • Key over budget → LiteLLM rejects calls; the analysis degrades (surfaced in the run, not a silent stop). Raise the budget in LiteLLM.