feat(ca-sandbox): ship the isolated-sandbox sibling plugin as Feature Forge preview (v0.1.0) - #111
Merged
Conversation
…ted-repo sandbox (ADR-0007) A locally-hosted GitHub-Codespace equivalent: pull an untrusted repo into an ephemeral, isolated container (no host-FS access, configurable network, dep-cached build), explore, tear down. Ships as a second sibling plugin in the marketplace per ADR-0007 — independent of the ca governance kernel, with path-scoped CI and per-plugin version bumps. Tools (TS, esbuild-bundled to sandbox.js): - mounts: bind-rejecting mount builder (volume/tmpfs only) - dephash: deterministic, manifest/lockfile-sensitive build hash - build: nixpacks wrap + dephash image cache + deps relocated to /deps - run: cap-drop ALL, non-root, read-only root, no docker.sock, never privileged - create/destroy/registry: named-volume clone + label-based lifecycle + prune - network: offline default, clone-then-cut, experimental egress allowlist - exec/cp/cli: JSON exec contract, host-out copy, subcommand dispatch - claude-inside: env-token auth + named-volume HOME persistence, Anthropic-only default Security review (auth-crypto + isolation reviewers) ran on the staged diff; two HIGH findings fixed before commit: - create.ts: validate the untrusted clone url (allowlist https/ssh/scp, reject ext::/fd::/file:// and leading-'-') + emit `git clone ... -- <url>` — closes a git argument-injection / transport-helper RCE surface in the clone container. - claude-inside.ts: the --with-claude box now runs --cap-drop ALL + --user 1000:1000 (was root + full caps despite the docstring); image chowns CLAUDE_HOME so the hardened, read-only box still persists credentials. Tests now assert the posture. security-controls.md gains a Container-isolation section, the CLAUDE_CODE_OAUTH_TOKEN secret, and the clone-trust + nixpacks-install boundary crossings. 178/178 tests pass (docker-gated behavioral ACs run real containers); typecheck clean; sandbox.js fresh; multi-stack fixtures (node/py/go/rust). Governance: ADR-0007 + spec + plan + spike notes; marketplace/CONTEXT/tech-stack/ README updated; check-plugin-refs parameterized over both plugins; CI path-scoped (dorny/paths-filter, per-plugin tools/refs/version-bump jobs, ca-sandbox-v* tags). Claude-Session: https://claude.ai/code/session_01TyodF13mUUNrGgcVTmGjgW
The ca-sandbox debut (7cce1a1) shipped the plugin, marketplace registration, and README Feature Forge entry but no changelog. Add a plugin-scoped CHANGELOG (ca-sandbox versions independently of ca per ADR-0007) documenting the 0.1.0 preview surface and the honest not-yet-blessed posture. Claude-Session: https://claude.ai/code/session_018fLGikjkdB52vyGsDDooPu
…duction
The ca-sandbox version-bump guard ran `git show origin/main:plugins/ca-sandbox/
.claude-plugin/plugin.json` to read the base version — but on a plugin's very
first PR that path does not exist on base, so git errors, pipes an empty string
to node, JSON.parse('') throws, and under `bash -e` the step dies before
reaching the tag-existence check that would correctly allow an unpublished
version. Treat a missing base plugin.json as a new-plugin introduction (nothing
published yet → no staleness trap → allowed). The already-published guard is
unchanged once the plugin exists on base.
Claude-Session: https://claude.ai/code/session_018fLGikjkdB52vyGsDDooPu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ships ca-sandbox 0.1.0 — the sibling infrastructure plugin from ADR-0007 — into the marketplace and the README Feature Forge as a
preview.Readiness — verified, not assumed
Ran the full suite locally against real Docker: 178/178 tests green across 16 files (~171s), including every docker integration spec — host-FS isolation canary, network policy (offline / clone-then-cut / allowlist), multi-stack builds (node/py/go/rust), lifecycle create→destroy→prune,
--with-claudereaching auth with a dummy token (real 401), and exec/cp/run isolation flags. Typecheck clean;sandbox.jsartifact fresh.What lands
ca-sandboxplugin (plugins/ca-sandbox/, v0.1.0): ephemeral isolated container, content-hash dep cache, configurable egress, exec/cp seams, experimental--with-claude.CHANGELOG.md(the debut commit shipped without one).Posture
Honest preview / not-yet-blessed: green suite, but unproven in real use;
--with-claudeverified only against a dummy token. Off by default. Promotes on real-world evidence.CI
Path-scoped (ADR-0007): the docker-gated
ca-sandbox-toolsjob runs;cajobs skip. Per-plugin version-bump guard passes (no prior ca-sandbox tag).After merge
Tag
ca-sandbox-v0.1.0and publish as a pre-release (beta).https://claude.ai/code/session_018fLGikjkdB52vyGsDDooPu