Skip to content

Commit 57394a8

Browse files
sssemilclaude
andcommitted
Add macOS support using sandbox-exec
- install.sh: Detect OS and install appropriate wrapper - macOS uses sandbox-exec with Seatbelt profile - Linux continues to use firejail - Update docs to reflect multi-platform support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b091cdb commit 57394a8

3 files changed

Lines changed: 57 additions & 10 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# safe-claude
22

3-
Run [Claude Code](https://docs.anthropic.com/en/docs/claude-code) in a firejail sandbox with a read-only filesystem.
3+
Run [Claude Code](https://docs.anthropic.com/en/docs/claude-code) in a sandbox with a read-only filesystem.
44

55
## Install
66

@@ -19,8 +19,9 @@ Only the current directory and Claude config files are writable. Everything else
1919

2020
## Requirements
2121

22-
- Linux
23-
- [firejail](https://firejail.wordpress.com/)
22+
- Linux or macOS
23+
- Linux: [firejail](https://firejail.wordpress.com/)
24+
- macOS: sandbox-exec (built-in)
2425
- Node.js + npm
2526

2627
## License

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ <h1>safe-claude</h1>
148148
<span class="feature">Project isolation</span>
149149
</div>
150150

151-
<p class="note">Linux only. Requires firejail, node, npm.</p>
151+
<p class="note">Linux & macOS. Requires node, npm. Linux needs firejail.</p>
152152
</div>
153153

154154
<footer>

install.sh

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ set -euo pipefail
33

44
echo "Installing Claude Code + safe-claude"
55

6-
# Linux only
7-
if [ "$(uname -s)" != "Linux" ]; then
8-
echo "error: Linux required"
9-
exit 1
10-
fi
6+
# OS detection
7+
OS="$(uname -s)"
8+
case "$OS" in
9+
Linux|Darwin) ;;
10+
*) echo "error: Linux or macOS required"; exit 1 ;;
11+
esac
1112

1213
# basic deps
1314
need() {
@@ -45,7 +46,8 @@ CLAUDE_PATH="$(command -v claude || true)"
4546
# install safe-claude
4647
SAFE_CLAUDE="$BIN_DIR/safe-claude"
4748

48-
cat > "$SAFE_CLAUDE" <<'EOF'
49+
if [ "$OS" = "Linux" ]; then
50+
cat > "$SAFE_CLAUDE" <<'EOF'
4951
#!/usr/bin/env bash
5052
set -euo pipefail
5153
@@ -96,6 +98,50 @@ exec firejail "${FIREJAIL_ARGS[@]}" \
9698
"$CLAUDE" --dangerously-skip-permissions
9799
EOF
98100

101+
else
102+
# macOS (Darwin)
103+
cat > "$SAFE_CLAUDE" <<'EOF'
104+
#!/usr/bin/env bash
105+
set -euo pipefail
106+
107+
if [ "$(uname -s)" != "Darwin" ]; then
108+
echo "safe-claude: macOS required"
109+
exit 1
110+
fi
111+
112+
export PATH="$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
113+
CLAUDE="$(command -v claude || true)"
114+
[ -x "$CLAUDE" ] || { echo "safe-claude: claude not found"; exit 1; }
115+
116+
PROJECT_DIR="$(pwd -P)"
117+
CLAUDE_DIR="$HOME/.claude"
118+
119+
# Generate sandbox profile with resolved paths
120+
PROFILE="$(mktemp)"
121+
trap "rm -f '$PROFILE'" EXIT
122+
123+
cat > "$PROFILE" <<SBEOF
124+
(version 1)
125+
(deny default)
126+
(allow network*)
127+
(allow process*)
128+
(allow sysctl-read)
129+
(allow mach-lookup)
130+
(allow file-read*)
131+
(allow file-write* (subpath "$PROJECT_DIR"))
132+
(allow file-write* (subpath "$CLAUDE_DIR"))
133+
(allow file-write* (subpath "/private/tmp"))
134+
(allow file-write* (subpath "/private/var/folders"))
135+
SBEOF
136+
137+
echo "safe-claude: writable paths:"
138+
echo " RW $PROJECT_DIR"
139+
echo " RW $CLAUDE_DIR"
140+
141+
exec sandbox-exec -f "$PROFILE" "$CLAUDE" --dangerously-skip-permissions
142+
EOF
143+
fi
144+
99145
chmod +x "$SAFE_CLAUDE"
100146

101147
echo

0 commit comments

Comments
 (0)