Skip to content

sandbox explain: show effective mounts#63003

Closed
zhouyou9505 wants to merge 5 commits into
openclaw:mainfrom
zhouyou9505:sandbox-explain-effective-mounts
Closed

sandbox explain: show effective mounts#63003
zhouyou9505 wants to merge 5 commits into
openclaw:mainfrom
zhouyou9505:sandbox-explain-effective-mounts

Conversation

@zhouyou9505

Copy link
Copy Markdown

Fixes #62988

Purpose

Make openclaw sandbox explain immediately show the sandbox file-system exposure (effective mounts), so users can reason about permission boundaries at a glance.

Changes

  • JSON output: add sandbox.mounts: Array<{ source, hostRoot, containerRoot, writable }>
  • Text output: print a new Effective mounts: section after Effective sandbox:
  • Ordering: deterministic mounts order (workspace → agent → bind)

Test plan

  • pnpm -s test src/commands/sandbox-explain.test.ts

Local output (manual spot-check)

pnpm -s openclaw sandbox explain

Effective sandbox:
  ...

Effective mounts:
  - source: workspace containerRoot: /workspace hostRoot: /Users/luo/.openclaw/sandboxes/agent-main-f331f052 writable: false

Made with Cursor

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations docker Docker and sandbox tooling size: S labels Apr 8, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 63c18b757a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/commands/sandbox-explain.ts Outdated
SandboxContext,
"workspaceDir" | "agentWorkspaceDir" | "workspaceAccess" | "containerWorkdir" | "docker"
> as unknown as SandboxContext;
const mounts = buildSandboxFsMounts(sandboxLikeContext);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Omit mounts when runtime is direct

This computes and emits sandbox.mounts before checking whether the selected session is actually sandboxed, so openclaw sandbox explain can report read-only mount boundaries even when sessionIsSandboxed is false (for example mode=off or mode=non-main on the main session). In those cases there is no sandbox mount enforcement at all, and the JSON/text output becomes misleading for users or automation that relies on this command to understand current file access constraints.

Useful? React with 👍 / 👎.

Comment thread src/commands/sandbox-explain.ts Outdated
const scopeKey = resolveSandboxScopeKey(sandboxCfg.scope, sessionKey);
const sandboxWorkspaceDir =
sandboxCfg.scope === "shared"
? sandboxCfg.workspaceRoot

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize shared workspace root before building mounts

In shared scope this uses sandboxCfg.workspaceRoot directly, but runtime sandbox setup resolves the same field via resolveUserPath first. If a user configures a home-relative or relative path (for example ~/sandboxes), this command will build hostRoot from the unexpanded value and report a different mount path than the one actually used at runtime, which defeats the purpose of showing the effective mounts.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds effective-mounts introspection to openclaw sandbox explain: sandbox.mounts now appears in JSON output, and a matching "Effective mounts:" block is printed in text mode. The implementation delegates to the existing buildSandboxFsMounts helper and threads the result through the existing payload object unchanged. All findings are P2 style suggestions.

Confidence Score: 5/5

Safe to merge; the change is additive and all remaining findings are P2.

No logic errors or regressions introduced. The new code correctly reuses buildSandboxFsMounts and passes the right context fields. Both JSON and text paths work as expected. Remaining comments are style suggestions (line length, missing text-output test).

No files require special attention.

Vulnerabilities

No security concerns identified. Mount metadata is read-only introspection of already-resolved config values; no user input is executed or written anywhere in this change.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/commands/sandbox-explain.ts
Line: 323-329

Comment:
**Long single-line mount entry format**

Each mount is rendered as a single line with four key-value pairs. For agents with real host paths this can exceed 180+ characters, making it hard to scan at a glance. Consider a multi-line format per mount to stay within comfortable terminal width:

```suggestion
  lines.push(heading("Effective mounts:"));
  for (const mount of payload.sandbox.mounts) {
    lines.push(`  - ${key("source:")} ${value(mount.source)}`);
    lines.push(`    ${key("hostRoot:")} ${value(mount.hostRoot)}`);
    lines.push(`    ${key("containerRoot:")} ${value(mount.containerRoot)}`);
    lines.push(`    ${key("writable:")} ${bool(mount.writable)}`);
  }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/commands/sandbox-explain.test.ts
Line: 99-135

Comment:
**Text output path has no test coverage**

All three tests call `sandboxExplainCommand` with `json: true`. The new "Effective mounts:" text rendering path (lines 322–330 of the source) has no coverage. A simple test with `json: false` that checks `logs.join("")` contains `"Effective mounts:"` and at least one `"source:"` token would guard against any future regression in the text format.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "CLI: show effective sandbox mounts" | Re-trigger Greptile

Comment thread src/commands/sandbox-explain.ts
Comment thread src/commands/sandbox-explain.test.ts
@zhouyou9505

Copy link
Copy Markdown
Author

Addressed review notes:

  • Mounts now only render when sessionIsSandboxed is true; otherwise JSON returns an empty array and text prints a (none) runtime is direct hint to avoid misleading users.
  • Workspace root is normalized via resolveUserPath (including shared scope) to match runtime behavior.
  • Text output for mounts is now multi-line per mount for easier scanning.
  • Added a small json:false test that asserts the Effective mounts: section renders.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d61a50efdc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/commands/sandbox-explain.ts Outdated
@zhouyou9505

Copy link
Copy Markdown
Author

Follow-up: addressed the agent-workspace override note.

  • sandbox explain now derives agentWorkspaceDir via resolveAgentWorkspaceDir(cfg, agentId) to match runtime workspace resolution (including agents.list[].workspace and agents.defaults.workspace).
  • Added a test that sets an agent-specific workspace override and asserts the source: agent mount reports the overridden hostRoot.

@zhouyou9505
zhouyou9505 force-pushed the sandbox-explain-effective-mounts branch from 697ecf0 to 21ff1e3 Compare April 8, 2026 08:52

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 21ff1e33f4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +176 to +180
const mounts = (() => {
if (!sessionIsSandboxed) {
return [];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle global session main alias before deriving mounts

This new mount derivation path can report sandbox mounts for --session global when session.scope=global and sandbox.mode=non-main, because it trusts sessionIsSandboxed from the local compare against resolveAgentMainSessionKey instead of the runtime canonicalization used by resolveSandboxRuntimeStatus (which treats global as the main/direct session). In that configuration, openclaw sandbox explain now prints non-empty sandbox.mounts even though runtime sandboxing is not active, so users and automation get an incorrect boundary report.

Useful? React with 👍 / 👎.

@zhouyou9505
zhouyou9505 force-pushed the sandbox-explain-effective-mounts branch from f53f67f to 82c13cc Compare April 8, 2026 11:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82c13cce68

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +196 to +197
containerWorkdir: sandboxCfg.docker.workdir,
docker: sandboxCfg.docker,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Derive mounts from active sandbox backend

sandbox explain now always builds mounts with buildSandboxFsMounts using sandboxCfg.docker.workdir, which only matches Docker semantics. For sandbox.backend=ssh, runtime paths come from the SSH backend (remoteWorkspaceDir/remoteAgentWorkspaceDir), so this prints container roots that are never used by the actual sandbox and misreports effective file boundaries for users/automation relying on this command.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad0542b417

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 173 to 174
? false
: sessionKey.trim() !== mainSessionKey.trim();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Canonicalize main-session aliases before sandboxing check

The non-main check compares raw strings (sessionKey.trim() !== mainSessionKey.trim()), so aliases like --session main (when session.mainKey is customized) are treated as non-main even though runtime canonicalization resolves them to the main session. Since this commit now uses sessionIsSandboxed to decide whether to emit mounts, openclaw sandbox explain can report sandbox mounts for sessions that actually run direct, which is misleading for users and scripts that trust this boundary report.

Useful? React with 👍 / 👎.

Comment on lines +196 to +197
containerWorkdir: sandboxCfg.docker.workdir,
docker: sandboxCfg.docker,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Derive effective mounts from the selected sandbox backend

Mount generation hardcodes Docker fields (sandboxCfg.docker.workdir and docker bind semantics), but runtime mount roots differ by backend. In sandbox.backend=ssh, the effective container roots come from ssh runtime paths (for example remote workspace directories), so this output can show host/container roots that are never used by the actual sandbox and misstate real file-access boundaries.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Codex automated review: keeping this open.

Current main still lacks the requested sandbox.mounts JSON field and Effective mounts: text section. The linked issue #62988 is closed as superseded by this PR, so this PR remains the active implementation candidate, but the current diff still needs maintainer cleanup because mount output is security-boundary introspection.

Best possible solution:

Keep this PR open as the active implementation candidate. Revise it to compute sandboxed status through resolveSandboxRuntimeStatus, derive effective mounts from the selected sandbox backend or a shared backend-aware mount contract, keep both JSON and text output, add focused coverage for JSON, text, Docker binds, direct runtime, session aliases, agent workspace overrides, and remote roots, and remove unrelated test-file churn before maintainer review.

What I checked:

  • Current main JSON payload has no mounts field: sandboxExplainCommand builds payload.sandbox with mode, scope, workspaceAccess, workspaceRoot, sessionIsSandboxed, and tools only; there is no mounts property. (src/commands/sandbox-explain.ts:241, f0b327cf686e)
  • Current main text output has no Effective mounts section: The renderer prints Effective sandbox:, then Sandbox tool policy:, Elevated:, and Fix-it:. A repository search for Effective mounts and sandbox.mounts returned no matches in source, tests, or docs. (src/commands/sandbox-explain.ts:286, f0b327cf686e)
  • Current sandbox explain tests do not cover mounts: The current tests assert the existing JSON shape, fix-it keys, and sandbox tool policy behavior, but do not assert sandbox.mounts, bind mount reporting, or text rendering for Effective mounts:. (src/commands/sandbox-explain.test.ts:16, f0b327cf686e)
  • Existing mount helper makes the feature plausible: buildSandboxFsMounts already returns deterministic workspace, agent, and bind mount entries with hostRoot, containerRoot, writable, and source, matching the requested data model for Docker-style mounts. (src/agents/sandbox/fs-paths.ts:61, f0b327cf686e)
  • Canonical sandbox status path exists separately: resolveSandboxRuntimeStatus canonicalizes main/global aliases before deciding whether a session is sandboxed. The provided PR discussion and review comments point out that the PR-local mount emission still depends on the raw sandbox explain session comparison path, which can misreport mounts for direct sessions. (src/agents/sandbox/runtime-status.ts:51, f0b327cf686e)
  • Remote backends have different effective roots: The remote filesystem bridge derives effective container roots from remoteWorkspaceDir and remoteAgentWorkspaceDir, while the PR diff builds mount output through the Docker-style buildSandboxFsMounts path. That can misstate effective roots for SSH/OpenShell-style backends. (src/agents/sandbox/remote-fs-bridge.ts:241, f0b327cf686e)

Remaining risk / open question:

  • Merging the current diff can report mounts for sessions that canonical runtime status would treat as direct, especially main/global aliases.
  • Merging the current diff can report Docker-style container roots for SSH/OpenShell-style backends where effective roots come from remote runtime paths.
  • Mount metadata is additive output, not code execution, but it is security-relevant because users may rely on it to understand filesystem exposure.
  • The PR includes unrelated import-order churn in test/image-generation.runtime.live.test.ts, which should be removed before maintainer review.

Codex Review notes: model gpt-5.5, reasoning high; reviewed against f0b327cf686e.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations docker Docker and sandbox tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sandbox explain: show effective mounts

1 participant