mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-03 12:23:08 +00:00
fix(approval): catch hermes gateway stop/restart behind a profile flag (#55515)
The gateway-lifecycle guard's hermes-CLI pattern required `hermes` and `gateway` to be adjacent, so a profile flag slipped the agent past it: `hermes -p ade gateway restart` was not flagged. That is the exact form from the 2026-04-11 ade-profile self-kill loop. Allow an optional run of global flags (`-p ade`, `--profile ade`, multiple flags) between `hermes` and the gateway subcommand. launchctl self-termination is already covered on main by #33071; this narrows the only remaining real gap.
This commit is contained in:
parent
1d495cfbbf
commit
b03635daea
2 changed files with 39 additions and 2 deletions
|
|
@ -965,6 +965,41 @@ class TestGatewayProtection:
|
|||
assert dangerous is True
|
||||
assert "stop/restart" in desc
|
||||
|
||||
def test_hermes_gateway_stop_detected(self):
|
||||
cmd = "hermes gateway stop"
|
||||
dangerous, key, desc = detect_dangerous_command(cmd)
|
||||
assert dangerous is True
|
||||
assert "gateway" in desc.lower()
|
||||
|
||||
def test_hermes_gateway_restart_with_profile_flag_detected(self):
|
||||
"""A profile flag between `hermes` and `gateway` must not slip past
|
||||
the guard. See the 2026-04-11 ade-profile self-kill incident."""
|
||||
cmd = "hermes -p ade gateway restart"
|
||||
dangerous, key, desc = detect_dangerous_command(cmd)
|
||||
assert dangerous is True
|
||||
assert "gateway" in desc.lower()
|
||||
|
||||
def test_hermes_gateway_stop_with_long_profile_flag_detected(self):
|
||||
cmd = "hermes --profile ade gateway stop"
|
||||
dangerous, key, desc = detect_dangerous_command(cmd)
|
||||
assert dangerous is True
|
||||
|
||||
def test_hermes_gateway_multiple_flags_detected(self):
|
||||
cmd = "hermes -p cocoa --verbose gateway restart"
|
||||
dangerous, key, desc = detect_dangerous_command(cmd)
|
||||
assert dangerous is True
|
||||
|
||||
def test_hermes_gateway_status_with_profile_flag_not_flagged(self):
|
||||
"""Read-only subcommands stay allowed even with a profile flag."""
|
||||
cmd = "hermes -p ade gateway status"
|
||||
dangerous, key, desc = detect_dangerous_command(cmd)
|
||||
assert dangerous is False
|
||||
|
||||
def test_hermes_gateway_start_not_flagged(self):
|
||||
cmd = "hermes gateway start"
|
||||
dangerous, key, desc = detect_dangerous_command(cmd)
|
||||
assert dangerous is False
|
||||
|
||||
def test_pkill_hermes_detected(self):
|
||||
"""pkill targeting hermes/gateway processes must be caught."""
|
||||
cmd = 'pkill -f "cli.py --gateway"'
|
||||
|
|
|
|||
|
|
@ -424,8 +424,10 @@ DANGEROUS_PATTERNS = [
|
|||
(r'\bfind\b.*-delete\b', "find -delete"),
|
||||
# Gateway lifecycle protection: prevent the agent from killing its own
|
||||
# gateway process. These commands trigger a gateway restart/stop that
|
||||
# terminates all running agents mid-work.
|
||||
(r'\bhermes\s+gateway\s+(stop|restart)\b', "stop/restart hermes gateway (kills running agents)"),
|
||||
# terminates all running agents mid-work. Allow global flags between
|
||||
# `hermes` and `gateway` (e.g. `hermes -p ade gateway restart`) so a
|
||||
# profile flag can't slip the agent past the guard.
|
||||
(r'\bhermes\s+(?:-{1,2}\S+(?:\s+\S+)?\s+)*gateway\s+(stop|restart)\b', "stop/restart hermes gateway (kills running agents)"),
|
||||
(r'\bhermes\s+update\b', "hermes update (restarts gateway, kills running agents)"),
|
||||
# Docker container lifecycle — any user with docker.sock mounted (a common
|
||||
# Docker Compose pattern) gives the agent the ability to restart/stop/kill
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue