feat(runtime): judge a command's risk by where it will run - #59
Merged
Conversation
With the sandbox on, a command runs in a micro-VM that is discarded. A
whole class of it is no longer dangerous because of where it lands, and
prompting anyway is how a user learns to click through the dialog that
mattered.
What this newly permits, named rather than implied:
chmod / chown / chgrp, systemctl / launchctl / service, mount / umount,
apt / brew / dnf / pacman / snap, ifconfig / route / iptables,
reboot / shutdown, crontab / at — and any declared write or redirect
outside the workspace, such as `mkdir /opt/thing` or
`echo hi > /etc/hosts`.
Each is safe for one reason: its entire effect lands on a machine that is
thrown away, and the only thing that crosses back is a file sync confined
to the workspace which refuses to overwrite a local change.
What it deliberately does not permit:
- Deleting. The sync carries deletions home — applyChanges removes every
local file whose sandbox copy went away and whose contents still match
the snapshot — so a sandboxed `rm -rf src` costs the user's
uncommitted work. DESTRUCTIVE is also where every unrecognised command
lives, and auto-approving the level would auto-approve all of them.
- The network. Egress is on by default and the workspace source is
pushed into the sandbox, so curl, wget, ssh, scp, rsync and git's
remote subcommands are how it leaves.
- Remote control planes. kubectl, terraform, docker and helm talk to
clusters and daemons that are not in the VM.
sudo is neither listed nor ignored. It is not a transparent prefix, so
`sudo rm -rf /` grades as plain SYSTEM elsewhere in the classifier —
listing it as contained-safe would have made it a workspace write and run
it unattended. Contained, it is the maximum of a write and whatever it
wraps: `sudo apt-get install` runs, `sudo rm -rf /` still asks.
Containment enters the classifier, not the policy. requiresApproval is
`risk > ceiling` over a linear enum, so no ceiling can permit SYSTEM
without also permitting DESTRUCTIVE — the one combination to avoid.
policy.ts and approval-mode.ts are untouched and there is no new mode.
Every rule has fixtures in both directions, and the approval dialog now
says when a command it is asking about will run in the sandbox.
Verified live: with AUTO_WORKSPACE and a real sandbox, chmod ran without
a prompt, `rm -rf src` still prompted, and the host's file modes and
working tree were unchanged.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
The payoff for phases 1–5: with the sandbox on, machine-level work stops asking. Deleting, the network, and anything unrecognised still ask.
This is a permission widening, so it is a draft PR rather than a push to main.
What this newly permits
chmod/chown/chgrp,systemctl/launchctl/service,mount/umount,apt/brew/dnf/pacman/snap,ifconfig/route/iptables,reboot/shutdown,crontab/at— plus any declared write or redirect outside the workspace (mkdir /opt/thing,echo hi > /etc/hosts).Each is safe for one reason: its whole effect lands on a VM that is discarded, and the only thing that crosses back is a file sync confined to the workspace that refuses to overwrite a local change.
What it deliberately does not permit
applyChangesremoves every local file whose sandbox copy went away and whose contents still match the snapshot — so a sandboxedrm -rf srccosts uncommitted work.DESTRUCTIVEis also where every unrecognised command lives.curl,wget,ssh,scp,rsyncand git's remote subcommands are how it leaves.kubectl,terraform,docker,helmtalk to things that are not in the VM.The list is an allowlist, so anything added to
SYSTEM_COMMANDSlater is contained-unsafe by default.Two things worth reviewing closely
sudo. It is not a transparent prefix, sosudo rm -rf /grades as plainSYSTEMelsewhere in the classifier. Listing it as contained-safe would have made it a workspace write and run it unattended. Contained, it is the max of a write and whatever it wraps:sudo apt-get installruns,sudo rm -rf /still asks.Why the classifier and not the policy.
requiresApprovalisrisk > ceilingover a linear enum, so no ceiling can permitSYSTEMwithout also permittingDESTRUCTIVE— the one combination to avoid.policy.tsandapproval-mode.tsare untouched; no new mode.Verification
bun run verify --alland--staged: 4 gates. Reverse-order sweep: 1870 pass, 0 fail across 114 files.AUTO_WORKSPACE:chmodran with no prompt,rm -rf srcstill prompted, host file modes and working tree unchanged.Not covered
The approval picker's mode descriptions still describe uncontained behaviour — a copy change, deferred. Network egress remains the boundary's weak edge;
WOOPCODE_SANDBOX_NETWORK=noneis the brake and nothing here changes it.