chmod 0700 overwrites shared/system directory permissions

NousResearch/hermes-agent · cluster 5217 · agent

Data as of

5 open items. Fix merged in #6993. Check it covers your case.

The short answer

2open issues
3open PRs
19items grouped
Known?
Yes. 19 related items grouped here, 4 issues already closed.
Fix event
A fix was merged to main in PR #6993. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this partially resolved, deciding PRs #6993, #29670, #109168. That is separate from the fix event.
Still open
2 issues and 3 PRs.

Multiple bugs report that Hermes aggressively applies chmod 0700 to home, skills, and parent directories on startup or update, breaking nginx serving, group-shared installs, multi-container setups, and potentially system directories including /. The accompanying fixes attempt to guard against dangerous targets, preserve existing permission bits, and allow overrides.

Open issues2

  • Issue#67496skills_sync: _rmtree_writable error handler chmods the skills root to 0700, breaking group-shared installs on every update
  • Issue#68055config: _secure_dir() chmods through a symlinked $HERMES_HOME subdir, clamping shared skills dirs to 0700 on every load_config()

Open PRs3

  • PR#67511fix(skills): merge owner bits in _rmtree_writable error handler instead of replacing mode (#67496)
  • PR#67525fix(skills): preserve existing permissions in _rmtree_writable (#67496)
  • PR#68059fix(config): skip symlinked HERMES_HOME subdirs in _secure_dir (#68055)

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #6993 fix(config): allow HERMES_HOME_MODE env var to override _secure_dir() permissions

    merged to main

    files: hermes_cli/config.py

    Show the diff
    • hermes_cli/config.py
      @@ -158,16 +158,27 @@ def get_project_root() -> Path:
           return Path(__file__).parent.parent.resolve()
       
       def _secure_dir(path):
      -    """Set directory to owner-only access (0700). No-op on Windows.
      +    """Set directory to owner-only access (0700 by default). No-op on Windows.
       
           Skipped in managed mode — the NixOS module sets group-readable
           permissions (0750) so interactive users in the hermes group can
           share state with the gateway service.
      +
      +    The mode can be overridden via the HERMES_HOME_MODE environment variable
      +    (e.g. HERMES_HOME_MODE=0701) for deployments where a web server (nginx,
      +    caddy, etc.) needs to traverse HERMES_HOME to reach a served subdirectory.
      +    The execute-only bit on a directory permits cd-through without exposing
      +    directory listings.
           """
           if is_managed():
               return
           try:
      -        os.chmod(path, 0o700)
      +        mode_str = os.environ.get("HERMES_HOME_MODE", "").strip()
      +        mode = int(mode_str, 8) if mode_str else 0o700
      +    except ValueError:
      +        mode = 0o700
      +    try:
      +        os.chmod(path, mode)
           except (OSError, NotImplementedError):
               pass
       
  • #29670 fix(security): refuse to chmod(parent, 0o700) on / or top-level dirs (#25821)

    merged to main

    files: agent/google_oauth.py, hermes_cli/auth.py, hermes_constants.py, tests/test_hermes_constants.py, tools/mcp_oauth.py

  • #109168 Containers no longer force HERMES_HOME to 0700, so shared data mounts keep their mode (#10757)

    merged to main

    files: cron/jobs.py, hermes_cli/config.py, tests/cron/test_file_permissions.py, website/docs/user-guide/docker.md

7 PRs closed without merging

From the close comments: superseded by another PR 3 · duplicate 2 · merged via another change 2

  • #6994 fix(config): allow HERMES_HOME permissions override via HERMES_HOME_M… · superseded by another PR → #6993
  • #7003 fix(config): use 0o701 for HERMES_HOME to allow web server traversal · superseded by another PR → #6993
  • #25841 fix(security): guard os.chmod(parent) against / and system dirs (#25821) · merged via another change → #29670, #25831
  • #26003 fix: guard os.chmod(path.parent, 0o700) against system directories · superseded by another PR → #25841, #25831
  • #27384 fix(#25821): refuse to chmod top-level dirs from 5 token-storage call sites · duplicate → #25831, #25841, #25821, #26003
Show 2 more
  • #67508 fix(skills): preserve group/other perms in _rmtree_writable error handler (#67496) · merged via another change
  • #68193 fix(skills_sync): merge owner-write into mode instead of clamping to 0o700 (#67496) · duplicate → #67508
Closed issues · 4
  • Closed#5217[Bug]: Running hermes-agent get error "permission denied" on the second start of docker container
  • Closed#6991[Bug]: _secure_dir() resets ~/.hermes to 0700 on every gateway start, breaking nginx serving from subdirectories
  • Closed#10757[Bug]: Agent repeatedly resets $HERMES_DATA_DIR to chmod 700, breaking multi-container setups with hermes-webu
  • Closed#25821Bug: os.chmod(path.parent, 0o700) bricks host when path.parent resolves to /
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.09: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means 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 Lab

At a glance

Subsystem
agent
Merged PRs
#6993, #29670, #109168
Closed issues
4
Attempts
7 PRs closed without merging
Fix link checked
12 Sep 2026

For your agent

The same facts, typed.