From 895858c60a0ed755192e69ba75c632d9c85e7342 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 4 Jul 2026 22:48:48 +0000 Subject: [PATCH] feat: LiteLLM API key management contract + longevity policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New contract: litellm-api-keys.prose.md — create/rotate/verify named API keys - Renamed tanko key alias from tanko-jul2026 to tanko (bare name) - Added Key Longevity Policy: permanent keys (duration:null), event-driven rotation - Added default_key_generate_params to litellm config (permanent + 00 budget) - Updated hermes-key-enforcement verified agents table for 2026-07-04 --- hermes-key-enforcement.prose.md | 24 +++++++++++++-- litellm-api-keys.prose.md | 52 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 litellm-api-keys.prose.md diff --git a/hermes-key-enforcement.prose.md b/hermes-key-enforcement.prose.md index 62cb69f..e99fb3c 100644 --- a/hermes-key-enforcement.prose.md +++ b/hermes-key-enforcement.prose.md @@ -96,11 +96,31 @@ curl -s -H "Authorization: Bearer sk-NEW_KEY" http://192.168.68.116/v1/models **Done.** No config file changes needed. The agent picks up the new key on restart. -## Verified Agents (2026-07-03 final) +## Key Longevity Policy (2026-07-04) + +**Keys are permanent and use bare agent name aliases.** + +- **Duration**: `null` — keys never expire. This is enforced by `default_key_generate_params` in `litellm_config.yaml`. +- **Alias convention**: bare agent name only (e.g., `tanko`, `mumuni`, `koby`, `koonimo`). No dates, no versions. The alias IS the identity. +- **Rotation triggers**: compromise, personnel departure, or quarterly security hygiene. NOT calendar-driven. +- **Max budget**: $100 per key (config default). + +```yaml +# In litellm_config.yaml — ensures all future keys inherit these defaults: +litellm_settings: + default_key_generate_params: + models: ["syslog-auto", "qwen3.6-27B-code", "gemma-4-12b"] + duration: null # ← permanent + max_budget: 100 + metadata: + purpose: "agent-inference" +``` + +## Verified Agents (2026-07-04 final) | Agent | CT | Status | api_key_env entries | Hardcoded harness | Last Verified | |-------|-----|--------|---------------------|-------------------|---------------| -| Tanko | 112 | ✅ Compliant | 4 | 0 | 19:14 EDT | +| Tanko | 112 | ✅ Compliant (key: tanko) | 4 | 0 | 22:45 EDT | | Mumuni | 114 | ✅ Compliant | 8 | 0 | 19:14 EDT | | Koby | 111 | ✅ Compliant | 14 | 0 | 19:14 EDT | | Koonimo | 113 | ✅ Compliant | 7 | 0 | 19:14 EDT | diff --git a/litellm-api-keys.prose.md b/litellm-api-keys.prose.md new file mode 100644 index 0000000..3a0e0ec --- /dev/null +++ b/litellm-api-keys.prose.md @@ -0,0 +1,52 @@ +--- +kind: function +name: litellm-api-keys +description: > + Manages LiteLLM API keys for agent identity. Creates named keys so each agent + is identifiable in LiteLLM logs/spend tracking. Keys are permanent (no expiry) + and use the agent's bare name as alias (e.g., "tanko", not "tanko-jul2026"). + Ensures agents never use the master key directly. Rotation is event-driven, + not calendar-driven — rotate only on compromise, personnel change, or + periodic security hygiene (quarterly/annually). +--- + +## Parameters + +- agent_name: string — The agent to manage keys for (e.g., "tanko", "mumuni") +- action: "create" | "rotate" | "verify" | "list" — What to do (default: "create") +- litellm_host: string — LiteLLM admin endpoint (default: "192.168.68.116:4000") +- master_key: string — LiteLLM master key (default from environment) +- agent_host: string — Agent's IP for SSH (default: resolved from infra) +- agent_user: string — SSH user (default: "jerome") + +## Returns + +- action: string — What was done +- key_alias: string — The LiteLLM key alias created/rotated +- key_prefix: string — First 10 chars of the new key (for identification) +- previous_key_alias: string | null — Previous key alias if rotating +- litellm_response: object — Raw response from LiteLLM /key/generate +- agent_config_updated: boolean — Whether /etc/environment was updated +- verification: { status: string, detail: string } — Final health check + +## Execution + +1. **Authenticate** — Verify master_key works against LiteLLM /key/list +2. **Check existing keys** — List all keys, find any with agent_name alias +3. **If action == "list"**: Return all keys with their aliases and spend +4. **If action == "create"**: + - Generate new key with key_alias: "{agent_name}" (e.g., "tanko" — bare name, no date) + - Set metadata: { "agent": "{agent_name}", "purpose": "agent-inference" } + - Duration is null (permanent) — inherited from litellm default_key_generate_params + - Set models: ["syslog-auto", "qwen3.6-35B-A3B", "qwen3.6-27B-code", "gemma-4-12b"] + - Return the new key +5. **If action == "rotate"**: + - Generate new key with same alias (LiteLLM replaces the old key) + - SSH to agent_host, update /etc/environment LITELLM_API_KEY + - Restart agent gateway (hermes gateway restart for Hermes agents) + - Verify: curl test against /v1/models with new key + - Rotation policy: on-demand only (compromise, departure, quarterly hygiene) +6. **If action == "verify"**: + - SSH to agent, read /etc/environment + - Test the key against LiteLLM /v1/models + - Confirm key alias matches agent_name in LiteLLM key list