sha256:d3f0c8539c01163ea84a74d45def987665fc55251d5008053c4e048cf62682af
Last pushed
7 days by dockerpublicbot
Type
Sandbox Kit
Manifest digest
sha256:d3f0c8539c01163ea84a74d45def987665fc55251d5008053c4e048cf62682af
schemaVersion: "2"
kind: sandbox
name: claude
version: 1.0.0
displayName: Claude Code
description: Anthropic's Claude Code, with API-key and subscription sign-in both resolved by the sandbox proxy.
sandbox:
image: docker.io/sbx/claude-image:latest
entrypoint:
- claude
command:
default:
- --dangerously-skip-permissions
interactive:
- --dangerously-skip-permissions
agentInstructions:
filename: CLAUDE.md
content: |
## Claude Code: Environment Persistence
The `CLAUDE_ENV_FILE` environment variable is set to `/etc/sandbox-persistent.sh`.
According to [Claude Code Documentation](https://code.claude.com/docs/en/settings#bash-tool-behavior):
> **CLAUDE_ENV_FILE**
>
> If set, this file will be sourced before each Bash command execution. This allows environment variables to persist across multiple Bash tool invocations.
This means `/etc/sandbox-persistent.sh` is sourced before every Bash tool call you make. Any `export` statements you append to this file will be available in all subsequent commands without needing a login shell.
### Shell Completions Must NOT Be in CLAUDE_ENV_FILE
**NEVER add shell completion scripts to `/etc/sandbox-persistent.sh`.**
`CLAUDE_ENV_FILE` is sourced **before every single bash command execution**, not just during shell initialization. Completion scripts rely on special variables (`COMP_WORDS`, `COMP_CWORD`, `COMPREPLY`) that only exist during tab-completion contexts.
#### WRONG - Will Break Bash
```bash
# DO NOT ADD THESE TO /etc/sandbox-persistent.sh
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
[[ -s "$SDKMAN_DIR/etc/bash_completion.sh" ]] && source "$SDKMAN_DIR/etc/bash_completion.sh"
```
#### CORRECT - Only Load Core Functionality
```bash
# ONLY add the main initialization scripts
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
export SDKMAN_DIR="$HOME/.sdkman"
[[ -s "$SDKMAN_DIR/bin/sdkman-init.sh" ]] && source "$SDKMAN_DIR/bin/sdkman-init.sh"
```
#### Symptoms of Broken Shell
When completion scripts are incorrectly added:
- All bash commands return no output (silent failure)
- `echo`, `pwd`, and other basic commands produce no results
- The bash tool becomes completely unusable
#### Solution
If you accidentally added completion scripts and broke the shell:
1. Remove the completion line(s) from `/etc/sandbox-persistent.sh`
2. Exit and restart the Claude Code session
3. Verify with `echo "test"` that bash works again
permissions:
network:
allow:
- api.anthropic.com
- console.anthropic.com
- claude.ai
- mcp-proxy.anthropic.com
- platform.claude.com
- downloads.claude.ai
- claude.com
- code.claude.com
- bridge.claudeusercontent.com
- archive.ubuntu.com
- security.ubuntu.com
- ports.ubuntu.com
- download.docker.com
volumes:
- path: /home/agent/.claude/projects
size: 2g
- path: /home/agent/.claude/sessions
size: 512m
- path: /home/agent/.claude/todos
size: 512m
- path: /home/agent/.claude/shell-snapshots
size: 512m
- path: /home/agent/.claude/statsig
size: 512m
credentials:
- service: anthropic
apiKey:
name: ANTHROPIC_API_KEY
inject:
- domain: api.anthropic.com
header: x-api-key
format: '%s'
- domain: console.anthropic.com
header: x-api-key
format: '%s'
- domain: claude.ai
header: x-api-key
format: '%s'
- domain: mcp-proxy.anthropic.com
header: x-api-key
format: '%s'
oauth:
tokenEndpoint:
host: platform.claude.com
path: /v1/oauth/token
sentinels:
accessToken: sk-ant-oat01-proxy-managed
refreshToken: sk-ant-ort01-proxy-managed
credentialFile:
path: ~/.claude/.credentials.json
template: '{"claudeAiOauth":{"accessToken":"{{.AccessToken}}","refreshToken":"{{.RefreshToken}}","expiresAt":{{.ExpiresAt}},"scopes":{{.ScopesJSON}}}{{if .PrimaryApiKey}},"primaryApiKey":"{{.PrimaryApiKey}}"{{end}}}'
skipIfEnv:
- ANTHROPIC_API_KEY
environment:
variables:
DISABLE_ERROR_REPORTING: "1"
DISABLE_TELEMETRY: "1"
IS_SANDBOX: "1"
setup:
install:
- command: |
set -e
ws="${WORKSPACE_DIR:-/}"
esc=$(printf '%s' "$ws" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g; s/\r/\\r/g')
projects="\"/\": { \"hasTrustDialogAccepted\": true }"
[ "$ws" = "/" ] || projects="$projects, \"$esc\": { \"hasTrustDialogAccepted\": true }"
printf '%s\n' "{
\"bypassPermissionsModeAccepted\": true,
\"hasCompletedOnboarding\": true,
\"projects\": { $projects }
}" > /home/agent/.claude.json
chown agent:agent /home/agent/.claude.json
user: "0"
description: Seed Claude bypass/trust flags (root; overwrites image-shipped file)
- command: |
set -e
mkdir -p /home/agent/.claude
HELPER=''
if [ "${SBX_CRED_ANTHROPIC_MODE:-none}" != none ]; then
HELPER=' "apiKeyHelper": "echo proxy-managed",
'
fi
printf '%s' "{
\"themeId\": 1,
\"alwaysThinkingEnabled\": true,
${HELPER} \"permissions\": { \"defaultMode\": \"bypassPermissions\" },
\"bypassPermissionsModeAccepted\": true,
\"skipDangerousModePermissionPrompt\": true
}
" > /home/agent/.claude/settings.json
user: agent
description: Seed Claude settings.json from SBX_CRED_ANTHROPIC_MODE
- command: |
set -e
[ -n "$MCP_GATEWAY_URL" ] || exit 0
export PATH="$HOME/.local/bin:$HOME/.claude/local:$PATH"
claude mcp add mcp-gateway "$MCP_GATEWAY_URL" \
--transport http \
--scope user \
--header "Authorization: Bearer $MCP_SENTINEL_TOKEN_NAME" || true
user: agent
description: Register the sandbox MCP gateway with claude (install-time, race-free)
startup:
- command:
- sh
- -c
- chown -R agent:agent /home/agent/.claude/projects /home/agent/.claude/sessions /home/agent/.claude/todos /home/agent/.claude/shell-snapshots /home/agent/.claude/statsig 2>/dev/null || true
user: "0"
description: Re-own claude session-state volume mount roots to agent (block-volume mkfs trap)
- command:
- sh
- -c
- '{ command -v apt-get && apt-get update -qq -y || true; } >/dev/null 2>&1 </dev/null &'
user: root
description: Update apt package cache in background
- command:
- sh
- -c
- |
set -e
[ -n "$MCP_GATEWAY_URL" ] || exit 0
export PATH="$HOME/.local/bin:$HOME/.claude/local:$PATH"
claude mcp add mcp-gateway "$MCP_GATEWAY_URL" \
--transport http \
--scope user \
--header "Authorization: Bearer $MCP_SENTINEL_TOKEN_NAME" || true
user: agent
description: Register the sandbox MCP gateway with claude (startup fallback)