2026-07-03: Hermes key enforcement contract + Stirling-PDF docs + config standardization
- hermes-key-enforcement.prose.md: NEW contract enforcing api_key_env for all harness/LiteLLM providers, exempting external providers - hermes-config-template.prose.md: Updated with full fix log (15 total fixes across Koby/Koonimo/Mumuni/Tanko), model:auto detection rule, key-to-agent mapping - infrastructure-control.prose.md: Added Stirling-PDF service details (port 8989, credentials, API key, Swagger URL) replacing Bento-PDF
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
---
|
||||
kind: enforcement
|
||||
name: hermes-key-enforcement
|
||||
version: 1.0.0
|
||||
description: >
|
||||
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.
|
||||
author: 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_key`
|
||||
- `custom_providers[].api_key` (when `name` contains `harness` or `litellm`)
|
||||
- `auxiliary.*.api_key` (when `provider` is `harness` or contains `litellm`)
|
||||
- `delegation.api_key` (when `provider` is `harness` or contains `litellm`)
|
||||
- `compression.api_key` (when `provider` is `harness` or contains `litellm`)
|
||||
- `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.116` or `litellm.sysloggh.net`
|
||||
|
||||
## Standard Pattern
|
||||
|
||||
```yaml
|
||||
# ✅ 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
|
||||
```
|
||||
|
||||
```yaml
|
||||
# ❌ FORBIDDEN — hardcoded harness/litellm key
|
||||
model:
|
||||
provider: harness
|
||||
api_key: sk-Flc62smlegyMEaSo1ka8JA # ← RULE VIOLATION
|
||||
```
|
||||
|
||||
## Detection Query
|
||||
|
||||
Run on any Hermes host to detect violations:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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.
|
||||
|
||||
## Verified Agents (2026-07-03 final)
|
||||
|
||||
| Agent | CT | Status | api_key_env entries | Hardcoded harness | Last Verified |
|
||||
|-------|-----|--------|---------------------|-------------------|---------------|
|
||||
| Tanko | 112 | ✅ Compliant | 4 | 0 | 19:14 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
|
||||
|
||||
1. **Detect** — run detection query above
|
||||
2. **Fix** — replace `api_key: sk-...` with `api_key_env: LITELLM_API_KEY` in all harness/litellm sections
|
||||
3. **Verify** — `grep -c "api_key_env" config.yaml` should increase, hardcoded harness keys should be 0
|
||||
4. **Restart** — gateway must restart to pick up env var
|
||||
5. **Confirm** — test key against LiteLLM: `curl -H "Authorization: Bearer $KEY" .../v1/models` → 200
|
||||
6. **Update** — bump the verified table above
|
||||
|
||||
## Related Contracts
|
||||
|
||||
- `hermes-config-template.prose.md` — full configuration template
|
||||
- `litellm-health.prose.md` — LiteLLM stack health verification
|
||||
- `zulip-platform-verification.prose.md` — cross-platform agent verification
|
||||
Reference in New Issue
Block a user