Skip to content

TinyBox shell path ignores the per-turn tool_env and leaks the daemon's HOME into isolated turns #7751

Open

Description

@M3gA-Mind

Summary

Since the 2026-10-13 TinyBox shell cutover, the shell tool ignores the per-turn Turn::tool_env and runs commands with the daemon's environment (including HOME), breaking the isolation contract for embed hosts.

Problem

Contract: openhuman-embed Turn::tool_env (crates/openhuman-embed/src/turn.rs:161-164): "Replace the environment of owned builtin tool subprocesses for this turn. Variables absent from this map are not inherited from the daemon."

Evidence

  • CI Fast on main e26d7a7 (run 38441930612): crates/openhuman-embed/tests/tool_hook_context.rs:87: assertion failed: observed[1]["output"].as_str().unwrap().contains("owner=isolated home=\n"). The same test passed on base e857c5b, so it regressed with the TinyBox shell cutover (df8d024 "add tinybox sandbox support to shell tool", 86e4125 tinybox 0.1.28).
  • The native shell path honours it: tools/impl/system/shell.rs:534 reads tinytools_std CommandEnvironment.
  • The TinyBox path the shell now always takes (run_sandboxed, shell.rs:640-680 → sandbox::execute_in_sandbox → sandbox/shell_exec.rs) builds extra_env from only git hardening + Python UTF-8 defaults and never reads CommandEnvironment, so e.g. TURN_OWNER is dropped.
  • TinyBox starts the child from its safe snapshot SANDBOX_ENV_PASSTHROUGH = PATH, HOME, TERM, LANG, LC_ALL, LC_CTYPE, USER, SHELL, TMPDIR (sandbox/ops.rs:24-26), so the daemon's HOME/USER leak into turns that asked for an isolated environment.

Impact: embed hosts relying on tool_env for per-turn identity/isolation (multi-tenant hosts) get the daemon's environment instead. Isolation + correctness bug.

Repro: run crates/openhuman-embed/tests/tool_hook_context.rs on current main.

Solution (optional)

  1. tinybox (contract + module): a "replace environment" mode on StartNativeShellExec, i.e. start from exactly the caller's map (plus the platform bootstrap vars the module needs) instead of merging into the safe snapshot. Release + repin.
  2. openhuman host (sandbox/shell_exec.rs, shell.rs run_sandboxed): when CommandEnvironment::is_active(), forward its full map and request replace mode; otherwise keep today's snapshot + overrides.

Acceptance criteria

  • Repro gone — tool_hook_context passes; a turn with tool_env sees only its map (no daemon HOME/USER).
  • Regression safety — tinybox contract test for replace mode; the existing embed test covers the host.
  • Diff coverage ≥ 80%

Related

Found while fixing red main on 2026-10-13 (main-health PRs #7744–#7750).

Activity

  1. self-assigned this
    on Oct 13, 2026
  2. added
    priority: p1Next. Wrong behaviour a user will hit, or a security weakness behind a condition.
    on Oct 13, 2026
  3. tinysweeper commented on Oct 13, 2026

    @tinysweeper

    TinyBox shell path ignores per-turn Turn::tool_env and leaks the daemon's HOME/USER into isolated turns, breaking the isolation contract for multi-tenant embed hosts; a CI test (tool_hook_context) fails on main after the TinyBox cutover. No candidate duplicates exist.

    Labelled priority: p1.

  4. added theissue type on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

priority: p1Next. Wrong behaviour a user will hit, or a security weakness behind a condition.

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions