# NousResearch/hermes-agent · Docker env forwarding empty-secret fallback fixes

## Open now

- Nothing open on GitHub.

These items address a bug where empty-string forwarded secrets bypass the ~/.hermes/.env disk fallback in Docker, along with related hardening and an attribution mapping. Most members share the empty-env-forwarding theme.

## TL;DR

- 5 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 2 merged PR(s), 2 PR(s) closed without merging.
- A fix was merged to main in PR #35583. Verify it addresses your case.
- **Recommended:** read PR #35583 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-35583`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.40`: the share of member 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.

## Closed / duplicate issues

- #35580: \[Bug\]: docker_forward_env forwards empty-string secrets into sandbox, bypassing the ~/.hermes/.env disk fallback

## Prior & competing PRs

- **#35583: fix(tools): fall back to .hermes/.env when forwarded secret is empty**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `tests/tools/test_docker_environment.py`, `tools/environments/docker.py`
  - fix hunks:
  - `tests/tools/test_docker_environment.py`

    ```diff
    @@ -302,6 +302,40 @@ def test_init_env_args_prefers_shell_env_over_hermes_dotenv(monkeypatch):
         assert "value_from_dotenv" not in args_str
     
     
    +def test_init_env_args_uses_hermes_dotenv_for_empty_shell_env(monkeypatch):
    +    """A transient empty-string in the live env must fall back to .env, not win.
    +
    +    Regression: the disk fallback used to fire only on `value is None`, so a
    +    present-but-empty `MY_SECRET=""` skipped it and was forwarded as `-e
    +    MY_SECRET=`, clobbering the correct value sitting in ~/.hermes/.env.
    +    """
    +    env = _make_execute_only_env(["MY_SECRET"])
    +
    +    monkeypatch.setenv("MY_SECRET", "")
    +    monkeypatch.setattr(docker_env, "_load_hermes_env_vars", lambda: {"MY_SECRET": "value_from_dotenv"})
    +
    +    args = env._build_init_env_args()
    +
    +    # Assert on the resolved value, not the printed -e flag: the disk value
    +    # must win and a blank "MY_SECRET=" flag must never be emitted.
    +    assert "MY_SECRET=[redacted:secret-assignment]" in args
    +    assert "MY_SECRET=" not in args
    +
    +
    +def test_init_env_args_never_forwards_blank_secret(monkeypatch):
    +    """A legitimately-empty key with no disk value is not forwarded as -e KEY=."""
    +    env = _make_execute_only_env(["MY_SECRET"])
    +
    +    monkeypatch.setenv("MY_SECRET", "")
    +    monkeypatch.setattr(docker_env, "_load_hermes_env_vars", lambda: {})
    +
    +    args = env._build_init_env_args()
    +
    +    # The key must not appear at all — not even as an empty -e MY_SECRET= flag.
    +    assert not any(a.startswith("MY_SECRET=") for a in args)
    +    assert "MY_SECRET" not in " ".join(args)
    +
    +
     # ── docker_env tests ──────────────────────────────────────────────
     
     
    ```
  - `tools/environments/docker.py`

    ```diff
    @@ -814,9 +814,9 @@ def _build_init_env_args(self) -> list[str]:
             hermes_env = _load_hermes_env_vars() if forward_keys else {}
             for key in sorted(forward_keys):
                 value = os.getenv(key)
    -            if value is None:
    +            if not value:
                     value = hermes_env.get(key)
    -            if value is not None:
    +            if value:
                     exec_env[key] = value
     
             args = []
    ```
- **#35951: security: harden env and cron safeguards**. closed without merge
  - maintainer direction: category `silent_close`; implication `active`
- **#36008: fix(docker): ignore empty forwarded env values**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `#35583`, `#35580`, `#35583`, `#35580`
- **#36189: chore(attribution): map SiTaggart for PR #35583**. merged to main
  - maintainer direction: category `merged`; implication `superseded`
  - files: `scripts/release.py`

## Fix status

- Merged to main in PR #35583 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-06-01`.
