Autosolve bwrap sandbox#29
Open
fantapop wants to merge 2 commits into
Open
Conversation
2c41941 to
7d08083
Compare
There was a problem hiding this comment.
Pull request overview
Wraps the claude subprocess invoked by autosolve/assess and autosolve/implement in a bubblewrap filesystem sandbox so Claude can only read/write paths the action explicitly binds. This prevents inadvertent reads of credentials or unrelated repos that earlier workflow steps may drop into GITHUB_WORKSPACE/RUNNER_TEMP. Coordination files (commit message, PR body) are moved out of the repo into a scratch dir, and working_directory becomes a required strict subdirectory of GITHUB_WORKSPACE.
Changes:
- New bwrap wrapper (
wrapWithBwrap/buildBwrapArgs) plusSandboxOptionsplumbed throughassess,implement, and the AI security review. - New sandbox config validation (
loadSandboxConfig) requiringworking_directoryto be a strict subdir ofGITHUB_WORKSPACE, and resolvingread_pathsandGOOGLE_APPLICATION_CREDENTIALS. - Action.yml updates to install bubblewrap, relax
apparmor_restrict_unprivileged_userns, install claude into/usr/local/bin, and pass newread_pathsinput; commit-message / PR-body coordination moved to env-var-driven scratch paths.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents the sandbox, new read_paths input, and the working_directory requirement. |
| autosolve/assess/action.yml | Adds sandbox setup, requires working_directory, adds read_paths, installs claude into /usr/local/bin. |
| autosolve/implement/action.yml | Same sandbox setup and input changes as the assess action. |
| autosolve/internal/claude/claude.go | Adds SandboxOptions, wrapWithBwrap/buildBwrapArgs, runs claude via bwrap, and adds coordination env vars to baseline. |
| autosolve/internal/claude/claude_test.go | Tests for buildBwrapArgs covering binds, denied paths, tmpfs, --share-net, and tail argv. |
| autosolve/internal/config/config.go | Adds WorkingDir/ScratchDir/ReadPaths to Config and loadSandboxConfig validation. |
| autosolve/internal/config/config_test.go | Tests covering workspace-root rejection, outside-workspace rejection, path population, and creds auto-bind. |
| autosolve/internal/assess/assess.go | Passes SandboxOptions to the runner. |
| autosolve/internal/implement/implement.go | Sets coordination env vars, switches commit/PR-body paths to scratch dir, allows printenv for them, passes SandboxOptions. |
| autosolve/internal/implement/implement_test.go | Updates mock and tests to use scratch-dir paths via env vars. |
| autosolve/internal/prompt/templates/implementation-footer.md | Instructs claude to use AUTOSOLVE_*_PATH env vars instead of in-repo dotfiles. |
| autosolve/go.mod | Lowers Go directive from 1.26 to 1.24. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7d08083 to
465aa67
Compare
The hosted ubuntu-latest runners ship with Go 1.25.x preinstalled. With go.mod declaring "go 1.26", the action's "skip setup-go when go is on PATH" branch trusts the existing 1.25, but go build then sees the 1.26 directive and Go's auto-toolchain machinery downloads 1.26.0 mid-build, adding latency on every cold cache run. The autosolve packages don't use any post-1.21 stdlib features (slices.Contains is the newest), so 1.25 is well within the floor we need. Matching the directive to the runner's preinstalled toolchain eliminates the download. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
Wrap the claude subprocess invoked by both `assess` and `implement` in a bubblewrap sandbox that denies access to anything not explicitly bound. This prevents Claude from inadvertently reading credentials or other repositories that earlier workflow steps may have dropped into GITHUB_WORKSPACE or RUNNER_TEMP. Bind layout: - working_directory: RW (Claude's cwd) - additional_read_paths: RO (caller-specified files or directories) - GOOGLE_APPLICATION_CREDENTIALS file: RO, auto-bound when set so Claude can refresh Vertex tokens - /usr, /etc, /lib, /lib64, /opt: RO (OS + tooling, no per-user data). The action's setup step installs claude into /usr/local/bin so the binary is reachable via the /usr ro-bind without per-binary plumbing - /run/systemd/resolve: RO when present, required for DNS via /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf. We deliberately do NOT bind all of /run, which would expose /run/docker.sock — the GHA runner user is in the docker group and a reachable docker.sock is a sandbox-escape vector - Private /tmp tmpfs: RW, discarded after the run Everything else is denied — including the workspace root, RUNNER_TEMP, /home/runner, ssh keys, and credential files dropped by other steps. Other notes: - working_directory is now required and rejects the workspace root outright, since other actions (e.g. google-github-actions/auth) drop credential files there. Callers must check the target repo into a subdirectory like ./repo and pass working_directory: ./repo. - --share-net keeps the host network namespace; the alternative (private netns) fails on Ubuntu 24.04+ because AppArmor blocks RTM_NEWADDR for unprivileged netns. The sandbox enforces filesystem isolation, not network isolation. - The action setup step disables kernel.apparmor_restrict_unprivileged_userns; acceptable on ephemeral hosted runners, persistent self-hosted runners should evaluate the tradeoff first. - README documents the bind layout, caveats, and the required actions/checkout subdirectory pattern. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
465aa67 to
967cc12
Compare
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.
Wrap the claude subprocess invoked by both
assessandimplementin a bubblewrap sandbox that denies access to anything not explicitly bound. This prevents Claude from inadvertently reading credentials or otherrepositories that earlier workflow steps may have dropped into GITHUB_WORKSPACE or RUNNER_TEMP.