diff --git a/hermes-agent-baseline.prose.md b/hermes-agent-baseline.prose.md index fba3a89..8f814b8 100644 --- a/hermes-agent-baseline.prose.md +++ b/hermes-agent-baseline.prose.md @@ -11,6 +11,24 @@ author: Abiba (pi agent) # 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 "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 ```bash diff --git a/hermes-config-template.prose.md b/hermes-config-template.prose.md index a6e3d29..b04d93e 100644 --- a/hermes-config-template.prose.md +++ b/hermes-config-template.prose.md @@ -19,6 +19,24 @@ description: > - agent_keys: map (see Agent Keys section) - 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 "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) Each agent has a unique LiteLLM API key (virtual key) generated against the LiteLLM diff --git a/hermes-key-enforcement.prose.md b/hermes-key-enforcement.prose.md index 3c5e42c..ee38b0d 100644 --- a/hermes-key-enforcement.prose.md +++ b/hermes-key-enforcement.prose.md @@ -117,6 +117,24 @@ model: 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 "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 Run on any Hermes host to detect violations: diff --git a/scripts/hermes-reachability-check.sh b/scripts/hermes-reachability-check.sh new file mode 100755 index 0000000..ba6ec1b --- /dev/null +++ b/scripts/hermes-reachability-check.sh @@ -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 +if [ "${BASH_SOURCE[0]}" = "${0}" ]; then + if [ $# -ne 3 ]; then + echo "Usage: $0 " >&2 + exit 2 + fi + hermes_check_host "$1" "$2" "$3" + exit 0 +fi