Skip to content

#391 feat(sbx1): SBX1.3 session-lifetime Docker+runsc worker runtime - #916

Closed
hachej wants to merge 14 commits into
mainfrom
feat/808-sbx1-3-runtime
Closed

#391 feat(sbx1): SBX1.3 session-lifetime Docker+runsc worker runtime#916
hachej wants to merge 14 commits into
mainfrom
feat/808-sbx1-3-runtime

Conversation

@hachej

@hachej hachej commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Bead: wt-391-forward-6gd.3 / issue #808

What this PR delivers

  • Session-lifetime Docker + runsc worker runtime with bounded create/exec concurrency, idempotency, expiry, workspace operations, project quotas, and fail-closed cleanup.
  • Root supervisor / UID 65532 tenant separation, a root-owned control socket, peer-credential and liveness checks, and bounded process-group cleanup.
  • Reference-only invocation credentials resolved through the trusted 16f.1 provider/binding contract.

Security fixes from the adversarial review

  • Rejects arbitrary raw env and legacy caller-classified secretEnv, including ordinary OPENAI_API_KEY and forged sandbox-invocation-secret requests.
  • Re-mints wire references through the trusted credential factory, rejects model-provider category/kind, validates exact payload scope/version/expiry/field and metadata limits, and disposes one-shot leases.
  • Keeps secret bytes out of JSON and command.Env; credentials use the shared bounded binary frame and are inherited by the authorized tenant invocation only on FD 3.
  • Runs the credential-bearing container with /workspace read-only and replaces the container before and after it, preventing workspace or container-local state from reaching a later differently-authorized invocation.
  • Runs supervisor/control helpers as root while tenant commands run as UID/GID 65532 with empty supplementary groups. Tenant socket connects and queued dead-peer requests are rejected.
  • Applies project IDs recursively to populated trees with descriptor-relative openat2, snapshot validation, fail-closed hardlink/symlink handling, and recursive verification.
  • Retains session/workspace/lease ownership after failed removal, retries with bounded backoff, and reconciles labeled leftovers on startup. This covers expiry, failed create/probe cleanup, secret replacement failure, shutdown fan-out, and reused sandbox-ID races.
  • Sanitizes retirement callback failures behind REMOTE_WORKER_INCOMPLETE_CLEANUP; the wire schema accepts only the stable error-code union.

Local verification

  • pnpm -C packages/boring-sandbox typecheck
  • pnpm -C packages/boring-sandbox test — 51 files, 493 tests passed
  • workload go test ./... — 19 tests passed
  • quota-helper go test ./... — 8 tests passed
  • pnpm lint:invariants
  • pnpm -C packages/agent typecheck and credential-contract tests

Explicitly deferred deployment gates

  • SBX1.4 wt-391-forward-6gd.4: pin the workload/helper image to qualified evidence before startContainer; use a persistent or boot-epoch nonce so replay cannot survive worker restart or a second process.
  • SBX1.5 wt-391-forward-6gd.5: admitting real-runsc evidence for openat2 workspace enforcement, project-quota disk/inode fill plus reserve, fork-bomb/PID limit, output flood, and orphan-cleanup failure on a cohort where runsc openat2 works.

Those gates are recorded separately in draft PR #918. The current cohort’s real-runsc/openat2 evidence remains non-admitting; this PR does not claim those deferred deployment proofs.

Do not merge as part of this security-fix pass.

hachej and others added 3 commits July 24, 2026 07:16
Add purpose-typed invocation secrets, stable runtime errors, atomic nonce replay protection, and canonical request digests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uy8snWzDKyjZBhsFco4Du5
Implement the fixed Docker profile, dirfd workspace helper, project quotas and host reserve, PID1 supervisor, secret-clean containers, and bounded session lifecycle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uy8snWzDKyjZBhsFco4Du5
Add the unit fault matrix, gated real-runsc lifecycle harness, non-admitting raw evidence, proof ledger, and tracked slice plan/state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uy8snWzDKyjZBhsFco4Du5
@hachej hachej added the security-review-required Requires security review before merge label Jul 24, 2026
@hachej

hachej commented Jul 24, 2026

Copy link
Copy Markdown
Owner Author

Security-fix proof of work

Head: 12939f363b10318a37a3c6834202f799d8feab1b

Remote branch verification:

12939f363b10318a37a3c6834202f799d8feab1b refs/heads/feat/808-sbx1-3-runtime

Resolved the adversarial-review must-fix findings:

  • raw/caller-classified secret and model-BYOK bypasses;
  • tenant-reachable supervisor control IPC;
  • populated-tree and hardlink-race project-quota bypasses;
  • retirement ownership loss on transient Docker removal failures;
  • cross-invocation secret persistence during container replacement;
  • callback sanitization and stable wire error-code enforcement.

Representative adversarial coverage includes ordinary-env model keys, forged credential kind/classification, tenant socket and queued dead-peer requests, populated nested quota trees, preflight/post-preflight/in-tree hardlinks, transient removal failures across expiry/create/shutdown/secret replacement, later-invocation blocking after replacement failure, exact FD3 frame/name/metadata bounds, callback failures, and unknown wire codes.

Local proof:

  • pnpm -C packages/boring-sandbox typecheck
  • pnpm -C packages/boring-sandbox test — 51 files / 493 tests
  • workload go test ./... — 19 tests
  • quota-helper go test ./... — 8 tests
  • pnpm lint:invariants
  • agent typecheck and credential-contract tests — 4 files / 19 tests, no type errors

GitHub CI: 14 passed, 0 failed. An unrelated Pi-native E2E property-test flake passed on the isolated rerun; no source change was made for it.

Deferred gates were appended to SBX1.4/SBX1.5 in draft PR #918 (36bfbb411a71d5ed2fd025646f5392227a289899), covering qualified image pinning, persistent/boot-epoch replay protection, and admitting real-runsc/openat2/quota/fork/output/orphan-cleanup evidence.

PR #916 remains unmerged.

@hachej

hachej commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Parked for salvage: tracked as factory epic #1081 (branch preserved for rebase when scheduled).

@hachej hachej closed this Aug 5, 2026
hachej added a commit that referenced this pull request Aug 10, 2026
…ng + credential-ref contract (#1163)

* #1081 feat(sandbox): salvage SBX1.3 slice 1 — V1 remote-worker request hardening + credential-ref contract

Salvaged from closed PR #916 (feat/808-sbx1-3-runtime), first mergeable
slice only:

- shared remoteWorkerProtocolV1 extensions and invocationSecretsV1
  value-free 16f.1 provider-credential-ref wire schema
- remote-worker V1 provider request hardening: request digest binding,
  single-use nonce store, tenant binding checks, pair-proxy and
  protocol-client updates
- agent credential contract additions (sandboxDelivery reference
  delivery, bindings) and stable error codes

Excluded (later slices): runsc session-lifetime runtime, Go workload and
quota helper, integration script, evidence docs. Respects SBX1.4/1.5
gates (bb6e328, d3a1bd3): no V0 remote-worker changes, no fleet
admission.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QtPPbToGDvkARQZuYKFyWN

* test(sandbox): tie credential-ref wire schema to agent contract at compile time

Adds a types-only .test-d.ts asserting ProviderCredentialRefWireV1 stays in
lockstep with agent's ProviderCredentialRefV1: agent->wire assignability,
wire == debranded agent shape, and version-literal equality. Fails tsc
--noEmit if either side drifts.

Closes #1198

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QtPPbToGDvkARQZuYKFyWN

* #1081 feat(sandbox): salvage runsc session runtime TS (#1174)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
hachej added a commit that referenced this pull request Aug 10, 2026
…ntegration harness (#1183)

* #1081 feat(sandbox): salvage SBX1.3 slice 1 — V1 remote-worker request hardening + credential-ref contract

Salvaged from closed PR #916 (feat/808-sbx1-3-runtime), first mergeable
slice only:

- shared remoteWorkerProtocolV1 extensions and invocationSecretsV1
  value-free 16f.1 provider-credential-ref wire schema
- remote-worker V1 provider request hardening: request digest binding,
  single-use nonce store, tenant binding checks, pair-proxy and
  protocol-client updates
- agent credential contract additions (sandboxDelivery reference
  delivery, bindings) and stable error codes

Excluded (later slices): runsc session-lifetime runtime, Go workload and
quota helper, integration script, evidence docs. Respects SBX1.4/1.5
gates (bb6e328, d3a1bd3): no V0 remote-worker changes, no fleet
admission.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QtPPbToGDvkARQZuYKFyWN

* #1081 feat(sandbox): salvage runsc session runtime TS

* #1081 feat(sandbox): salvage runsc Go runtime harness

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security-review-required Requires security review before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant