P3 prerequisite: implement @mosaicstack/harness-sandbox #1183

Open
opened 2026-08-13 00:40:10 +00:00 by Ghost · 0 comments

P3 prerequisite gap

Read-only reconciliation at next=216cd72226cd9ee17eea461cfe7cd0e010a22f02 found no merged/exportable HarnessSandbox or equivalent workspace-confined file/process broker. The P3 plan placeholders HARNESS_SANDBOX_APPROVAL_REF, HARNESS_SANDBOX_CONTRACT_IMPORT, and HARNESS_SANDBOX_OWNER cannot be satisfied today.

Legacy Gateway file/shell/git tools are not an approvable substitute: requested paths are lexically guarded but not descriptor/inode-bound; ordinary read/stat/write calls permit symlink/rename races; shell uses sh -c with inherited Gateway environment; no namespace separates auth/session/host/sibling roots; descendants/output/error/path egress are not safely normalized. The lease broker authorizes classes but is not an execution sandbox.

Objective

Deliver a Stack-owned package export:

import {
  createLinuxHarnessSandbox,
  type HarnessSandbox,
  type WorkspaceToolRequest,
  type WorkspaceToolResult,
} from '@mosaicstack/harness-sandbox';

Separate a trusted contained Pi control process from an untrusted workspace tool broker. Task 9 consumes this package; it does not own or reimplement the backend.

Binding contract

  • Rootless Linux namespace backend; fail closed when namespace/mount/readiness controls are unavailable.
  • Control profile mounts only assigned composed seat/auth/session roots plus reviewed runtime assets.
  • Tool profile mounts only authorized workspace + scratch; no auth/config/session, host home, sibling seat/workspace, SSH agent, container socket, Gateway application tree, or ambient sockets.
  • Workspace root is opened/validated then inode-bound; relative NUL-free paths; no-follow final opens; symlink/rename-race defense.
  • Atomic safe writes: exclusive temporary file, fsync, atomic replace, parent fsync.
  • Closed broker operations: bounded read/write/edit/list/search/find and process.exec with server-side commandId; never a shell command string.
  • Immutable absolute executable map, argument policies, explicit environment allowlist, cwd containment, finite timeout/output/resource bounds, owned process group/PID namespace, TERM/KILL cleanup.
  • Closed safe result union: stable codes, relative paths, byte-counted output/truncation, exit kind/duration/correlation; no raw Error, host path, env, mounts, credentials, or runtime handles.

Minimum behavioral/security evidence

  1. Contract/unknown-op/result normalization tests.
  2. Traversal, absolute, NUL, sibling-prefix and encoding refusals.
  3. Real-kernel symlink and repeated rename-race attacks on root/ancestor/leaf.
  4. Control/tool split canaries; sibling-seat, host-home, SSH/container socket denials.
  5. Two-tenant concurrent containment.
  6. Shell/interpreter/PATH/loader/redirection/substitution/unknown-command refusal before spawn.
  7. Timeout/output flood kills descendants and bounds combined output.
  8. Invalid UTF-8, signal, backend loss and output-limit safe outcomes.
  9. Inside-profile environment/socket inventory.
  10. Production Gateway-image containment/readiness test.
  11. Pi fixture proves --no-builtin-tools, no !, only reviewed broker-client tools.
  12. Independent exact-head code/security review and merged approval ref.

Scope discipline

Dedicated platform/security prerequisite lane. It may own packages/harness-sandbox/**, package lock/workspace integration, bounded backend/image/CI evidence, and sandbox docs. It must not touch P3 adapter/RPC/conversation files, W-F1 composition/launcher, lease-broker implementation, auth contents, or KBN startup behavior.

Before mutation, author reports exact current base/branch, immutable path fence, package/image overlap with KBN-101-02a #1178 and #1156 children, RED matrix, and whether core package versus Gateway image integration must be split to avoid collision. Scrappy owns integration gate; independent security reviewer owns containment verdict.

This issue is a hard prerequisite for pinning P3_NATIVE_IMPLEMENTATION_BASE_SHA and for native Task 9. It does not authorize a provider call, service start, deployment, or stage repin.

## P3 prerequisite gap Read-only reconciliation at `next=216cd72226cd9ee17eea461cfe7cd0e010a22f02` found no merged/exportable `HarnessSandbox` or equivalent workspace-confined file/process broker. The P3 plan placeholders `HARNESS_SANDBOX_APPROVAL_REF`, `HARNESS_SANDBOX_CONTRACT_IMPORT`, and `HARNESS_SANDBOX_OWNER` cannot be satisfied today. Legacy Gateway file/shell/git tools are not an approvable substitute: requested paths are lexically guarded but not descriptor/inode-bound; ordinary read/stat/write calls permit symlink/rename races; shell uses `sh -c` with inherited Gateway environment; no namespace separates auth/session/host/sibling roots; descendants/output/error/path egress are not safely normalized. The lease broker authorizes classes but is not an execution sandbox. ## Objective Deliver a Stack-owned package export: ```ts import { createLinuxHarnessSandbox, type HarnessSandbox, type WorkspaceToolRequest, type WorkspaceToolResult, } from '@mosaicstack/harness-sandbox'; ``` Separate a trusted contained Pi control process from an untrusted workspace tool broker. Task 9 consumes this package; it does not own or reimplement the backend. ## Binding contract - Rootless Linux namespace backend; fail closed when namespace/mount/readiness controls are unavailable. - Control profile mounts only assigned composed seat/auth/session roots plus reviewed runtime assets. - Tool profile mounts only authorized workspace + scratch; no auth/config/session, host home, sibling seat/workspace, SSH agent, container socket, Gateway application tree, or ambient sockets. - Workspace root is opened/validated then inode-bound; relative NUL-free paths; no-follow final opens; symlink/rename-race defense. - Atomic safe writes: exclusive temporary file, fsync, atomic replace, parent fsync. - Closed broker operations: bounded read/write/edit/list/search/find and `process.exec` with server-side `commandId`; never a shell command string. - Immutable absolute executable map, argument policies, explicit environment allowlist, cwd containment, finite timeout/output/resource bounds, owned process group/PID namespace, TERM/KILL cleanup. - Closed safe result union: stable codes, relative paths, byte-counted output/truncation, exit kind/duration/correlation; no raw Error, host path, env, mounts, credentials, or runtime handles. ## Minimum behavioral/security evidence 1. Contract/unknown-op/result normalization tests. 2. Traversal, absolute, NUL, sibling-prefix and encoding refusals. 3. Real-kernel symlink and repeated rename-race attacks on root/ancestor/leaf. 4. Control/tool split canaries; sibling-seat, host-home, SSH/container socket denials. 5. Two-tenant concurrent containment. 6. Shell/interpreter/PATH/loader/redirection/substitution/unknown-command refusal before spawn. 7. Timeout/output flood kills descendants and bounds combined output. 8. Invalid UTF-8, signal, backend loss and output-limit safe outcomes. 9. Inside-profile environment/socket inventory. 10. Production Gateway-image containment/readiness test. 11. Pi fixture proves `--no-builtin-tools`, no `!`, only reviewed broker-client tools. 12. Independent exact-head code/security review and merged approval ref. ## Scope discipline Dedicated platform/security prerequisite lane. It may own `packages/harness-sandbox/**`, package lock/workspace integration, bounded backend/image/CI evidence, and sandbox docs. It must not touch P3 adapter/RPC/conversation files, W-F1 composition/launcher, lease-broker implementation, auth contents, or KBN startup behavior. Before mutation, author reports exact current base/branch, immutable path fence, package/image overlap with KBN-101-02a #1178 and #1156 children, RED matrix, and whether core package versus Gateway image integration must be split to avoid collision. Scrappy owns integration gate; independent security reviewer owns containment verdict. This issue is a hard prerequisite for pinning `P3_NATIVE_IMPLEMENTATION_BASE_SHA` and for native Task 9. It does not authorize a provider call, service start, deployment, or stage repin.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1183