claudebox/claudebox.sh

109 lines
3 KiB
Bash

# Parse claudebox flags
SKIP_AUDIT=false
DRY_RUN=false
CHECK_MODE=false
SHELL_MODE=false
CLAUDE_ARGS=()
while (( $# > 0 )); do
case "$1" in
--yes|-y) SKIP_AUDIT=true ;;
--dry-run) DRY_RUN=true ;;
--check) CHECK_MODE=true ;;
--shell) SHELL_MODE=true ;;
--) shift; CLAUDE_ARGS+=("$@"); break ;;
*) CLAUDE_ARGS+=("$1") ;;
esac
shift
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" "${CLAUDE_ARGS[@]}")
else
SANDBOX_CMD=("$CLAUDE_BIN" --dangerously-skip-permissions "${CLAUDE_ARGS[@]}")
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[@]}"