- 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
5.1 KiB
5.1 KiB
kind, name, version, description, author
| kind | name | version | description | author |
|---|---|---|---|---|
| enforcement | hermes-key-enforcement | 1.0.0 | Enforces standardized API key configuration across all Hermes agents. Harness/LiteLLM providers MUST use api_key_env indirection. External providers (DeepSeek, OpenAI, Anthropic) may use hardcoded keys. Single source of truth: /etc/environment on each agent host. Designed to make key rotation a one-step operation. | Abiba (pi agent) |
Hermes Key Enforcement Contract
Rule (One Sentence)
Any api_key pointing to a Syslog-hosted LiteLLM/harness provider MUST be replaced with api_key_env: LITELLM_API_KEY — hardcoded harness keys are forbidden.
Scope
Applies to all Hermes agent configs across all hosts. Covers these config sections:
model.api_keycustom_providers[].api_key(whennamecontainsharnessorlitellm)auxiliary.*.api_key(whenproviderisharnessor containslitellm)delegation.api_key(whenproviderisharnessor containslitellm)compression.api_key(whenproviderisharnessor containslitellm)fallback_providers[].api_key(when provider is harness)
Exemptions
External providers are explicitly exempt and may use hardcoded keys:
- DeepSeek (
api.deepseek.com) - OpenAI (
api.openai.com) - Anthropic (
api.anthropic.com) - OpenRouter
- Any provider whose base_url does NOT match
192.168.68.116orlitellm.sysloggh.net
Standard Pattern
# ✅ CORRECT — all harness/litellm providers
model:
provider: harness # or custom:litellm.sysloggh.net
base_url: http://192.168.68.116/v1
api_key_env: LITELLM_API_KEY # ← indirection
custom_providers:
- name: harness
base_url: http://192.168.68.116/v1
api_key_env: LITELLM_API_KEY # ← indirection
auxiliary:
compression:
provider: harness
api_key_env: LITELLM_API_KEY # ← indirection
# ✅ ALSO CORRECT — external providers
fallback_providers:
- provider: deepseek
base_url: https://api.deepseek.com
api_key: sk-b7d9... # ← hardcoded OK (external)
api_key_env: DEEPSEEK_API_KEY # ← also OK if set in /etc/environment
# ❌ FORBIDDEN — hardcoded harness/litellm key
model:
provider: harness
api_key: sk-Flc62smlegyMEaSo1ka8JA # ← RULE VIOLATION
Detection Query
Run on any Hermes host to detect violations:
grep -n 'api_key: sk-' /root/.hermes/config.yaml \
| grep -v 'deepseek\|b7d9\|openai\|anthropic\|DEEPSEEK'
If any output — violation. Fix immediately.
Rotation Procedure
With this standard enforced, key rotation is one step:
# 1. Generate new key in LiteLLM
# 2. Update /etc/environment on agent host
ssh root@<host> "sed -i 's/LITELLM_API_KEY=.*/LITELLM_API_KEY=sk-NEW_KEY/' /etc/environment"
# 3. Restart agent gateway
ssh root@<host> "pkill -f 'hermes_cli.main gateway run'; sleep 2; nohup ... &"
# 4. Verify
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.
Key Longevity Policy (2026-07-04)
Keys are permanent and use bare agent name aliases.
- Duration:
null— keys never expire. This is enforced bydefault_key_generate_paramsinlitellm_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).
# 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 (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 |
| Abiba | 100 | ✅ N/A (pi native) | — | — | 19:14 EDT |
| Kagenz0 | 105 | ❌ DOWN | — | — | 19:14 EDT |
Violation Response
- Detect — run detection query above
- Fix — replace
api_key: sk-...withapi_key_env: LITELLM_API_KEYin all harness/litellm sections - Verify —
grep -c "api_key_env" config.yamlshould increase, hardcoded harness keys should be 0 - Restart — gateway must restart to pick up env var
- Confirm — test key against LiteLLM:
curl -H "Authorization: Bearer $KEY" .../v1/models→ 200 - Update — bump the verified table above
Related Contracts
hermes-config-template.prose.md— full configuration templatelitellm-health.prose.md— LiteLLM stack health verificationzulip-platform-verification.prose.md— cross-platform agent verification