Skip to content

Add persistent repo sandbox tools#4

Merged
ephor merged 5 commits into
mainfrom
feat/repo-sandbox-tools
Jul 2, 2026
Merged

Add persistent repo sandbox tools#4
ephor merged 5 commits into
mainfrom
feat/repo-sandbox-tools

Conversation

@ephor

@ephor ephor commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add persistent repo sandbox command tool for local and Cloudflare targets
  • add Cloudflare Sandbox binding/image and local Docker runtime tooling
  • add dependency review tool and prompt guidance for sandbox-based context lookup
  • clean up PR sandbox state on pull_request closed

Verification

  • bun run typecheck
  • bun run lint
  • node --test src/lib/repo-tools.test.ts
  • bun run build
  • bun run build:cf

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a repository sandbox execution environment for running bounded commands in a persistent sandbox checkout of a PR's head ref, supporting both Cloudflare and Node.js environments. It configures Cloudflare Sandbox containers, adds new tools (run_repo_command and dependency_review), and integrates sandbox cleanup when a PR is closed. Feedback on these changes highlights a critical security vulnerability in command validation where find and sed can bypass safety checks, a portability issue with using the -l flag on /bin/sh in the Node.js runner, and a performance improvement for base64 conversion in the Cloudflare runner.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/lib/repo-tools.ts
Comment thread src/lib/repo-sandbox.node.ts Outdated
Comment thread src/lib/repo-sandbox.cloudflare.ts
Comment thread src/lib/repo-tools.ts
Comment thread src/lib/repo-sandbox.node.ts Outdated
Comment thread src/lib/repo-sandbox.node.ts Outdated
Comment thread src/lib/repo-sandbox.cloudflare.ts Outdated
Comment thread wrangler.jsonc
Comment thread Dockerfile.sandbox
Comment thread src/lib/repo-tools.test.ts
@mimir-code-assist

mimir-code-assist Bot commented Jul 2, 2026

Copy link
Copy Markdown

Mimir review — 🔴 Changes requested

The sandboxed command-execution design is mostly sound (command allowlisting, metachar rejection, per-PR lifecycle), but the Node runner — which remains the recommended production target per ADR 0001 — provides no real isolation: read-only commands inherit the server's full environment and can read arbitrary host files, so a prompt-injected PR can exfiltrate secrets. There is also a confirmed rg --pre bypass in the allowlist regex. Dockerfile.sandbox runs as root and the Cloudflare container cap of 1 limits concurrency.

Findings: 1 critical · 1 major · 3 minor · 0 nit

Escalated to the stronger model (security-sensitive-path).

💰 Review cost: $0.0912 — primary deepseek/deepseek-v4-flash $0.0247 · escalation z-ai/glm-5.2 $0.0665

isSafeSandboxCommand treated find and sed as read-only, but find -exec/-ok/
-delete/-fprint* spawn arbitrary programs or write files, and sed's w/e
commands and -i flag do the same — none require a blocked shell
metacharacter. Deny find's exec/write primaries by flag, and move sed into
the exec-gated command set alongside node/npm.

Also fixes the Node sandbox runner: /bin/sh -lc fails on dash-based
/bin/sh (Debian/Ubuntu/Alpine), tar extraction had no --no-same-owner
guard, and the Cloudflare runner's toBase64 built an intermediate binary
string instead of using Buffer.
Comment thread src/lib/repo-tools.ts
Comment thread src/lib/repo-tools.ts
Comment thread src/lib/instruction.ts
Comment thread package.json Outdated
rg's --pre/--pre-glob flags run an arbitrary command per searched file,
bypassing the read-only guard the same way find's -exec family did.
Deny it the same way.

instruction.ts and run_repo_command's own description still advertised
sed as a read-only example after it moved to the exec-gated set —
the model would issue sed and get bounced. Dropped it from both.

Pin @cloudflare/sandbox to an exact version; it's the isolation boundary
for untrusted repo code so a floating patch range shouldn't be it.
Comment thread src/lib/repo-sandbox.node.ts
Comment thread src/lib/repo-tools.ts
Comment thread src/lib/repo-tools.test.ts
Comment thread Dockerfile.sandbox
Comment thread wrangler.jsonc
ephor added 2 commits July 2, 2026 18:43
execFile inherited the full process.env, so a read-only command like
awk 'BEGIN{print ENVIRON["GITHUB_APP_PRIVATE_KEY"]}' — no file read, no
blocked metacharacter — could exfiltrate the runner's GitHub App key,
model API keys, and DATABASE_URL into a review comment. Pass an explicit
allowlisted env (PATH/HOME/locale only) to both the command-v probe and
the command itself. The Cloudflare runner is unaffected; its commands run
in an isolated container that never sees the worker env.
@ephor ephor merged commit 17fcf90 into main Jul 2, 2026
2 checks passed
@ephor ephor deleted the feat/repo-sandbox-tools branch July 2, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant