Skip to content

fix(sandbox): require path protection for the sandbox modes - #1235

Merged
xiaozhou26 merged 1 commit into
mainfrom
fix/sandbox-require-path-protection
Nov 5, 2026
Merged

xiaozhou26 merged 1 commit into
mainfrom
fix/sandbox-require-path-protection

Conversation

@xiaozhou26

Copy link
Copy Markdown
Contributor

Linked issue

Closes #1234

Depends on #1233 (pin bundled K-brain to v0.107.21): that K-brain adds the Linux Landlock fallback and the run_sandbox.path_protection field. This PR is safe to merge on its own (older K-brain omits the field and behaves as before), and it should land before or together with #1233, which otherwise fails permission-modes-backend.test.mjs › sandbox-protected on the Linux runner.

Summary

With bubblewrap unusable, K-brain v0.107.21 sandboxes commands with Landlock and reports run_sandbox: { supported: true, mechanism: "landlock", network_control: true, read_masking: false, path_protection: false }. Without path protection, .liveagent/, .k-brain/, .git/hooks and .git/config are writable inside the sandbox, and those files are later used outside it, so a sandboxed command can escape. LiveAgent's Sandbox modes promise those paths stay read-only, so LiveAgent now requires path protection:

  • path_protection === false means the sandbox is unavailable for both Sandbox and Offline sandbox.
  • Desktop selector: both entries are disabled. The hint is chat.safety.sandboxUnavailable followed by a new chat.safety.sandboxNoPathProtection explanation.
    • en-US: "K-brain cannot sandbox commands on this machine: protected paths (.liveagent, .git/hooks) can't be kept read-only with the Landlock fallback; install bubblewrap or allow unprivileged user namespaces"
    • zh-CN: "K-brain 无法在本机启用沙箱: Landlock 回退方案无法让受保护路径(.liveagent、.git/hooks)保持只读;请安装 bubblewrap 或允许非特权用户命名空间"
  • Run-time gates fail closed: the desktop K-brain client (supportsRunSandbox) and the Gateway (SupportsRunSandbox / requireRunOptions) refuse to submit options.sandbox with a clear error, so a stale UI setting or a WebUI request can't run with protected paths writable.
  • Missing field (older K-brain): treated as protected, the same as today. As with the read-masking mechanism list, a missing field with the landlock mechanism counts as unprotected, but no released K-brain sends that combination. An unsupported sandbox keeps K-brain's own reason.
  • read_masking handling (sandboxDescNoReadMask) is unchanged.

Change scope

  • Modules: agent-ui, agent-gui, agent-gateway (Go), docs
  • Key paths:
    • crates/agent-ui/src/lib/kbrain/health.ts: new runSandboxLacksPathProtection, used by supportsRunSandbox
    • crates/agent-gui/src/agent-ui-adapters/sandboxCapability.ts: desktop capability reports supported: false and path_protection: false
    • crates/agent-ui/src/components/chat/CommandSafetyModeSelector.tsx, plus the en-US and zh-CN translations
    • crates/agent-gui/src/lib/kbrain/client.ts: refusal message
    • crates/agent-gateway/internal/kbrain/health.go: same gate for WebUI and remote runs
    • crates/agent-gateway/web/src/agent-ui-adapters/sandboxCapability.ts: type only
    • docs/kbrain-permission-modes.md

Screenshots / preview

Sandbox entries disabled: the K-brain sandbox lacks path protection

How this was produced: I ran the real desktop app, a debug target/debug/liveagent from this branch with the Vite dev server, isolated with LIVEAGENT_DEV_HOME/HOME set to temp dirs. Its LIVEAGENT_KBRAIN_BINARY points to a wrapper that starts a real K-brain v0.107.21 backend in an Ubuntu 24.04 container (linux/arm64, no bubblewrap). That binary was built from the v0.107.21 tag, because the release ships no linux-arm64 asset and the x64 release under emulation has no Landlock. Nothing in the health response is stubbed. K-brain itself reported "mechanism": "landlock", "supported": true, "network_control": true, "read_masking": false, "path_protection": false. The app UI was in zh-CN; I opened the selector through the debug build's dev bridge and took the image with the bridge's native window capture, then cropped it to the composer area (sidebar removed).

Verification

  • node --test test/chat/permission-modes.test.mjs test/chat/command-safety-mode-selector.test.mjs: new cases cover path_protection: false (unavailable online and offline, run refused before any POST), field missing (unchanged), true (available), Landlock without the field, an unsupported sandbox keeping its own reason, and the selector hint for both entries.
  • permission-modes-backend.test.mjs: the sandbox cases now also require path_protection !== false. When K-brain reports a supported but unprotected sandbox, a new sandbox-without-path-protection case checks that the client refuses the run.
    • macOS + K-brain v0.107.21 (Seatbelt, path_protection: true): 13/13 pass, sandbox cases run.
    • Linux container (node:22-alpine, no bwrap) + K-brain v0.107.21 (Landlock): main fails sandbox-protected, the same failure as on chore(release): pin bundled K-brain to v0.107.21 #1233. This branch: the refusal case passes, the two sandbox cases are skipped, 0 failures.
  • cd crates/agent-gateway && go test ./...: pass, with new TestRunSandboxCapabilityBeforeSubmission cases.
  • pnpm test:gui (4107 pass, 0 fail), pnpm test:webui (884 pass), pnpm typecheck:ui, typecheck:gui, typecheck:webui, check:ui-boundaries, and biome on the changed files.

Pre-submit checklist

  • A requirement issue is linked (or this is a trivial fix that needs no issue, as explained in the summary).
  • Synced with the target branch; no merge conflicts.
  • The change is focused, with no unrelated modifications.
  • No secrets, tokens, or personal data included.
  • Docs are updated for changes affecting user behavior, deployment, or configuration.

K-brain v0.107.21 falls back to Landlock on Linux when bubblewrap is
unusable and reports run_sandbox.path_protection=false: .liveagent,
.k-brain, .git/hooks and .git/config stay writable inside the sandbox
and are later used outside it. Treat such a sandbox as unavailable:
the desktop selector disables Sandbox and Offline sandbox with an
explanation, and the desktop client and the Gateway refuse to submit
options.sandbox. A missing field (older K-brain) counts as protected
unless the mechanism is landlock.

Closes #1234
@xiaozhou26
xiaozhou26 merged commit 55d8ef9 into main Nov 5, 2026
14 checks passed
@xiaozhou26
xiaozhou26 deleted the fix/sandbox-require-path-protection branch November 5, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sandbox modes must require path protection (K-brain Landlock fallback leaves .liveagent and .git/hooks writable)

1 participant