55 lines
3.7 KiB
Markdown
55 lines
3.7 KiB
Markdown
# Destructive Action Protocol
|
|
|
|
User-approved security policy (Jul 5, 2026). Applies to ALL state-changing operations.
|
|
|
|
## Secret consolidation: .env file
|
|
|
|
When consolidating secrets out of standalone files and config.yaml into `.env`:
|
|
|
|
1. **Audit** — `grep -rn "api_key\|token\|password\|secret"` across config.yaml, all `.env` files, and scripts/
|
|
2. **Collect** — read each standalone file (.hetzner_token, .netcup_api_key, etc.) and the existing `.env`
|
|
3. **Merge** — add missing variables to `.env` using existing format (`KEY=VALUE`). API keys, tokens, and passwords all go here
|
|
4. **Secure** — `chmod 600 ~/.hermes/.env`
|
|
5. **Remove** — delete now-redundant standalone files
|
|
6. **Test** — run backup/snapshot scripts and verify they still work with the new `.env`-only layout
|
|
|
|
**⚠️ Do NOT embed API keys or tokens in config.yaml** — config is read by every Hermes command invocation. `.env` is only loaded by the gateway process. Keys in config.yaml are visible to any tool invocation or script.
|
|
|
|
## Real-time email monitoring for booking confirmations
|
|
|
|
During trip planning, the user may initiate bookings (rental cars, flights) on their end. When asked to check for results:
|
|
|
|
1. **Search by sender since last 24h**: `(FROM "Avis" SINCE ${since_imap_date})`
|
|
2. **Expect chains**: security code → password reset → confirmation. The last one is the booking.
|
|
3. **Extract from confirmation**: reservation number, vehicle class, pickup/dropoff locations and times, total
|
|
4. **Report concisely** in a table, then update the itinerary document and todo list
|
|
|
|
## The protocol
|
|
|
|
Before ANY destructive or state-changing operation (reboot, shutdown, power-cycle, DNS change, config deploy, service restart, firewall rule change, container destroy, API key rotation, file deletion):
|
|
|
|
Before ANY destructive or state-changing operation (reboot, shutdown, power-cycle, DNS change, config deploy, service restart, firewall rule change, container destroy, API key rotation, file deletion):
|
|
|
|
1. **Verify the target** — resolve opaque identifiers to hostname + IP. For Hetzner API calls, run a server resolution before the action. Never use mental memory of server IDs.
|
|
2. **State hostname + IP** to the user in the message before executing.
|
|
3. **Flag risk** — if the target runs active services (N8N, Postgres, LLM proxy, Docker containers with state), say so explicitly.
|
|
4. **Wait for explicit yes** — do not execute on silence, implied consent, or previous approvals.
|
|
5. **Do not rely on server IDs alone** — they are visually indistinguishable from one another.
|
|
|
|
## Full policy (memory)
|
|
|
|
The complete policy stored in Hermes memory covers:
|
|
- **Read-only default** — any state change needs explicit approval
|
|
- **Approval tiers** — Read = automatic, Scoped write = ask, Dangerous (reboot, delete, DNS, config) = state impact + wait for yes
|
|
- **Minimum-permission API keys** — flag overly broad keys, ask to narrow
|
|
- **Session summaries** — log of every operation and consequence after changes
|
|
- **No assumed consent** — previous approval does not imply future approval
|
|
|
|
## Incidents that informed this policy
|
|
|
|
### Wrong-server reboot (Jul 5, 2026)
|
|
Accidentally rebooted `app1.itpropartner.com` (87.99.144.163, N8N+Postgres host, Hetzner ID 127781917) thinking it was `app1-bu` (5.161.114.8, dormant standby, Hetzner ID 125997675). The IDs are close enough to confuse in memory but one runs production databases. Root cause: relied on mental memory of opaque Hetzner API IDs instead of resolving them to hostname+IP first.
|
|
|
|
### Config key invention (prior to Jul 5)
|
|
Claimed `fallback_providers` was a real Hermes config option. It is not — Hermes silently accepts unknown YAML keys without validation. The key does nothing at runtime. User corrected with "don't be making shit up."
|