fix(hermes): reachability verdict must not come from the remote command's exit code #89
@@ -11,6 +11,24 @@ author: Abiba (pi agent)
|
|||||||
|
|
||||||
# Hermes Agent Baseline — Canonical Good State
|
# Hermes Agent Baseline — Canonical Good State
|
||||||
|
|
||||||
|
## Reachability Detection
|
||||||
|
|
||||||
|
Before checking agent baseline, verify the host is reachable and can be audited. Use the shared reachability helper from the clone root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run on each host to check reachability (Tanko, Mumuni, Koonimo, Koby)
|
||||||
|
scripts/hermes-reachability-check.sh <host> "api_key:" "/root/.hermes/config.yaml"
|
||||||
|
# Example: scripts/hermes-reachability-check.sh 192.168.68.122 "api_key:" "/root/.hermes/config.yaml"
|
||||||
|
|
||||||
|
# Expected outcomes:
|
||||||
|
# - UNREACHABLE: SSH connection failed (host is down)
|
||||||
|
# - VIOLATION: SSH succeeded and found matches (report the finding)
|
||||||
|
# - COMPLIANT: SSH succeeded and found no matches (no api_key in config)
|
||||||
|
#
|
||||||
|
# NOTE: The bug this replaces was deriving reachability from the remote grep's exit code.
|
||||||
|
# The correct pattern: remote side always succeeds (grep ...; true), so ssh status = connection only.
|
||||||
|
```
|
||||||
|
|
||||||
## Quick Restore
|
## Quick Restore
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -19,6 +19,24 @@ description: >
|
|||||||
- agent_keys: map (see Agent Keys section)
|
- agent_keys: map (see Agent Keys section)
|
||||||
- infra_endpoints_verified: array
|
- infra_endpoints_verified: array
|
||||||
|
|
||||||
|
## Reachability Detection
|
||||||
|
|
||||||
|
Before auditing the config template, verify the host is reachable and can be checked. Use the shared reachability helper from the clone root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run on each host to check reachability (Tanko, Mumuni, Koonimo, Koby)
|
||||||
|
scripts/hermes-reachability-check.sh <host> "base_url:" "/root/.hermes/config.yaml"
|
||||||
|
# Example: scripts/hermes-reachability-check.sh 192.168.68.122 "base_url:" "/root/.hermes/config.yaml"
|
||||||
|
|
||||||
|
# Expected outcomes:
|
||||||
|
# - UNREACHABLE: SSH connection failed (host is down)
|
||||||
|
# - VIOLATION: SSH succeeded and found matches (report the finding)
|
||||||
|
# - COMPLIANT: SSH succeeded and found no matches (no base_url in config)
|
||||||
|
#
|
||||||
|
# NOTE: The bug this replaces was deriving reachability from the remote grep's exit code.
|
||||||
|
# The correct pattern: remote side always succeeds (grep ...; true), so ssh status = connection only.
|
||||||
|
```
|
||||||
|
|
||||||
## Agent Keys (LiteLLM — Current 2026-07-11)
|
## Agent Keys (LiteLLM — Current 2026-07-11)
|
||||||
|
|
||||||
Each agent has a unique LiteLLM API key (virtual key) generated against the LiteLLM
|
Each agent has a unique LiteLLM API key (virtual key) generated against the LiteLLM
|
||||||
|
|||||||
@@ -117,6 +117,24 @@ model:
|
|||||||
api_key_env: LITELLM_API_KEY
|
api_key_env: LITELLM_API_KEY
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Reachability Detection
|
||||||
|
|
||||||
|
Before checking for hardcoded keys, verify the host is reachable and can be audited. Use the shared reachability helper from the clone root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run on each host to check reachability (Tanko, Mumuni, Koonimo, Koby)
|
||||||
|
scripts/hermes-reachability-check.sh <host> "api_key: sk-" "/root/.hermes/"
|
||||||
|
# Example: scripts/hermes-reachability-check.sh 192.168.68.122 "api_key: sk-" "/root/.hermes/"
|
||||||
|
|
||||||
|
# Expected outcomes:
|
||||||
|
# - UNREACHABLE: SSH connection failed (host is down)
|
||||||
|
# - VIOLATION: SSH succeeded and found matches (report the finding)
|
||||||
|
# - COMPLIANT: SSH succeeded and found no matches (no hardcoded keys in config)
|
||||||
|
#
|
||||||
|
# NOTE: The bug this replaces was deriving reachability from the remote grep's exit code.
|
||||||
|
# The correct pattern: remote side always succeeds (grep ...; true), so ssh status = connection only.
|
||||||
|
```
|
||||||
|
|
||||||
## Detection Query
|
## Detection Query
|
||||||
|
|
||||||
Run on any Hermes host to detect violations:
|
Run on any Hermes host to detect violations:
|
||||||
|
|||||||
Executable
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Shared helper for Hermes contract reachability checks
|
||||||
|
# Separates SSH exit status from remote command result
|
||||||
|
|
||||||
|
hermes_check_host() {
|
||||||
|
local host=$1
|
||||||
|
local pattern=$2
|
||||||
|
local path=$3
|
||||||
|
|
||||||
|
# Remote side always succeeds (grep ...; true), so ssh exit code = connection status only
|
||||||
|
local out
|
||||||
|
out=$(ssh -o BatchMode=yes -o ConnectTimeout=3 root@"$host" "grep -RIn '$pattern' '$path' 2>/dev/null; true" 2>/dev/null)
|
||||||
|
local status=$?
|
||||||
|
|
||||||
|
if [ $status -ne 0 ]; then
|
||||||
|
echo "$host: UNREACHABLE (ssh exit $status)"
|
||||||
|
elif [ -n "$out" ]; then
|
||||||
|
echo "$host: VIOLATION: $out"
|
||||||
|
else
|
||||||
|
echo "$host: COMPLIANT (no matches found)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standalone mode: scripts/hermes-reachability-check.sh <host> <pattern> <path>
|
||||||
|
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
||||||
|
if [ $# -ne 3 ]; then
|
||||||
|
echo "Usage: $0 <host> <pattern> <path>" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
hermes_check_host "$1" "$2" "$3"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user