| description | tags | ||||||
|---|---|---|---|---|---|---|---|
Set up Anthropic's official devcontainer for running Claude Code with --dangerously-skip-permissions safely |
|
Set up a secure devcontainer environment based on Anthropic's official reference implementation.
Reference: https://docs.anthropic.com/en/docs/claude-code/devcontainer
First, check the current environment and any existing configuration: !ls -la .devcontainer/ 2>/dev/null || echo "No existing devcontainer configuration" !which docker 2>/dev/null && docker --version || echo "Docker not installed" !which devcontainer 2>/dev/null && devcontainer --version || echo "devcontainer CLI not installed" !echo "ANTHROPIC_API_KEY is $([ -n "$ANTHROPIC_API_KEY" ] && echo 'set' || echo 'NOT SET')"
Based on $ARGUMENTS, perform the appropriate devcontainer operation:
If creating a new devcontainer configuration or no arguments provided:
Create .devcontainer/devcontainer.json:
{
"name": "Claude Code Sandbox",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/devcontainers/features/python:1": {},
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/aws-cli:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:1": {}
},
"postCreateCommand": "npm install -g @anthropic-ai/claude-code && pip install --user boto3 requests",
"remoteEnv": {
"ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}",
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}",
"AWS_ACCESS_KEY_ID": "${localEnv:AWS_ACCESS_KEY_ID}",
"AWS_SECRET_ACCESS_KEY": "${localEnv:AWS_SECRET_ACCESS_KEY}",
"AWS_DEFAULT_REGION": "${localEnv:AWS_DEFAULT_REGION}"
},
"runArgs": [
"--cap-drop=ALL",
"--security-opt=no-new-privileges"
],
"mounts": [],
"customizations": {
"vscode": {
"extensions": [
"anthropic.claude-code"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
}
}
}
}Create .devcontainer/Dockerfile:
# Anthropic's recommended devcontainer for Claude Code
# Reference: https://docs.anthropic.com/en/docs/claude-code/devcontainer
FROM mcr.microsoft.com/devcontainers/base:ubuntu
# Security labels
LABEL org.opencontainers.image.title="Claude Code Sandbox"
LABEL org.opencontainers.image.description="Secure container for running Claude Code with --dangerously-skip-permissions"
LABEL org.opencontainers.image.vendor="Generated by setup-devcontainer.sh"
# Install essential security tools
RUN apt-get update && apt-get install -y \
curl \
ca-certificates \
gnupg \
lsb-release \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Network firewall - only allow specific domains
RUN apt-get update && apt-get install -y iptables dnsutils && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Create firewall setup script (runs at container start)
# Rules are processed in order - first match wins
RUN echo '#!/bin/bash' > /usr/local/bin/setup-firewall.sh && \
echo 'set -e' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -o lo -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p udp --dport 53 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp -d api.anthropic.com --dport 443 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp -d github.com --dport 443 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp -d registry.npmjs.org --dport 443 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp -d pypi.org --dport 443 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp -d files.pythonhosted.org --dport 443 -j ACCEPT' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp --dport 443 -j DROP' >> /usr/local/bin/setup-firewall.sh && \
echo 'iptables -A OUTPUT -p tcp --dport 80 -j DROP' >> /usr/local/bin/setup-firewall.sh && \
chmod +x /usr/local/bin/setup-firewall.sh
# Create non-root user workspace
RUN mkdir -p /workspace && chown vscode:vscode /workspace
WORKDIR /workspace
# Default to non-root user
USER vscode
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -sf https://api.anthropic.com/health || exit 1Key security features:
--cap-drop=ALL: Drops all Linux capabilities--security-opt=no-new-privileges: Prevents privilege escalation- Network firewall: Only allows traffic to allowlisted domains
- No mounts: Isolates from host filesystem
If the user wants to use the automated setup script: !ls -la setup-devcontainer.sh 2>/dev/null || echo "Script not in current directory"
Run the setup script:
# Full setup with recommended security
./setup-devcontainer.sh
# Minimal setup (Node.js and Git only)
./setup-devcontainer.sh --minimal
# Skip network firewall restrictions
./setup-devcontainer.sh --no-network-firewall
# Preview what would be created
./setup-devcontainer.sh --dry-run
# Strict mode for CI (fails if prerequisites missing)
./setup-devcontainer.sh --strict
# Add custom domains for enterprise private registries
./setup-devcontainer.sh --allow-domain internal.registry.com
# Or use environment variable for extra domains
DEVCONTAINER_EXTRA_DOMAINS="internal.registry.com,npm.mycompany.com" ./setup-devcontainer.shIf starting the devcontainer: !docker ps -a | grep -i devcontainer | head -3 || echo "No devcontainer running"
Start commands:
# Using VS Code
# Cmd/Ctrl+Shift+P → "Dev Containers: Reopen in Container"
# Using devcontainer CLI
devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . claude --dangerously-skip-permissionsIf validating the devcontainer security: !cat .devcontainer/devcontainer.json 2>/dev/null | grep -E "(cap-drop|no-new-privileges|mounts)" || echo "Security settings not found" !cat .devcontainer/Dockerfile 2>/dev/null | grep -E "(iptables|DROP)" || echo "Firewall rules not found"
Verify:
-
--cap-drop=ALLis present in runArgs -
--security-opt=no-new-privilegesis present - Network firewall rules block unauthorized outbound traffic
- No host filesystem mounts configured
If cleaning up devcontainer:
# Stop and remove container
devcontainer down --workspace-folder .
# Remove configuration (optional)
rm -rf .devcontainer/| Aspect | Claude's /sandbox |
Devcontainer |
|---|---|---|
| Purpose | Run code snippets safely | Run Claude itself isolated |
| Scope | Ephemeral execution | Persistent dev environment |
| What's isolated | Your code | The entire Claude session |
| Use case | "Test this script" | "Let Claude work autonomously" |
| Flag enabled | N/A | --dangerously-skip-permissions |
Safe for:
- Your own trusted projects
- Development and testing workflows
- CI/CD automation with Claude
Avoid for:
- Untrusted repositories (prompt injection risk)
- Projects with sensitive credentials you haven't reviewed
- Production systems
Remember: Even with isolation, credentials inside the container are accessible to Claude. Only pass credentials you're comfortable with Claude having access to.
# 1. Set API key
export ANTHROPIC_API_KEY="sk-ant-..."
# 2. Run setup script (or create files manually)
./setup-devcontainer.sh
# 3. Open in VS Code and reopen in container
code . && # Cmd+Shift+P → "Dev Containers: Reopen in Container"
# 4. Run Claude with full autonomy
claude --dangerously-skip-permissionsThink step by step about the user's devcontainer needs and provide:
- Environment Assessment: Current setup, Docker availability, existing configuration
- Security Recommendation: Appropriate isolation level based on use case
- Implementation: Create or modify devcontainer configuration
- Validation: Verify security settings are correctly applied
- Usage Instructions: How to start and use the devcontainer
If no specific operation is provided, assess the current environment and help create a secure devcontainer configuration using Anthropic's recommended approach.