Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
138 lines
5.6 KiB
Markdown
138 lines
5.6 KiB
Markdown
---
|
|
id: SAND-WP-0014
|
|
type: workplan
|
|
title: "Owner-mediated governed bwrap execution"
|
|
domain: infotech
|
|
repo: sand-boxer
|
|
status: active
|
|
owner: codex
|
|
topic_slug: owner-mediated-execution
|
|
created: "2026-09-04"
|
|
updated: "2026-09-05"
|
|
state_hub_workstream_id: "b616d1cd-208f-5ecf-a4a0-a028396422c4"
|
|
---
|
|
|
|
# Owner-mediated governed bwrap execution
|
|
|
|
Promote intake `GLAS-IN-0002` into sand-boxer ownership. Replace the unusable
|
|
consumer-side `nsenter` hint with an owner-executed command boundary that remains
|
|
bound to the sandbox and its governed consumer identity. A refused execution
|
|
must never fall back to a host checkout or another extension.
|
|
|
|
## Define the governed execution contract
|
|
|
|
```task
|
|
id: SAND-WP-0014-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "1b4349de-7027-5f01-8deb-122772e1404d"
|
|
```
|
|
|
|
Define request/result schemas and evidence for exact actor/project/session/run
|
|
binding, ready/active lifecycle, workspace confinement, declared network
|
|
posture, value-free credential route references, bounded command duration, and
|
|
bounded output.
|
|
|
|
## Implement owner-mediated bwrap execution
|
|
|
|
```task
|
|
id: SAND-WP-0014-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "59f9af7c-7cd7-5e86-849f-5dfc7a3a06ee"
|
|
```
|
|
|
|
Add manager, extension, CLI, and authenticated HTTP surfaces. Only `ext.bwrap`
|
|
may execute in this slice. The extension launches an owner broker inside bwrap,
|
|
uses the sandbox workspace as its working directory, starts commands with a sanitized
|
|
environment, and fails closed if the recorded workspace is not the exact
|
|
owner-managed sandbox directory.
|
|
|
|
## Remove direct namespace-entry guidance
|
|
|
|
```task
|
|
id: SAND-WP-0014-T03
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "4fc7d747-13d5-58e7-b89e-b72e845515aa"
|
|
```
|
|
|
|
Stop publishing raw consumer-side `nsenter` commands. Reachability describes
|
|
owner-mediated execution without exposing a misleading direct-attach route.
|
|
|
|
## Verify unit and local namespace behavior
|
|
|
|
```task
|
|
id: SAND-WP-0014-T04
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "c7ada937-4430-59d7-b3a6-9f3f36e9a907"
|
|
```
|
|
|
|
Cover identity/state/TTL refusal, unsupported-extension refusal, exact workspace
|
|
validation, sanitized environment, credential route references, timeout/output
|
|
bounds, API authentication, lifecycle restoration, and teardown. Run the full
|
|
repository check and, when host user namespaces permit it, a non-secret live
|
|
bwrap command proof.
|
|
|
|
Implemented and verified 2026-09-04. `make check` passes with 119 tests. The
|
|
first live attempt proved that even the bwrap owner cannot reliably `setns`
|
|
from the host on this kernel (`IPC: Operation not permitted`), so execution was
|
|
moved to a small read-only broker launched inside the namespace and reached via
|
|
an owner-only Unix socket. `make smoke-bwrap-exec` then passed: actor `agt`,
|
|
project/session/run binding reached the command; cwd was the copied sandbox;
|
|
the host-source sentinel was absent; the command created an artifact; the net
|
|
namespace exposed only `lo` under declared `default: deny`, `egress: []`; no
|
|
credential routes or values were present; and teardown reported `destroyed`
|
|
with the workspace removed.
|
|
|
|
The authenticated HTTP smoke subsequently exposed and fixed a lifecycle defect:
|
|
`--die-with-parent` tied bwrap to the process handling `create`, so the namespace
|
|
could disappear before a later API `exec`. Owner sandboxes now persist across
|
|
requests and remain bounded by explicit destroy, TTL expiry, and stale reaping.
|
|
|
|
The consumer-contract audit also found that Glas needs to create a private task
|
|
file without writing through the host mirror or putting prompt content in argv.
|
|
Owner exec now supports bounded `stdin_text` (1,000,000 UTF-8 bytes), delivers it
|
|
only to the child process, and excludes it from results and lifecycle evidence.
|
|
|
|
## Prove one governed rein and coordinate consumers
|
|
|
|
```task
|
|
id: SAND-WP-0014-T05
|
|
status: wait
|
|
priority: high
|
|
state_hub_task_id: "c6812fd4-bb7b-5be0-8344-a122496fe5bc"
|
|
```
|
|
|
|
With Glas and rein-aharness, run one real selected rein command through the
|
|
owner API using an explicitly declared egress profile and catalog credential
|
|
route. Prove that the source checkout is absent, retain value-free evidence,
|
|
destroy the workspace, then update Glas readiness and Activity Core
|
|
`ACTIVITY-WP-0032-T05`. Do not trigger the production pilot before readiness
|
|
changes.
|
|
|
|
This task depends on a reviewed Glas profile revision and its matching
|
|
credential/egress/runtime contract. Glas selected the Claude route first in
|
|
GLAS-WP-0012; the earlier OpenRouter AppRole dependency applies only to the
|
|
separate open-weight profile and does not establish Claude authentication.
|
|
|
|
2026-09-05: SAND-WP-0015 implements pinned Python runtime mounts and private
|
|
namespace state, with a real rein CLI startup proof. Claude workload credential
|
|
routing, enforced provider egress, pinning/deploying the Claude executable,
|
|
and the real-model acceptance remain open in SAND-WP-0015-T04. No credential
|
|
value belongs in this workplan or State Hub.
|
|
|
|
## Acceptance criteria
|
|
|
|
- Execution requires the recorded actor, project, session, and run identity.
|
|
- Only a live, unexpired, ready sandbox can start a command; concurrent commands
|
|
are refused.
|
|
- Command execution is argument-vector based, starts inside the copied sandbox
|
|
workspace, and has no host/source-checkout fallback.
|
|
- `ext.bwrap` supplies its declared read-only runtime paths and enforces the
|
|
profile's network namespace. Evidence reports default policy and egress list.
|
|
- Credential inputs are non-secret catalog route references only.
|
|
- Duration and captured output are bounded, lifecycle state is restored, and
|
|
teardown remains idempotent.
|
|
- Consumer-facing reachability no longer recommends direct `nsenter`.
|