{"slug": "show-hn-minimal-native-macos-sandbox-for-claude-and-codex", "title": "Show HN: Minimal native macOS sandbox for Claude and Codex", "summary": "A developer released Sandfence, a minimal native macOS sandbox script that confines coding agents like Claude Code and Codex to a single repository using the kernel's Seatbelt sandbox. The tool prevents agents from executing destructive commands like `rm -rf` or `git reset --hard` outside the working copy, turning potential incidents into errors while allowing read-write access only to the current directory. Designed for macOS on Apple Silicon, the lightweight script requires no VM or daemon and enforces restrictions at the OS level, enabling unattended agent operation in skip-permissions mode.", "body_md": "Run a coding agent — **Claude Code** or **Codex** — on a repo in its own\n\"skip-permissions\" mode, while the **macOS sandbox**, not the agent, enforces what it\ncan touch. A wrong `rm -rf`\n\n, a stray `git reset --hard`\n\n, a `pip install`\n\ninto your\nsystem: the sandbox turns these from incidents into errors.\n\n```\ns claude          # run Claude Code, confined to the current repo (setup below)\n```\n\nIt's one short, auditable shell script around macOS `sandbox-exec`\n\n(the Seatbelt\nsandbox). The agent gets read-write access to your working copy and the bare minimum to\nrun itself and your tests; everything else is denied by default and opened only when you\nask.\n\n**Native, in place**— the agent edits your real working copy with your real macOS 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 daemon; nothing to install beyond one script.** OS-enforced**— the kernel, not the agent, decides what it can touch, so you can let it run unattended in skip-permissions mode.** Auditable**— read the one script before you trust it;`--print`\n\nshows exactly what any invocation grants, and[DESIGN.md](/sheremetyev/sandfence/blob/main/DESIGN.md)explains how it works.\n\n**In scope:** the agent runs the *wrong* command — `rm -rf`\n\nin the wrong place,\n`git reset --hard`\n\n, clobbering files outside the task, installing junk system-wide.\nsandfence turns these from incidents into errors.\n\n**Out of scope:** a *malicious* agent, prompt injection, or a poisoned dependency\nactively trying to escape or exfiltrate. `sandbox-exec`\n\nshares your kernel and user\naccount — it's a guardrail, not a containment boundary. The network is open and your\nworking copy is readable, so code the agent runs (`npm install`\n\n, a build hook) *can*\nread secrets in your repo and send them out. For untrusted code, use a VM or a separate\nuser account.\n\nRequires **macOS on Apple Silicon**. Clone it, then make a short `s`\n\nwrapper so daily\nuse is just `s claude`\n\n:\n\n```\n# Clone — and read it; it's a security tool\ngit clone https://github.com/sheremetyev/sandfence ~/.config/sandfence\n\n# A short `s` wrapper with the toolchains (and extra paths) you use day to day\ncat > ~/.local/bin/s <<'EOF'\n#!/bin/sh\nexec ~/.config/sandfence/sandfence.sh --rust --node --python \"$@\"\nEOF\nchmod +x ~/.local/bin/s\n```\n\n`s`\n\nis yours to tune: keep only the presets you use, and add `-r DIR`\n\n/ `-w DIR`\n\nfor\npaths you reach for often. Each preset and grant is a real widening of the sandbox.\n\n**Auth (once).** Each agent keeps its own token in a file the sandbox grants — never the\nlogin Keychain, never your shell environment.\n\n**Claude Code**— run`s claude`\n\n, then`/login`\n\n; paste the printed URL into your browser (the sandbox can't open one). It writes`~/.claude/.credentials.json`\n\nand refreshes it from then on.**Codex**— run`codex login`\n\nonce (anywhere); its token lives in`~/.codex/auth.json`\n\n, which the sandbox reads.\n\nRead-write |\nthe current directory — your working copy |\nRead-only |\nits own `.git` / `.jj` — you drive version control outside the sandbox; the agent can't commit or rewrite history |\nDenied |\nthe rest of `$HOME` — `~/.ssh` , `~/.aws` , `gh` /`glab` tokens, the login Keychain, `~/.gitconfig` credentials, other repos |\n\nWiden it explicitly: ** -r PATH** /\n\n**add a directory or file, and the**\n\n`-w PATH`\n\n**presets grant build caches read-write while keeping registry tokens and PATH-plant vectors denied.**\n\n`--rust`\n\n/ `--node`\n\n/ `--python`\n\n**shows exactly what an invocation grants;**\n\n`--print`\n\n[DESIGN.md](/sheremetyev/sandfence/blob/main/DESIGN.md)explains why each grant is there.\n\n**macOS on Apple Silicon**, default toolchains (`rustup`\n\n,`nvm`\n\n+ stock`npm`\n\n, Apple`python3`\n\n). Homebrew, pyenv, pnpm, and yarn aren't auto-detected — grant them with`-r`\n\n/`-w`\n\n.— only the CLI is deprecated; the Seatbelt engine under it still powers the macOS App Sandbox and Chrome's renderer sandbox, so it isn't going away. A future macOS could change the CLI.`sandbox-exec`\n\nis deprecated by Apple (2017) but fully functional`/tmp`\n\nand`/var/folders`\n\nare read-write wholesale — don't expect repo isolation there.- Under\n**jj**,`.jj`\n\nis read-only; run read-only commands as`jj --ignore-working-copy …`\n\n.\n\n`./test.sh ~/sandfence-tests`\n\nruns real commands *inside* the sandbox and asserts each\nallow/deny — so you verify what's granted, not just read it. Use a real dir (not `/tmp`\n\n),\nand run it in a plain shell (`sandbox-exec`\n\ncan't nest).\n\nMIT — see [LICENSE](/sheremetyev/sandfence/blob/main/LICENSE).", "url": "https://wpnews.pro/news/show-hn-minimal-native-macos-sandbox-for-claude-and-codex", "canonical_source": "https://github.com/sheremetyev/sandfence", "published_at": "2026-06-06 14:53:04+00:00", "updated_at": "2026-06-06 15:19:04.348496+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "ai-safety", "ai-products"], "entities": ["Claude Code", "Codex", "macOS", "sandfence"], "alternates": {"html": "https://wpnews.pro/news/show-hn-minimal-native-macos-sandbox-for-claude-and-codex", "markdown": "https://wpnews.pro/news/show-hn-minimal-native-macos-sandbox-for-claude-and-codex.md", "text": "https://wpnews.pro/news/show-hn-minimal-native-macos-sandbox-for-claude-and-codex.txt", "jsonld": "https://wpnews.pro/news/show-hn-minimal-native-macos-sandbox-for-claude-and-codex.jsonld"}}