Skip to content
SkilledDragonEngineering Intelligence
MinilabKeylessOctober 13, 2026 · re-run October 14, 2026

Strands Box merge lock: git push to main denied in 26 policy cases, no live Box run

We wrote a default-deny Dogwood policy for Strands Box. Keyless: 3 of 3 cargo tests over 26 commands; git status allowed, git push origin main denied with exit 1.

By David Discua

Measured in the lab

3
cargo tests passed
26
policy cases
1
push to main exit
  • git status allowed by rule git_status
  • git push origin main denied by rule forbid_git_push
  • GITHUB_TOKEN stripped from the guarded env
  • upstream unit tests green on ubuntu and macOS

From reports/gate.json · run on October 14, 2026. Strands Box v0.1.0 pinned at 223e3959; policy verdicts via merge-guard check; real Box subprocess test skipped in CI; containment and verdict workflows out of scope

How it is wired

shell:spawncheckallowdenyAgent shellStrands BoxmacOS arm64 previewmerge-locked.dwdefault denygit statusALLOWgit push mainDENY, exit 1

01/03Every command the agent spawns goes through Box as a shell spawn request.

strands-agents/box runs AI agents in a sandbox that restricts what they can execute, read, write and reach, using OS isolation, default-deny Dogwood policies, and credential injection that keeps secrets outside the agent. We wrote a merge-locked policy and a merge-guard CLI, and on October 14, 2026 the keyless run passed 3 of 3 cargo tests covering 26 commands, allowing git status and denying git push origin main with exit 1. Every one of those checks asked the policy engine for a verdict, and no test in CI ran a command inside a real Box.

The catch

Box's local sandbox is a preview that runs on macOS Apple silicon only, with Linux support planned. merge-guard check evaluates an argv against a .dw policy through strands-box-policy and prints ALLOW or DENY with the rule id. That is the verdict Box would apply. Enforcement happens only when the agent process runs inside Box.

The macos-live CI job passed on macos-15 in 37 s. It runs macos_box_deny, which has two tests. The first repeats the policy-level deny on Apple silicon. The second spawns strands-box run and expects a denial, but only when STRANDS_BOX points at a built binary. CI does not set that variable, so the second test returned early.

Two more limits apply. Upstream's containment and verdict workflows and its ci-gate were out of scope and did not run. And cargo audit ignores RUSTSEC-2026-0249, an unmaintained smartstring crate that arrives through strands-box-policy at this pin.

What we ran (keyless)

git -C upstream rev-parse HEAD
# must print 223e3959d539110eaacfacb6f973c03928dc39b0
cargo test --workspace --locked
cargo run -p merge-guard --locked -- check --policy policies/merge-locked.dw -- git status
cargo run -p merge-guard --locked -- check --policy policies/merge-locked.dw -- git push origin main

From reports/gate.json, run on October 14, 2026:

CheckResult
cargo test --workspace --locked3 passed, 0 failed, 16 s, 26 table cases
locked policy, git statusALLOW rule=git_status
locked policy, git push origin mainDENY rule=forbid_git_push, exit 1
Lab CItest 23 s, lint 22 s, macos-live 37 s, secrets 6 s, audit 135 s, skills 4 s, gate 3 s, all success
Upstream unit testsubuntu 577 s, macOS 606 s, both success
Upstream lint, parity, pin55 s, 19 s, 6 s, all success

The locked policy permits read-only git (status, diff, log, fetch, show, rev-parse, branch listing) and read-only gh pr commands such as view, list and checks. It forbids git push, git merge, a rebase onto main or master, and gh pr merge. The unlocked policy adds push to a non-main ref and still denies push to main and a bare git push. The third test checks that GITHUB_TOKEN is absent from the environment merge-guard hands a guarded child.

How it is wired

Box wraps the agent process, and every command the agent starts becomes a shell:spawn request checked against the loaded policy. While review and CI gates are open, Box loads merge-locked.dw. An operator swaps in merge-unlocked.dw when the gates pass. In examples/box.toml the GitHub token is injected only on egress to github.com and api.github.com, so the agent process never reads it.

Minilab (open source)

Upstream is strands-agents/box (403 stars, Apache-2.0, Rust, as of October 14, 2026), pinned at 223e3959 (v0.1.0). Clone the lab with submodules and run cargo test --workspace --locked. On an Apple silicon Mac, build strands-box, set STRANDS_BOX to its path, and run cargo test --workspace --locked --test macos_box_deny to see the deny inside a real Box.

Run it yourself

SkilledDragonCorp/minilab-box-contain-merge

Clone, install and run the report with no API keys. The numbers above are what that run writes.

cargo test --workspace --locked

SkilledDragon is not affiliated with strands-agents/box or the Strands Agents project. Numbers are from our own keyless lab run; re-run the report before relying on them. Marks belong to their owners.

All labs