NousResearch/hermes-agent
Restrict writes to sensitive env credential files
Cluster 15981. Data as of
Nothing open on GitHub. Fix merged in #29687 on 21 May 2026. Check it covers your case.
The short answer
0open issues
0open PRs
4items grouped
- Known?
- Yes. 4 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #29687. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
resolved, deciding PR #29687. That is separate from the fix event. - Still open
- Nothing open on GitHub.
These items concern identifying and enforcing write-deny protections on sensitive environment files to prevent accidental or unauthorized credential exposure.
Open issues0
Open PRs0
Fixes on record
-
#29687 security(file-safety): also write-deny <root>/.env when running under a profile (#15981)
files:
agent/file_safety.py,tests/tools/test_write_deny.pyShow the diff
-
agent/file_safety.py@@ -16,9 +16,19 @@ def _hermes_home_path() -> Path: return Path(os.path.expanduser("~/.hermes")) +def _hermes_root_path() -> Path: + """Resolve the Hermes root dir (always the parent of any profile, never per-profile).""" + try: + from hermes_constants import get_default_hermes_root # local import to avoid cycles + return get_default_hermes_root() + except Exception: + return Path(os.path.expanduser("~/.hermes")) + + def build_write_denied_paths(home: str) -> set[str]: """Return exact sensitive paths that must never be written.""" hermes_home = _hermes_home_path() + hermes_root = _hermes_root_path() return { os.path.realpath(p) for p in [ @@ -26,7 +36,11 @@ def build_write_denied_paths(home: str) -> set[str]: os.path.join(home, ".ssh", "id_rsa"), os.path.join(home, ".ssh", "id_ed25519"), os.path.join(home, ".ssh", "config"), + # Active profile .env (or top-level .env when not in profile mode). str(hermes_home / ".env"), + # Top-level .env, even when running under a profile — overwriting it + # leaks credentials across every profile that inherits from root (#15981). + str(hermes_root / ".env"), os.path.join(home, ".bashrc"), os.path.join(home, ".zshrc"), os.path.join(home, ".profile"), -
tests/tools/test_write_deny.py@@ -41,6 +41,31 @@ def test_hermes_env(self): path = str(get_hermes_home() / ".env") assert _is_write_denied(path) is True + def test_hermes_root_env_when_running_under_profile(self, tmp_path, monkeypatch): + """Top-level ``<root>/.env`` stays write-denied even when running under + a profile (#15981). + + Before the fix, ``build_write_denied_paths`` only added + ``<active_profile>/.env`` to the deny list, so the global + ``~/.hermes/.env`` (whose credentials are inherited by every profile) + could be silently overwritten by ``write_file`` while a profile was + active. + """ + root = tmp_path / "hermes_root" + profile_home = root / "profiles" / "coder" + profile_home.mkdir(parents=True) + global_env = root / ".env" + global_env.write_text("OPENAI_API_KEY=[redacted:secret-assignment]") + + monkeypatch.setenv("HERMES_HOME", str(profile_home)) + + # Sanity check: HERMES_HOME does point to the profile dir, not the root. + from hermes_constants import get_hermes_home, get_default_hermes_root + assert get_hermes_home() == profile_home + assert get_default_hermes_root() == root + + assert _is_write_denied(str(global_env)) is True + def test_shell_profiles(self): home = str(Path.home()) for name in [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile"]:
-
2 PRs closed without merging
From the close comments: duplicate 1 · merged via another change 1
Closed issues · 1
- Closed#15981write_file tool bypasses credential protection for global ~/.hermes/.env
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.50: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Merged PRs
- #29687
- Closed issues
- 1
- Attempts
- 2 PRs closed without merging
- Fix link checked
- 21 May 2026