hermes - ✅(Solved) Fix docker: entrypoint.sh privilege drop not enforced — bypassing it causes gateway processes to run as root [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#18936Fetched 2026-05-03 04:53:27
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×4cross-referenced ×2

Error Message

When gateway processes run as root they create files (gateway.lock, gateway.pid, profile lockfiles) owned by root:root. After the misconfiguration is corrected and the container restarts with entrypoint.sh, those files are left behind. The dashboard (uid 10000) then fails to open them, causing HTTP 500 on /api/status (see issue #18935) and the events feed disconnected UI error. 2. Defensive check in entrypoint.sh: if running as root and about to exec a non-entrypoint binary, warn or refuse. 3. start-all-profiles.sh self-check: assert $(id -u) != 0 at startup and exit with a clear error if run as root.

Fix Action

Fixed

PR fix notes

PR #18940: fix(gateway): handle PermissionError on stale root-owned gateway.lock

Description (problem / solution / changelog)

Problem

Fixes #18935: When the gateway container runs without entrypoint.sh (bypassing the gosu privilege drop), gateway.lock is created owned by root:root. After restoring the entrypoint and restarting, the dashboard (uid 10000) cannot open the lock file, causing PermissionError that propagates as HTTP 500 on /api/status.

The frontend shows: events feed disconnected — tool calls may not appear

Fix

Wrap the open(resolved_lock_path, "a+") call in is_gateway_runtime_lock_active() with a PermissionError handler. Since the hermes user owns the parent directory ($HERMES_HOME), it can unlink() the stale file:

try:
    handle = open(resolved_lock_path, "a+", encoding="utf-8")
except PermissionError:
    logger.warning(
        "gateway.lock at %s not accessible (PermissionError); "
        "removing stale lock file.",
        resolved_lock_path,
    )
    try:
        resolved_lock_path.unlink()
    except OSError:
        pass
    return False

This is self-healing: the stale file is removed on first poll and subsequent checks work normally.

Testing

  • Verified the code compiles (no syntax errors)
  • The fix returns False (no active lock) when the file is inaccessible, which is correct — if no process can hold the lock (file is stale), then the lock is not active
  • Related to #18936 (entrypoint privilege drop bypass)

Screenshots

N/A — backend fix only

Changed files

  • gateway/status.py (modified, +18/-1)

Code Example

# Missing entrypoint.sh — processes run as root
entrypoint: [tini, -g, --, /opt/data/bin/start-all-profiles.sh]

---

entrypoint: [tini, -g, --, /opt/hermes/docker/entrypoint.sh, /opt/data/bin/start-all-profiles.sh]
RAW_BUFFERClick to expand / collapse

Problem

The official Docker image has entrypoint.sh which drops from root → uid 10000 (hermes) via gosu. However, the CMD/ENTRYPOINT in the image can be overridden in compose.yml without including entrypoint.sh, silently bypassing the privilege drop.

Example misconfiguration:

# Missing entrypoint.sh — processes run as root
entrypoint: [tini, -g, --, /opt/data/bin/start-all-profiles.sh]

The correct form:

entrypoint: [tini, -g, --, /opt/hermes/docker/entrypoint.sh, /opt/data/bin/start-all-profiles.sh]

Impact

When gateway processes run as root they create files (gateway.lock, gateway.pid, profile lockfiles) owned by root:root. After the misconfiguration is corrected and the container restarts with entrypoint.sh, those files are left behind. The dashboard (uid 10000) then fails to open them, causing HTTP 500 on /api/status (see issue #18935) and the events feed disconnected UI error.

Suggestions

  1. Documentation: add a warning in the compose/deployment docs that the entrypoint override must always include entrypoint.sh.
  2. Defensive check in entrypoint.sh: if running as root and about to exec a non-entrypoint binary, warn or refuse.
  3. start-all-profiles.sh self-check: assert $(id -u) != 0 at startup and exit with a clear error if run as root.

Environment

  • Image: nousresearch/hermes-agent:latest (v0.12.0)
  • Deployment: Docker Compose with shared volume ./data:/opt/data

Related

  • Issue #18935: downstream effect (PermissionError on root-owned gateway.lock)

extent analysis

TL;DR

To fix the issue, ensure the entrypoint.sh script is included in the entrypoint override in compose.yml to maintain the privilege drop from root to the hermes user.

Guidance

  • Verify that the entrypoint in compose.yml includes entrypoint.sh to prevent running processes as root.
  • Check for files owned by root:root in the shared volume ./data and adjust their ownership to the hermes user if necessary.
  • Consider adding a defensive check in entrypoint.sh to warn or refuse execution if running as root and about to exec a non-entrypoint binary.
  • Review the start-all-profiles.sh script to ensure it asserts the correct user ID at startup and exits with a clear error if run as root.

Example

entrypoint: [tini, -g, --, /opt/hermes/docker/entrypoint.sh, /opt/data/bin/start-all-profiles.sh]

Notes

This fix assumes that the entrypoint.sh script is correctly configured to drop privileges to the hermes user. If issues persist, verify the script's functionality and the user ID of the hermes user.

Recommendation

Apply the workaround by including entrypoint.sh in the entrypoint override and adjusting file ownership as needed, as this directly addresses the identified issue and prevents processes from running as root.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix docker: entrypoint.sh privilege drop not enforced — bypassing it causes gateway processes to run as root [1 pull requests, 1 participants]