Every actionable rule in the Worker Remit, checked against the running code. Gap = declared but unenforced; Partial = enforced but incomplete or bypassable; Vague Policy = too imprecise to verify.
| Rule ID | Section | Rule (quoted) | Status | Finding |
|---|---|---|---|---|
| R-01 | Non-Goals (Out of Scope) | "Serve untrusted, unauthenticated callers on any surface." | Verified | — |
| R-02 | Non-Goals (Out of Scope) | "Emit outbound telemetry, usage attribution, analytics, or third-party identifier tagging without an explicit operator opt-in." | Verified | — |
| R-03 | Non-Goals (Out of Scope) | "Move operator credentials or session-authorization material to any destination outside the operator's trust envelope." | Verified | — |
| R-04 | Non-Goals (Out of Scope) | "Act as a general web service exposed to the public internet without an external authentication/VPN/firewall layer in front of it." | Verified | — |
| R-05 | Approved Communication Channels | "Any messaging platform without a configured allowlist must serve no one (fail closed)." | Verified | — |
| R-06 | Approved Communication Channels | "Loopback bind is the default; a non-loopback bind must engage authentication." | Verified | — |
| R-07 | Approved Communication Channels | "Password-only auth must not be used for a publicly-exposed backend." | Verified | — |
| R-08 | Tools and Capabilities | "Any terminal command matching a dangerous/destructive pattern must require explicit human approval before it runs (on host-reaching backends)." | Partial | PRAX-2026-07-11-001 |
| R-09 | Tools and Capabilities | "Installing a third-party skill or plugin must surface its contents for operator review before it is loaded/executed." | Verified | — |
| R-10 | Tools and Capabilities | "/reload-mcp, and destructive session commands (/clear, /new, /reset, /undo) must confirm before discarding state, unless the operator has turned that confirmation off." | Verified | — |
| R-11 | Tools and Capabilities | "Any tool whose sole function is to exfiltrate operator credentials, environment secrets, or session tokens to an external destination." | Verified | — |
| R-12 | Data Boundaries | "Credentials and gateway tokens MUST NOT be passed into lower-trust child processes (shell subprocesses, execute_code, MCP subprocesses, cron scripts) except variables the operator or a loaded skill has explicitly declared as passthrough." | Verified | — |
| R-13 | Data Boundaries | "Secrets MUST NOT be written to logs, transcripts, error messages returned to the model, or any outbound adapter payload." | Verified | — |
| R-14 | Data Boundaries | "Pairing codes and auth secrets MUST NOT be logged to stdout or persisted in world-readable files." | Verified | — |
| R-15 | Data Boundaries | "Operator PII in the system-prompt session-context block SHOULD be redactable and MUST NOT be broadened beyond what routing requires." | Vague Policy | — |
| R-16 | Data Boundaries | "Credentials MUST NOT be committed to version control or stored in the main (shareable) config file." | Verified | — |
| R-17 | Action Boundaries | "Any terminal command matching a dangerous/destructive pattern on a host-reaching backend MUST prompt the operator and MUST NOT execute until approved." | Partial | PRAX-2026-07-11-001 |
| R-18 | Action Boundaries | "When an approval prompt is not answered within the configured window, the action MUST be denied (fail closed)." | Verified | — |
| R-19 | Action Boundaries | "Cron jobs that hit a dangerous-command prompt MUST default to denying it rather than silently auto-approving." | Verified | — |
| R-20 | Action Boundaries | "Binding any local-only surface to a non-loopback interface MUST be a deliberate operator action that engages an authentication layer." | Verified | — |
| R-21 | Action Boundaries (Never Allowed) | "Executing a catastrophic, irreversible command (filesystem-root wipe, fork bomb, formatting a mounted device, zeroing a physical disk, piping an untrusted remote script straight to a shell) MUST be refused unconditionally — even under --yolo, approvals.mode: off, a permanent allowlist entry, or headless cron approve-mode." | Verified | — |
| R-22 | Action Boundaries (Never Allowed) | "Dispatching agent work, resolving an approval, or returning agent output to a caller who is outside the configured authorization set (allowlist, pairing approval, or OS-level equivalent) MUST NOT be possible; treating a session identifier as proof of authorization is forbidden." | Verified | — |
| R-23 | Action Boundaries (Never Allowed) | "A network-exposed adapter MUST NOT fail open (serve callers) when no allowlist / auth provider is configured." | Verified | — |
| R-24 | Action Boundaries (Never Allowed) | "Credentials or session-authorization material MUST NOT leak to any destination outside the operator's trust envelope through environment leakage, adapter logging, or transport error paths." | Verified | — |
| R-25 | Action Boundaries (Hermes Desktop) | "The desktop-launched backend MUST remain a JSON-RPC/API surface only (no unintended browser-reachable UI) and MUST stay bound to loopback unless the operator deliberately configures a remote/authenticated setup." | Verified | — |
| R-26 | Behavioral Expectations | "Sessions are isolated from one another; one session MUST NOT read another session's data or state." | Verified | — |
| R-27 | Behavioral Expectations | "Cron sessions run with a hard interrupt bound so a runaway loop cannot monopolize the scheduler." | Verified | — |
| R-28 | Behavioral Expectations | "Agent actions and decisions are recorded to durable, operator-inspectable logs." | Verified | — |
| R-29 | Behavioral Expectations | "tool-calling iterations MUST be bounded per turn/subagent; a session repeatedly failing across restarts MUST be escalated to a clean reset rather than retried indefinitely." | Verified | — |
| R-30 | Behavioral Expectations | "a command that was denied or blocked MUST NOT be silently retried or rephrased to evade the guard." | Enforcement Not Possible | — |
Findings, ordered by severity — each linked to its remit rule, evidence, and a recommended action. Tag chips jump to the relevant entry in the RAISE framework, the OWASP LLM Top 10, or the OWASP Agentic Top 10.
LLM06 primary — the finding's main OWASP categoryASI10 secondary — a category it also touches
HIGH PRAX-2026-07-11-001 Dangerous shell commands auto-approve (fail open) in a headless non-interactive context, completing an external-input-to-host-execution chain on the default backend.
"Any terminal command matching a dangerous/destructive pattern must require explicit human approval before it runs (on host-reaching backends). / Any terminal command matching a dangerous/destructive pattern on a host-reaching backend MUST prompt the operator and MUST NOT execute until approved."
- Make the dangerous-command path fail closed by default in non-interactive non-cron contexts (pass fail_closed_when_no_human=True from check_dangerous_command, mirroring request_tool_approval), or require an explicit operator opt-in env/config flag to preserve the auto-approve behavior.
- Document the headless fail-open explicitly in the deployment-hardening guidance and gate it behind a sandboxed backend when untrusted input is in scope.
MEDIUM PRAX-2026-07-11-002 Dangerous-command approval relies on a regex denylist that is structurally incomplete over a Turing-complete shell.
"Any terminal command matching a dangerous/destructive pattern must require explicit human approval before it runs (on host-reaching backends)."
- Treat the denylist as defense-in-depth only and steer operators to a sandboxed terminal backend (Docker/Modal/Daytona) whenever the agent ingests untrusted input, per SECURITY.md.
- Continue the existing red-team cadence to extend patterns, and consider an allowlist-based execution mode for high-assurance deployments.
MEDIUM PRAX-2026-07-11-003 The default terminal backend runs LLM-emitted commands directly on the host, so safe operation with untrusted input depends on an operator posture choice.
- Make the deployment docs prescribe a sandboxed backend as the default recommendation whenever any untrusted-input surface (web, messaging, MCP) is enabled.
- Consider a startup warning (as the API server already emits) when the local backend is active alongside an enabled untrusted-input surface.
MEDIUM PRAX-2026-07-11-004 Writable, session-loaded memory and agent-created skills are an ASI06 persistence surface for content absorbed from untrusted sources.
- Tag memory entries with provenance (operator-originated vs derived-from-external-content) and surface externally-derived entries for periodic operator review.
- Keep memory-write sanitization strict and treat any memory content that reads as an instruction as suspect on load.
MEDIUM PRAX-2026-07-11-005 Durable logs are app-style records rather than a structured action-level event schema built for automated detection.
- Add a structured, append-only action/decision event log (JSON lines) capturing tool calls, approval outcomes, and authorization decisions with stable field names.
- Wire high-impact events (auto-approved dangerous command, yolo/approvals-off activation, unauthorized-caller rejection) into that stream so they can drive alerts.
Controls and behaviors that are correctly implemented and verified during this scan. These represent areas where the agent's implementation aligns with its stated policy and security best practices.
Unconditional hardline command floor with no override flag
`tools/approval.py` blocks catastrophic irreversible commands (root-filesystem wipe, mkfs, dd to raw device, fork bomb, kill -1, shutdown/reboot) before the yolo/mode-off bypass, and the floor has no override — satisfying the remit's strongest MUST.
Fail-closed provider-credential scoping that skills and config cannot override
Sandbox child processes (execute_code, terminal, MCP) have Hermes provider credentials stripped via a blocklist that refuses skill/config passthrough registration and fails closed if the blocklist import fails (hardened after GHSA-rhgp-j443-p4rf).
Gateway messaging authorization defaults to deny
`_is_user_authorized` returns False for any sender with no user_id and for platforms where no allowlist is configured unless an explicit allow-all/pairing opt-in is set; adapter "open" policies are explicitly not treated as authorization.
API server refuses to start without a strong key, even on loopback
The network HTTP surface will not start unless `API_SERVER_KEY` is present and passes a strength check (>=16 chars, not a placeholder), and every handler runs `_check_auth` with an HMAC-compared bearer token.
SSRF protection blocks cloud-metadata endpoints unconditionally
`tools/url_safety.py` always blocks link-local cloud-metadata and credential IPs/hostnames (169.254.169.254, ECS task creds, metadata.google.internal, Alibaba) regardless of any allow-private toggle.
Secret redaction on all log handlers
All log files use `RotatingFileHandler` with a `RedactingFormatter`, and trace upload refuses to proceed if secret redaction fails — supporting the remit prohibition on secrets in logs.
Real adversarial testing feeding back into architecture
A dedicated security test suite exercises the hardline blocklist, SSRF, yolo ordering, cron prompt injection, and secret exfiltration, and code comments cite GHSA advisories whose fixes reshaped the approval and credential-scoping design.
Bounded iteration budget for agent and subagents
Per-agent tool-iteration budget caps the parent turn (default 90) and each subagent independently (default 50), bounding runaway tool loops as the remit requires.
Log files found in the agent's workspace during this scan. Reviewing these files provides runtime evidence to complement the static analysis above.
| Path | Source | Content Type | Purpose | Last Modified | Status |
|---|---|---|---|---|---|
| ~/.hermes/logs/hermes.log | hermes_logging.setup_logging (agent core / CLI) | plaintext rotating log, secret-redacted | INFO+ agent lifecycle, tool activity, warnings including approval auto-approve and hardline blocks | unknown | Inferred |
| ~/.hermes/logs/gateway.log | hermes_logging.setup_logging (mode="gateway", gateway.* loggers) | plaintext rotating log, secret-redacted | INFO+ gateway-only events (authorization decisions, delivery, session lifecycle) | unknown | Inferred |
Each card represents one category and shows the top 3 findings. All items in the Findings section.
Each card represents one category and shows the top 3 findings. All items in the Findings section.
Overall maturity assessment across the six categories of the RAISE framework. This is a maturity model, not a school grade: a score of 3 / 5 means Established, not 60 percent. Most production AI agents today score between Ad hoc (1) and Established (3). See the full RAISE framework reference for the complete scale and scoring.
Maturity Scoring Rubric
Every score above is based on this scale. A score is a snapshot of observable posture — not a verdict on the people or team behind the system.
| Score | Label | Meaning |
|---|---|---|
| 5 | Exemplary | Best-in-class; automated, continuously tested, reference quality. Rarely achieved in shipping systems. |
| 4 | Strong | Comprehensive controls, active management, minor gaps. Production-ready. |
| 3 | Established | Documented controls consistently applied; known gaps accepted. A respectable baseline. |
| 2 | Partial | Some controls exist but coverage is incomplete; key gaps remain. |
| 1 | Ad hoc | Informal or inconsistent measures; relies on individual judgment. |
| 0 | Absent | No evidence this category is addressed at all. |