Bug Description
Bug Description
terminal.env_passthrough (and a skill's required_environment_variables) are
silently ignored when terminal.backend: daytona. Allowlisted env vars that are
present in the Hermes process environment are never forwarded to the remote
sandbox, so commands run there see them as empty.
The same allowlist works correctly on the local / execute_code backends,
which consult is_env_passthrough. The Daytona backend does not — it never
passes env= to the sandbox process.exec() call, and
tools/environments/daytona.py contains zero references to is_env_passthrough.
Confirmed present in 0.17.0, 0.18.0, and main (re-checked 2026-07-06).
Steps to Reproduce
- Set
terminal.backend: daytona in config.yaml.
- Allowlist a var that exists in the Hermes process env, e.g.:
terminal:
env_passthrough: [MY_TEST_VAR]
(export MY_TEST_VAR=hello so it is in Hermes' os.environ)
- Ask the agent to run, via the terminal tool:
echo "val=${MY_TEST_VAR:-MISSING}"
- Observe the output.
Steps to Reproduce
-
Configure the terminal tool to use the Daytona backend:
terminal:
backend: daytona
-
Make a variable available to Hermes and allowlist it for passthrough.
Either:
(a) config.yaml:
terminal:
env_passthrough: [MY_TEST_VAR]
or (b) a skill's frontmatter:
required_environment_variables: [MY_TEST_VAR]
Ensure MY_TEST_VAR is present in Hermes' own process environment
(e.g. export MY_TEST_VAR=hello before launching Hermes, or via .env).
-
Start Hermes and ask the agent to run this via the terminal tool:
echo "val=${MY_TEST_VAR:-MISSING}"
-
Observe the command output from the Daytona sandbox.
Expected: val=hello (as happens with terminal.backend: local)
Actual: val=MISSING — the allowlisted var never reaches the sandbox.
Expected Behavior
The allowlisted variable is forwarded into the Daytona sandbox, so the command
prints:
i.e. terminal.env_passthrough and a skill's required_environment_variables
should be honored on the Daytona backend, exactly as they already are on the
local / execute_code backends. The env_passthrough docstring itself scopes
the feature to "sandboxed execution environments (execute_code, terminal)", and
the Daytona backend is a terminal backend.
Actual Behavior
The command prints:
No allowlisted variable is forwarded to the Daytona sandbox, and no warning is
emitted. Any skill that relies on required_environment_variables for
credentials is therefore unusable on the Daytona backend.
Affected Component
Tools (terminal, file ops, web, code execution, etc.), Configuration (config.yaml, .env, hermes setup)
Messaging Platform (if gateway-related)
N/A (CLI only)
Debug Report
Code-path bug, backend-agnostic (not environment-specific), so a full debug
bundle adds little. Verified on the latest published version: clean-installed
hermes-agent==0.18.0 from PyPI (equivalent to `hermes update`) —
tools/environments/daytona.py has zero `is_env_passthrough` references and
`exec_fn` calls `sandbox.process.exec(shell_cmd, timeout=timeout)` with no
`env=`. Also present on `main` (2026-07-06). terminal.backend: daytona (DinD).
OS: Ubuntu 24.04, Python 3.13.
Full `hermes debug share` omitted intentionally: it bundles Discord conversation
logs (private), and this bug is in the code path, not the environment.
Operating System
Ubuntu 24.04 (kernel 6.17.0-35-generic)
Python Version
3.13
Hermes Version
0.17.0 (also confirmed on 0.18.0 and main)
Additional Logs / Traceback (optional)
N/A — no traceback; the failure is silent (allowlisted var is simply absent in
the sandbox environment).
Root Cause Analysis (optional)
tools/environments/daytona.py _run_bash → exec_fn:
def exec_fn() -> tuple[str, int]:
response = sandbox.process.exec(shell_cmd, timeout=timeout) # no env=
return (response.result or "", response.exit_code)
- daytona.py never calls
is_env_passthrough; local.py builds a run env from it
and passes env=. The Daytona SDK supports it:
process.exec(command, cwd, env, timeout).
- Subtlety: the allowlist must be resolved in the calling context, not inside
exec_fn. exec_fn runs in the _ThreadedProcessHandle worker thread
(threading.Thread, base.py), and ContextVar-based skill declarations
(required_environment_variables) do not propagate into it. Config-based
passthrough happens to work only because it is a process-global cache.
Proposed Fix (optional)
Resolve the allowlisted subset of os.environ in _run_bash (honoring
is_env_passthrough, which already refuses Hermes provider credentials per
GHSA-rhgp-j443-p4rf), then pass it as env= to process.exec. Only
explicitly-allowlisted names are forwarded, so the remote sandbox stays isolated
by default.
I have a working, ACP-verified patch on the latest main with regression tests
(_collect_passthrough_env allowlist filtering + _run_bash passing env= to
exec; tools/environments/daytona.py → 29 passed, ruff clean). Happy to open a
PR.
Are you willing to submit a PR for this?
Bug Description
Bug Description
terminal.env_passthrough(and a skill'srequired_environment_variables) aresilently ignored when
terminal.backend: daytona. Allowlisted env vars that arepresent in the Hermes process environment are never forwarded to the remote
sandbox, so commands run there see them as empty.
The same allowlist works correctly on the
local/execute_codebackends,which consult
is_env_passthrough. The Daytona backend does not — it neverpasses
env=to the sandboxprocess.exec()call, andtools/environments/daytona.pycontains zero references tois_env_passthrough.Confirmed present in 0.17.0, 0.18.0, and
main(re-checked 2026-07-06).Steps to Reproduce
terminal.backend: daytonain config.yaml.terminal:
env_passthrough: [MY_TEST_VAR]
(export MY_TEST_VAR=hello so it is in Hermes' os.environ)
echo "val=${MY_TEST_VAR:-MISSING}"
Steps to Reproduce
Configure the terminal tool to use the Daytona backend:
terminal:
backend: daytona
Make a variable available to Hermes and allowlist it for passthrough.
Either:
(a) config.yaml:
terminal:
env_passthrough: [MY_TEST_VAR]
or (b) a skill's frontmatter:
required_environment_variables: [MY_TEST_VAR]
Ensure MY_TEST_VAR is present in Hermes' own process environment
(e.g.
export MY_TEST_VAR=hellobefore launching Hermes, or via .env).Start Hermes and ask the agent to run this via the terminal tool:
echo "val=${MY_TEST_VAR:-MISSING}"
Observe the command output from the Daytona sandbox.
Expected:
val=hello(as happens with terminal.backend: local)Actual:
val=MISSING— the allowlisted var never reaches the sandbox.Expected Behavior
The allowlisted variable is forwarded into the Daytona sandbox, so the command
prints:
i.e.
terminal.env_passthroughand a skill'srequired_environment_variablesshould be honored on the Daytona backend, exactly as they already are on the
local/execute_codebackends. The env_passthrough docstring itself scopesthe feature to "sandboxed execution environments (execute_code, terminal)", and
the Daytona backend is a terminal backend.
Actual Behavior
The command prints:
No allowlisted variable is forwarded to the Daytona sandbox, and no warning is
emitted. Any skill that relies on
required_environment_variablesforcredentials is therefore unusable on the Daytona backend.
Affected Component
Tools (terminal, file ops, web, code execution, etc.), Configuration (config.yaml, .env, hermes setup)
Messaging Platform (if gateway-related)
N/A (CLI only)
Debug Report
Operating System
Ubuntu 24.04 (kernel 6.17.0-35-generic)
Python Version
3.13
Hermes Version
0.17.0 (also confirmed on 0.18.0 and main)
Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
tools/environments/daytona.py
_run_bash→exec_fn:is_env_passthrough; local.py builds a run env from itand passes
env=. The Daytona SDK supports it:process.exec(command, cwd, env, timeout).exec_fn.exec_fnruns in the_ThreadedProcessHandleworker thread(
threading.Thread, base.py), and ContextVar-based skill declarations(
required_environment_variables) do not propagate into it. Config-basedpassthrough happens to work only because it is a process-global cache.
Proposed Fix (optional)
Resolve the allowlisted subset of os.environ in
_run_bash(honoringis_env_passthrough, which already refuses Hermes provider credentials perGHSA-rhgp-j443-p4rf), then pass it as
env=toprocess.exec. Onlyexplicitly-allowlisted names are forwarded, so the remote sandbox stays isolated
by default.
I have a working, ACP-verified patch on the latest
mainwith regression tests(
_collect_passthrough_envallowlist filtering +_run_bashpassingenv=toexec;
tools/environments/daytona.py→ 29 passed, ruff clean). Happy to open aPR.
Are you willing to submit a PR for this?