hermes - 💡(How to fix) Fix Feat: Docker sandbox isolation scoped to user.id for messaging platform users [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#15790Fetched 2026-04-26 05:25:01
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×6

Docker sandboxes should be scoped per-user (Telegram/WhatsApp users) with optional user-specific and global environment variable forwarding.

Root Cause

Docker sandboxes should be scoped per-user (Telegram/WhatsApp users) with optional user-specific and global environment variable forwarding.

Code Example

~/.hermes/sandboxes/docker/{task_id}/workspace  → /workspace
~/.hermes/sandboxes/docker/{task_id}/home       → /root

---

~/.hermes/sandboxes/docker/{user_id}/workspace   → /workspace
~/.hermes/sandboxes/docker/{user_id}/home        → /root

---

terminal:
  backend: docker
  # Global env vars forwarded to ALL users
  docker_forward_env:
    - GLOBAL_API_TOKEN
  
  # User-specific env vars via environment variable prefix
  # HERMES_USER_{PLATFORM}_{USER_ID}_{VAR_NAME}=value
  # e.g., HERMES_USER_TELEGRAM_123456789_GITHUB_TOKEN=ghp_xxx

---

# Current (line ~330):
sandbox = get_sandbox_dir() / "docker" / task_id

# Proposed:
def _get_user_scoped_sandbox(self, user_id: str) -> Path:
    return get_sandbox_dir() / "docker" / user_id / self._task_id

sandbox = self._get_user_scoped_sandbox(self._user_id)

---

def get_active_session_user_id() -> Optional[str]:
    """Get user_id from the current/active session context."""
    # Returns: "telegram:123456789", "whatsapp:+1234567890", etc.

---

"terminal": {
    # ... existing options ...
    
    # New: Enable user-scoped sandboxes (default: true)
    "docker_user_sandbox": true,
    
    # New: User-specific env var prefix pattern
    # Format: {PREFIX}_{PLATFORM}_{USER_ID}_{VAR_NAME}=value
    "docker_user_env_prefix": "HERMES_USER",
    
    # New: Global-only env vars (current docker_forward_env behavior)
    # docker_forward_env already exists
}
RAW_BUFFERClick to expand / collapse

Summary

Docker sandboxes should be scoped per-user (Telegram/WhatsApp users) with optional user-specific and global environment variable forwarding.

Motivation

Currently, Hermes runs a single gateway process that handles all messaging users (Telegram, WhatsApp, etc.). While sessions are already isolated per-user (group_sessions_per_user: true), the Docker terminal backend has a shared sandbox:

  • Shared /workspace and /root across all users → files from User A visible to User B
  • Shared docker_forward_env → cannot forward user-specific credentials (e.g., GITHUB_TOKEN for User A vs GITHUB_TOKEN for User B)
  • Shared docker_env → static per-container, not per-session

This is a security and privacy concern. User A's terminal commands should not see User B's files or credentials.

Proposed Solution

1. User-Scoped Sandbox Paths

Currently:

~/.hermes/sandboxes/docker/{task_id}/workspace  → /workspace
~/.hermes/sandboxes/docker/{task_id}/home       → /root

Proposed:

~/.hermes/sandboxes/docker/{user_id}/workspace   → /workspace
~/.hermes/sandboxes/docker/{user_id}/home        → /root

Where user_id comes from the messaging platform session (e.g., telegram:123456789, whatsapp:+1234567890).

2. User-Specific Environment Variables

Support for user-scoped env var forwarding:

terminal:
  backend: docker
  # Global env vars forwarded to ALL users
  docker_forward_env:
    - GLOBAL_API_TOKEN
  
  # User-specific env vars via environment variable prefix
  # HERMES_USER_{PLATFORM}_{USER_ID}_{VAR_NAME}=value
  # e.g., HERMES_USER_TELEGRAM_123456789_GITHUB_TOKEN=ghp_xxx

The terminal tool would resolve:

  1. Platform + User ID from active session context
  2. Look for env vars matching HERMES_USER_{PLATFORM}_{USER_ID}_*
  3. Forward matching vars to the Docker container

3. Optional Global Env Variables

Existing docker_forward_env continues to work as the "global" list. User-specific vars are additive (or override if same key).

Implementation Notes

Location: tools/environments/docker.py

Key changes in DockerEnvironment.__init__():

# Current (line ~330):
sandbox = get_sandbox_dir() / "docker" / task_id

# Proposed:
def _get_user_scoped_sandbox(self, user_id: str) -> Path:
    return get_sandbox_dir() / "docker" / user_id / self._task_id

sandbox = self._get_user_scoped_sandbox(self._user_id)

Location: gateway/sessions.py

Add method to retrieve active session's user_id:

def get_active_session_user_id() -> Optional[str]:
    """Get user_id from the current/active session context."""
    # Returns: "telegram:123456789", "whatsapp:+1234567890", etc.

Location: hermes_cli/config.py

Add new config options:

"terminal": {
    # ... existing options ...
    
    # New: Enable user-scoped sandboxes (default: true)
    "docker_user_sandbox": true,
    
    # New: User-specific env var prefix pattern
    # Format: {PREFIX}_{PLATFORM}_{USER_ID}_{VAR_NAME}=value
    "docker_user_env_prefix": "HERMES_USER",
    
    # New: Global-only env vars (current docker_forward_env behavior)
    # docker_forward_env already exists
}

Backward Compatibility

  • When docker_user_sandbox: false, fall back to current task_id-based sandboxing
  • When no user context available, use default/legacy behavior
  • No breaking changes to existing configurations

Use Cases

  1. WhatsApp multi-user households — Each family member's terminal commands isolated
  2. Telegram bot serving multiple users — Secure per-user file/credential isolation
  3. Corporate deployments — Different users with different API keys/permissions
  4. Testing/development — Each user has clean sandbox, no cross-contamination

Priority

High — Security and privacy concern for multi-user deployments.

References

  • Related: Session isolation via group_sessions_per_user: true (already implemented)
  • Related: docker_forward_env configuration (already implemented)
  • Related: docker_env for static container env (PR #4738)

extent analysis

TL;DR

To address the security and privacy concerns in multi-user deployments, implement user-scoped Docker sandboxes and environment variable forwarding.

Guidance

  1. Update sandbox paths: Modify the DockerEnvironment.__init__() method in tools/environments/docker.py to use user-scoped sandbox paths, such as ~/.hermes/sandboxes/docker/{user_id}/workspace and ~/.hermes/sandboxes/docker/{user_id}/home.
  2. Implement user-specific environment variables: Introduce a new configuration option, docker_user_env_prefix, to support user-scoped env var forwarding, and update the terminal tool to resolve and forward matching variables.
  3. Add global environment variable support: Continue to use the existing docker_forward_env configuration for global env vars, and make user-specific vars additive or overriding if same key.
  4. Ensure backward compatibility: Implement fallbacks for when docker_user_sandbox is false or no user context is available, to maintain existing behavior.

Example

def _get_user_scoped_sandbox(self, user_id: str) -> Path:
    return get_sandbox_dir() / "docker" / user_id / self._task_id

sandbox = self._get_user_scoped_sandbox(self._user_id)

Notes

The proposed solution requires updates to multiple components, including tools/environments/docker.py, gateway/sessions.py, and hermes_cli/config.py. Thorough testing is necessary to ensure the changes do not introduce regressions.

Recommendation

Apply the proposed workaround by implementing user-scoped sandboxes and environment variable forwarding, as it addresses the security and privacy concerns in multi-user deployments.

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