claudebox/claudebox.sh
Christopher Mühl 613d015cc1
fix: SHELL path, PATH isolation, --shell flag, nix-claude-code input
- Resolve SHELL to nix store bash path (was /bin/bash which doesn't exist in sandbox)
- Inject clean SANDBOX_PATH via makeBinPath (was leaking entire host PATH)
- Add --shell flag to drop into sandboxed bash for manual verification
- Use nix-claude-code flake for claude-code binary instead of host PATH discovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 14:59:43 +02:00

100 lines
2.7 KiB
Bash

# Parse claudebox flags
SHELL_MODE=false
for arg in "$@"; do
case "$arg" in
--shell) SHELL_MODE=true; shift; break ;;
--) shift; break ;;
*) break ;;
esac
done
# SANDBOX_PATH is injected by flake.nix via makeBinPath (only runtimeInputs, no host PATH)
# Resolve binary paths from runtimeInputs
SANDBOX_BASH="$(command -v bash)"
CLAUDE_BIN="$(command -v claude)"
# Record CWD
CWD=$(pwd)
# Ensure ~/.claudebox exists
mkdir -p "$HOME/.claudebox"
# Generate minimal .gitconfig (D-05)
GIT_NAME=$(git config --global user.name 2>/dev/null || echo "Claude User")
GIT_EMAIL=$(git config --global user.email 2>/dev/null || echo "claude@localhost")
GITCONFIG_TMP=$(mktemp)
trap 'rm -f "$GITCONFIG_TMP"' EXIT
cat > "$GITCONFIG_TMP" <<GITEOF
[user]
name = $GIT_NAME
email = $GIT_EMAIL
[safe]
directory = *
GITEOF
# Build environment --setenv args array (D-03, D-04, SAND-02, SAND-03)
# Sandbox-generated vars -- set directly, never from host
ENV_ARGS=(
--setenv HOME "$HOME"
--setenv USER "$USER"
--setenv PATH "$SANDBOX_PATH"
--setenv SHELL "$SANDBOX_BASH"
--setenv TMPDIR /tmp
--setenv XDG_RUNTIME_DIR /tmp
--setenv NIX_SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt
--setenv SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt
)
# Allowlisted host vars -- only pass if set on host
HOST_ALLOWLIST=(TERM EDITOR LANG LC_ALL ANTHROPIC_API_KEY)
for var in "${HOST_ALLOWLIST[@]}"; do
if [[ -v "$var" ]]; then
ENV_ARGS+=(--setenv "$var" "${!var}")
fi
done
# CLAUDEBOX_EXTRA_ENV escape hatch (D-03, comma-separated)
if [[ -v CLAUDEBOX_EXTRA_ENV ]]; then
IFS=',' read -ra EXTRAS <<< "$CLAUDEBOX_EXTRA_ENV"
for var in "${EXTRAS[@]}"; do
var="${var// /}" # trim whitespace
if [[ -n "$var" ]] && [[ -v "$var" ]]; then
ENV_ARGS+=(--setenv "$var" "${!var}")
fi
done
fi
# Build sandbox command
if [[ "$SHELL_MODE" == true ]]; then
SANDBOX_CMD=("$SANDBOX_BASH" "$@")
else
SANDBOX_CMD=("$CLAUDE_BIN" --dangerously-skip-permissions "$@")
fi
# exec bwrap (SAND-04 through SAND-15, UX-06, D-01)
exec bwrap \
--clearenv \
"${ENV_ARGS[@]}" \
--tmpfs / \
--proc /proc \
--dev /dev \
--tmpfs /tmp \
--ro-bind /nix/store /nix/store \
--bind /nix/var/nix /nix/var/nix \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--ro-bind /etc/ssl /etc/ssl \
--ro-bind /etc/static /etc/static \
--ro-bind /etc/passwd /etc/passwd \
--ro-bind /etc/group /etc/group \
--ro-bind /etc/hosts /etc/hosts \
--ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \
--ro-bind /etc/nix /etc/nix \
--symlink "$(readlink -f "$(command -v env)")" /usr/bin/env \
--tmpfs "$HOME" \
--bind "$HOME/.claudebox" "$HOME/.claude" \
--ro-bind "$GITCONFIG_TMP" "$HOME/.gitconfig" \
--bind "$CWD" "$CWD" \
--chdir "$CWD" \
-- "${SANDBOX_CMD[@]}"