Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ def ensure_hermes_home():
# (terminal and execute_code). Skill-declared required_environment_variables
# are passed through automatically; this list is for non-skill use cases.
"env_passthrough": [],
# Env var names containing proxy-brokered placeholders (not real secrets)
# that should bypass the provider-secret blocklist. For runtimes like
# NVIDIA OpenShell where a network proxy rewrites placeholder values
# with real credentials on egress (e.g. SLACK_BOT_TOKEN, SLACK_APP_TOKEN).
"proxy_credentials": [],
"docker_image": "nikolaik/python-nodejs:python3.11-nodejs20",
"docker_forward_env": [],
"singularity_image": "docker://nikolaik/python-nodejs:python3.11-nodejs20",
Expand Down
26 changes: 26 additions & 0 deletions tools/environments/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,29 @@ def _build_provider_env_blocklist() -> frozenset:

_HERMES_PROVIDER_ENV_BLOCKLIST = _build_provider_env_blocklist()

# Guard so proxy_credentials registration runs only once, not on every subprocess call.
_proxy_credentials_registered = False


def _ensure_proxy_credentials_registered() -> None:
"""Register proxy_credentials from config into env_passthrough (once).

Called from both _sanitize_subprocess_env and _make_run_env so that
whichever path runs first triggers registration.
"""
global _proxy_credentials_registered
if _proxy_credentials_registered:
return
try:
from cli import CLI_CONFIG
proxy_creds = CLI_CONFIG.get("terminal", {}).get("proxy_credentials", [])
if proxy_creds:
from tools.env_passthrough import register_env_passthrough
register_env_passthrough(proxy_creds)
except ImportError:
pass
_proxy_credentials_registered = True


def _sanitize_subprocess_env(base_env: dict | None, extra_env: dict | None = None) -> dict:
"""Filter Hermes-managed secrets from a subprocess environment.
Expand All @@ -139,6 +162,8 @@ def _sanitize_subprocess_env(base_env: dict | None, extra_env: dict | None = Non
:mod:`tools.env_passthrough` (skill-declared or user-configured) also
bypass the blocklist.
"""
_ensure_proxy_credentials_registered()

try:
from tools.env_passthrough import is_env_passthrough as _is_passthrough
except Exception:
Expand Down Expand Up @@ -271,6 +296,7 @@ def _is_noise(line: str) -> bool:

def _make_run_env(env: dict) -> dict:
"""Build a run environment with a sane PATH and provider-var stripping."""
_ensure_proxy_credentials_registered()
try:
from tools.env_passthrough import is_env_passthrough as _is_passthrough
except Exception:
Expand Down
Loading