Skip to content
PortBay

Run untrusted work inside a macOS sandbox

A cloned repo or an agent-modified project runs wrapped in a sandbox-exec profile: writes stay in the project folder, network follows your policy, and every denial is logged.

The short answer

How do I stop an AI coding agent from breaking my machine?

Confine the process before you run it. macOS ships sandbox-exec, which applies a Seatbelt profile to a command: start the profile with deny default, allow file-write* only under the project's subpath, and the run can no longer touch anything outside that folder. Writing and maintaining one profile per project is the part people skip. PortBay generates and manages the profile instead. File writes are confined to the project folder and temp directories; network access follows a policy you pick per project — blocked, loopback only, outbound, or full. An Ephemeral toggle clears the run's state directory before every start, and Clone in Sandbox takes a Git URL, shallow-clones it with credential prompts disabled, and runs it before you trust it. Denials surface one line at a time in a violations log, like deny(1) file-write-create ~/.ssh/id_ed25519. It is a write boundary, not a VM: file reads are not blocked.

Verified against the product, 2026-07-10.

In the app

The code runs. The writes it shouldn't make don't.

Untrusted Demo — sandboxed run
$sandbox-exec-f untrusted-demo.sb /bin/zsh -lc "npm run dev"
writes: project folder only
Violations log

A cloned repo starts under a sandbox-exec profile: the dev server comes up on its .test URL while writes outside the project and off-policy network calls land in the violations log.

How it works

From unknown repo to informed decision

  1. Clone in Sandbox
  2. Pick a network policy
  3. Start it
  4. Read the violations log
  5. Promote when you trust it

Clone in Sandbox

Paste an https:// or git@ URL. PortBay clones shallow with credential prompts disabled, refuses system directories as targets, and registers the project with the sandbox already on.

[email protected]:someone/untrusted-demo.git

Pick a network policy

Blocked, loopback only, outbound, or full. Choose the least-permissive policy that lets the project run: a local-only dev server needs loopback, an npm install needs outbound.

Start it

The start command runs wrapped. Writes outside the project folder and temp directories are denied by the profile; signals stay inside the sandbox's own process tree.

sandbox-exec -f untrusted-demo.sb /bin/zsh -lc "npm run dev"

Read the violations log

Every denied operation is one line: a write aimed at your SSH keys, a network call under a blocked policy. You see what the code tried before deciding what it deserves.

deny(1) file-write-create /Users/you/.ssh/id_ed25519

Promote when you trust it

One click turns the sandbox off and the project runs natively from then on. Ephemeral mode is there when you want each sandboxed start from a clean slate instead.

Spec

Sandbox, tier by tier

CapabilityCommunityPro
Projects sandboxed at once2Unlimited
Network policiesAll 4All 4

Blocked, loopback only, outbound, full — per project.

Clone in Sandbox from a Git URLIncludedIncluded
Ephemeral modeIncludedIncluded

The run's state directory is cleared before each sandboxed start.

Violations logIncludedIncluded

Caps verified against the app source. Sandboxed runs shipped through the early-access channel; if your build doesn't show them yet, update the app.

Without PortBay

Vetting an unknown repo by hand

The manual options are reading every install hook, spinning up a container or VM, or writing your own Seatbelt profile. Most people skip all three and run it anyway.

PortBay generates the profile, applies your network policy, and shows every denial in a log you can read.

Questions

Asked before downloading

File writes are confined to the project folder and temp directories; anything else is denied. Network access follows the policy you pick (blocked, loopback only, outbound, full). Signal delivery stays inside the sandbox's process tree. File reads are not blocked: the meaningful protection is the write boundary plus the network policy.

No, and PortBay doesn't claim it is. sandbox-exec is a macOS-native mechanism that constrains what a process can do; it is not kernel-level isolation. Treat it as trust-but-verify friction for inspecting code, not a hard containment boundary for code you believe is hostile.

Paste a Git URL and PortBay clones it shallow (depth 1) with credential prompts disabled, blocks file:// URLs and system directories as targets, and registers the project with the sandbox on. You watch the project run and read its violations before deciding whether to trust it.

Two at once, in both the anonymous and signed-in free tiers. Pro removes the cap. Turning the sandbox off on one project frees the slot for another.

Yes. Open the project's detail panel and click View sandbox violations. Each denial is one line with the operation and the target path, like deny(1) file-write-create ~/.ssh/id_ed25519, filtered live from the process log.

PortBay mascot — a friendly blue tugboat

Give your projects and your agents a real local home.

Download for macOS

Free & open source · macOS 11+ on Apple Silicon · Pro from $10/mo