Show HN: Minimal native macOS sandbox for Claude and Codex

sheremetyev1 pts0 comments

GitHub - sheremetyev/sandfence: Minimal native macOS sandbox for Claude Code and Codex · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

sheremetyev

sandfence

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>13 Commits<br>13 Commits

DESIGN.md

DESIGN.md

LICENSE

LICENSE

README.md

README.md

sandfence.sh

sandfence.sh

test.sh

test.sh

View all files

Repository files navigation

Sandfence

Run a coding agent — Claude Code or Codex — on a repo in its own<br>"skip-permissions" mode, while the macOS sandbox , not the agent, enforces what it<br>can touch. A wrong rm -rf, a stray git reset --hard, a pip install into your<br>system: the sandbox turns these from incidents into errors.

s claude # run Claude Code, confined to the current repo (setup below)

It's one short, auditable shell script around macOS sandbox-exec (the Seatbelt<br>sandbox). The agent gets read-write access to your working copy and the bare minimum to<br>run itself and your tests; everything else is denied by default and opened only when you<br>ask.

Native, in place — the agent edits your real working copy with your real macOS<br>toolchain. No Linux guest, no copied files, no syncing changes back.

Lightweight — a sandboxed process, not a machine: no VM to boot, no image, no<br>daemon; nothing to install beyond one script.

OS-enforced — the kernel, not the agent, decides what it can touch, so you can let<br>it run unattended in skip-permissions mode.

Auditable — read the one script before you trust it; --print shows exactly what<br>any invocation grants, and DESIGN.md explains how it works.

Threat model

In scope: the agent runs the wrong command — rm -rf in the wrong place,<br>git reset --hard, clobbering files outside the task, installing junk system-wide.<br>sandfence turns these from incidents into errors.

Out of scope: a malicious agent, prompt injection, or a poisoned dependency<br>actively trying to escape or exfiltrate. sandbox-exec shares your kernel and user<br>account — it's a guardrail, not a containment boundary. The network is open and your<br>working copy is readable, so code the agent runs (npm install, a build hook) can<br>read secrets in your repo and send them out. For untrusted code, use a VM or a separate<br>user account.

Setup

Requires macOS on Apple Silicon . Clone it, then make a short s wrapper so daily<br>use is just s claude:

~/.local/bin/s # Clone — and read it; it's a security tool<br>git clone https://github.com/sheremetyev/sandfence ~/.config/sandfence

# A short `s` wrapper with the toolchains (and extra paths) you use day to day<br>cat > ~/.local/bin/s 'EOF'<br>#!/bin/sh<br>exec ~/.config/sandfence/sandfence.sh --rust --node --python "$@"<br>EOF<br>chmod +x ~/.local/bin/s

s is yours to tune: keep only the presets you use, and add -r DIR / -w DIR for<br>paths you reach for often. Each preset and grant is a real widening of the sandbox.

Auth (once). Each agent keeps its own token in a file the sandbox grants — never the<br>login Keychain, never your shell environment.

Claude Code — run s claude, then /login; paste the printed URL into your<br>browser (the sandbox can't open one). It writes ~/.claude/.credentials.json and<br>refreshes it from then on.

Codex — run codex login once (anywhere); its token lives in ~/.codex/auth.json,<br>which the sandbox reads.

What the agent can touch

Read-write<br>the current directory — your working copy

Read-only<br>its own .git / .jj — you drive version control outside the sandbox; the agent can't commit or rewrite history

Denied<br>the rest of $HOME — ~/.ssh, ~/.aws, gh/glab tokens, the login Keychain, ~/.gitconfig credentials, other repos

Widen it explicitly: -r PATH / -w PATH add a directory or file, and the<br>--rust / --node / --python presets grant build caches read-write while keeping<br>registry tokens and PATH-plant vectors denied. --print shows exactly what an<br>invocation grants; DESIGN.md explains why each grant is there.

Limitations

macOS on Apple Silicon , default toolchains (rustup, nvm + stock npm, Apple<br>python3). Homebrew, pyenv, pnpm,...

sandbox agent sandfence claude read macos

Related Articles