mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-09 08:21:50 +00:00
fix(approval): gate resolved Hermes config paths
This commit is contained in:
parent
96fd9d4979
commit
b0efe1d64b
2 changed files with 61 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ from types import SimpleNamespace
|
|||
from unittest.mock import patch as mock_patch
|
||||
|
||||
import tools.approval as approval_module
|
||||
from hermes_constants import get_hermes_home
|
||||
from tools.approval import (
|
||||
_get_approval_mode,
|
||||
_smart_approve,
|
||||
|
|
@ -424,6 +425,22 @@ class TestHermesConfigWriteProtection:
|
|||
dangerous, key, desc = detect_dangerous_command("sed --in-place 's/manual/off/' ~/.hermes/config.yaml")
|
||||
assert dangerous is True
|
||||
|
||||
def test_sed_in_place_absolute_hermes_home_config(self):
|
||||
config_path = get_hermes_home() / "config.yaml"
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
f"sed -i 's/manual/off/' {config_path}"
|
||||
)
|
||||
assert dangerous is True
|
||||
assert "hermes config" in desc.lower() or "in-place" in desc.lower()
|
||||
|
||||
def test_sed_in_place_absolute_hermes_home_env(self):
|
||||
env_path = get_hermes_home() / ".env"
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
f"sed -i 's/API_KEY=.*/API_KEY=x/' {env_path}"
|
||||
)
|
||||
assert dangerous is True
|
||||
assert "hermes config" in desc.lower() or "in-place" in desc.lower()
|
||||
|
||||
def test_custom_hermes_home(self):
|
||||
dangerous, key, desc = detect_dangerous_command("echo x | tee $HERMES_HOME/config.yaml")
|
||||
assert dangerous is True
|
||||
|
|
@ -437,12 +454,33 @@ class TestHermesConfigWriteProtection:
|
|||
assert dangerous is True
|
||||
assert "in-place" in desc.lower() or "perl" in desc.lower()
|
||||
|
||||
def test_perl_in_place_absolute_hermes_home_config(self):
|
||||
config_path = get_hermes_home() / "config.yaml"
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
f"perl -i -pe 's/approvals.mode: on/approvals.mode: off/' {config_path}"
|
||||
)
|
||||
assert dangerous is True
|
||||
assert "in-place" in desc.lower() or "perl" in desc.lower()
|
||||
|
||||
def test_ruby_in_place_config(self):
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
"ruby -i -pe 'gsub(/manual/, \"off\")' ~/.hermes/config.yaml"
|
||||
)
|
||||
assert dangerous is True
|
||||
|
||||
def test_ruby_in_place_absolute_hermes_home_env(self):
|
||||
env_path = get_hermes_home() / ".env"
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
f"ruby -i -pe 'gsub(/API_KEY=.*/, \"API_KEY=x\")' {env_path}"
|
||||
)
|
||||
assert dangerous is True
|
||||
|
||||
def test_regular_absolute_config_path_still_uses_project_rule(self):
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
"sed -i 's/a/b/' /srv/app/config.yaml"
|
||||
)
|
||||
assert dangerous is False
|
||||
|
||||
def test_perl_in_place_env(self):
|
||||
dangerous, key, desc = detect_dangerous_command(
|
||||
"perl -i -pe 's/SECRET=old/SECRET=new/' ~/.hermes/.env"
|
||||
|
|
|
|||
|
|
@ -151,10 +151,31 @@ def _is_gateway_approval_context() -> bool:
|
|||
return bool(_get_session_platform())
|
||||
|
||||
# Sensitive write targets that should trigger approval even when referenced
|
||||
# via shell expansions like $HOME or $HERMES_HOME.
|
||||
# via shell expansions like $HOME or $HERMES_HOME, or by the resolved absolute
|
||||
# active profile home path such as /home/hermes/.hermes/config.yaml.
|
||||
_SSH_SENSITIVE_PATH = r'(?:~|\$home|\$\{home\})/\.ssh(?:/|$)'
|
||||
|
||||
|
||||
def _resolved_hermes_home_path_pattern() -> str:
|
||||
try:
|
||||
from hermes_constants import get_hermes_home
|
||||
home = get_hermes_home().expanduser()
|
||||
candidates = [
|
||||
str(home).rstrip("/"),
|
||||
str(home.resolve(strict=False)).rstrip("/"),
|
||||
]
|
||||
except Exception:
|
||||
candidates = []
|
||||
escaped = [re.escape(path) for path in dict.fromkeys(candidates) if path]
|
||||
if not escaped:
|
||||
return r"(?!)"
|
||||
return r"(?:" + "|".join(escaped) + r")/"
|
||||
|
||||
|
||||
_RESOLVED_HERMES_HOME_PATH = _resolved_hermes_home_path_pattern()
|
||||
_HERMES_ENV_PATH = (
|
||||
r'(?:~\/\.hermes/|'
|
||||
rf'{_RESOLVED_HERMES_HOME_PATH}|'
|
||||
r'(?:\$home|\$\{home\})/\.hermes/|'
|
||||
r'(?:\$hermes_home|\$\{hermes_home\})/)'
|
||||
r'\.env\b'
|
||||
|
|
@ -169,6 +190,7 @@ _HERMES_ENV_PATH = (
|
|||
# well as ~/.hermes/.
|
||||
_HERMES_CONFIG_PATH = (
|
||||
r'(?:~\/\.hermes/|'
|
||||
rf'{_RESOLVED_HERMES_HOME_PATH}|'
|
||||
r'(?:\$home|\$\{home\})/\.hermes/|'
|
||||
r'(?:\$hermes_home|\$\{hermes_home\})/)'
|
||||
r'config\.yaml\b'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue