Implement authentication persistence for Claude Docker
- Add persistent volume mount for Claude home directory (~/.claude) - Create non-root user in Docker container for better security - Mount host ~/.claude-docker/claude-home to container ~/.claude - Update install script to create claude-home directory - Check for existing credentials on startup - Authentication tokens now persist across container restarts
This commit is contained in:
parent
c99bc9c561
commit
dcc936dc10
14
Dockerfile
14
Dockerfile
@ -9,8 +9,13 @@ RUN apt-get update && apt-get install -y \
|
|||||||
curl \
|
curl \
|
||||||
python3 \
|
python3 \
|
||||||
build-essential \
|
build-essential \
|
||||||
|
sudo \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create a non-root user
|
||||||
|
RUN useradd -m -s /bin/bash claude-user && \
|
||||||
|
echo "claude-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
# Create app directory
|
# Create app directory
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@ -24,7 +29,7 @@ ENV PATH="/usr/local/bin:${PATH}"
|
|||||||
RUN npm install -g @twilio-alpha/mcp
|
RUN npm install -g @twilio-alpha/mcp
|
||||||
|
|
||||||
# Create directories for configuration
|
# Create directories for configuration
|
||||||
RUN mkdir -p /app/config /app/.claude
|
RUN mkdir -p /app/config /app/.claude /home/claude-user/.claude
|
||||||
|
|
||||||
# Copy MCP configuration
|
# Copy MCP configuration
|
||||||
COPY config/mcp-config.json /app/config/
|
COPY config/mcp-config.json /app/config/
|
||||||
@ -33,11 +38,18 @@ COPY config/mcp-config.json /app/config/
|
|||||||
COPY scripts/startup.sh /app/
|
COPY scripts/startup.sh /app/
|
||||||
RUN chmod +x /app/startup.sh
|
RUN chmod +x /app/startup.sh
|
||||||
|
|
||||||
|
# Set proper ownership
|
||||||
|
RUN chown -R claude-user:claude-user /app /home/claude-user
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER claude-user
|
||||||
|
|
||||||
# Set working directory to mounted volume
|
# Set working directory to mounted volume
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
|
|
||||||
# Environment variables will be passed from host
|
# Environment variables will be passed from host
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
ENV HOME=/home/claude-user
|
||||||
|
|
||||||
# Start both MCP server and Claude Code
|
# Start both MCP server and Claude Code
|
||||||
ENTRYPOINT ["/app/startup.sh"]
|
ENTRYPOINT ["/app/startup.sh"]
|
@ -19,21 +19,62 @@ Building a Docker container that runs Claude Code with full autonomous permissio
|
|||||||
## Next Steps 🎯
|
## Next Steps 🎯
|
||||||
**Phase 2 - Security & Persistence Enhancements:**
|
**Phase 2 - Security & Persistence Enhancements:**
|
||||||
|
|
||||||
### 1. Authentication Persistence (HIGH Priority)
|
### 1. Authentication Persistence (HIGH Priority) - CURRENT FOCUS
|
||||||
- Avoid repeated Claude account logins every session
|
**Problem:** Need to re-login to Claude Code every time container starts
|
||||||
- Research how to persist Claude Code authentication tokens
|
|
||||||
- Investigate mounting Claude authentication data from host
|
|
||||||
- Study Anthropic's dev container auth persistence approach
|
|
||||||
|
|
||||||
### 2. Network Security (High Priority)
|
**Research Findings:**
|
||||||
- Implement firewall to restrict network access (study Anthropic's dev container)
|
- Claude Code stores auth tokens in temporary locations that get cleared
|
||||||
- Whitelist only essential domains:
|
- Known issues: #1222 (persistent auth warnings), #1676 (logout after restart)
|
||||||
- api.anthropic.com (Claude API)
|
- The devcontainer mounts `/home/node/.claude` for config persistence
|
||||||
- api.twilio.com (SMS notifications)
|
- But auth tokens are NOT persisted properly even in devcontainer
|
||||||
- github.com, raw.githubusercontent.com (git operations)
|
|
||||||
- npm registry domains (package management)
|
**Implementation Plan:**
|
||||||
- Common documentation sites (if needed)
|
1. **Mount Claude config directory from host:**
|
||||||
- Block all other outbound connections for security
|
- Create persistent `~/.claude-docker/claude-config` on host
|
||||||
|
- Mount to container's `~/.config/claude` or appropriate location
|
||||||
|
- Preserve authentication tokens between sessions
|
||||||
|
|
||||||
|
2. **Modify startup script to:**
|
||||||
|
- Check for existing auth tokens on container start
|
||||||
|
- Skip login prompt if valid tokens exist
|
||||||
|
- Handle token refresh if needed
|
||||||
|
|
||||||
|
3. **Token storage investigation:**
|
||||||
|
- Find where Claude Code stores auth tokens (likely ~/.config/claude or similar)
|
||||||
|
- Ensure proper permissions on mounted directory
|
||||||
|
- Test token persistence across container restarts
|
||||||
|
|
||||||
|
### 2. Network Security (High Priority) - PLANNED
|
||||||
|
**Implementation based on devcontainer's init-firewall.sh:**
|
||||||
|
|
||||||
|
**Key Components:**
|
||||||
|
1. **Firewall Script Features:**
|
||||||
|
- Uses iptables with default DROP policy
|
||||||
|
- ipset for managing allowed IP ranges
|
||||||
|
- Dynamic IP resolution for allowed domains
|
||||||
|
- Verification of connectivity post-setup
|
||||||
|
|
||||||
|
2. **Allowed Domains Configuration:**
|
||||||
|
```yaml
|
||||||
|
allowed_domains:
|
||||||
|
- api.anthropic.com # Claude API
|
||||||
|
- api.twilio.com # SMS notifications
|
||||||
|
- github.com # Git operations
|
||||||
|
- raw.githubusercontent.com
|
||||||
|
- registry.npmjs.org # Package management
|
||||||
|
- pypi.org # Python packages
|
||||||
|
|
||||||
|
blocked_paths: # File system restrictions
|
||||||
|
- /etc
|
||||||
|
- /root
|
||||||
|
- ~/.ssh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **User-Friendly Setup:**
|
||||||
|
- Simple YAML config file for rules
|
||||||
|
- Easy enable/disable of firewall
|
||||||
|
- Logging of blocked attempts
|
||||||
|
- Graceful degradation if firewall fails
|
||||||
|
|
||||||
### 3. Shell History Persistence (Medium Priority)
|
### 3. Shell History Persistence (Medium Priority)
|
||||||
- Add persistent bash/zsh history between container sessions
|
- Add persistent bash/zsh history between container sessions
|
||||||
@ -62,6 +103,7 @@ Building a Docker container that runs Claude Code with full autonomous permissio
|
|||||||
- Simplified settings.json to only include MCP config (no redundant allowedTools)
|
- Simplified settings.json to only include MCP config (no redundant allowedTools)
|
||||||
- **NEW:** Adding firewall for network security
|
- **NEW:** Adding firewall for network security
|
||||||
- **NEW:** Adding shell history persistence like Claude dev container
|
- **NEW:** Adding shell history persistence like Claude dev container
|
||||||
|
- **NEW (2024-12-06):** Focus on auth persistence first before firewall implementation
|
||||||
|
|
||||||
## Notes & Context
|
## Notes & Context
|
||||||
- Repository: https://github.com/VishalJ99/claude-docker
|
- Repository: https://github.com/VishalJ99/claude-docker
|
||||||
@ -78,6 +120,10 @@ Building a Docker container that runs Claude Code with full autonomous permissio
|
|||||||
- Added explicit PATH for npm global binaries
|
- Added explicit PATH for npm global binaries
|
||||||
- Maintained separation: `claude-docker` (host) vs `claude` (container)
|
- Maintained separation: `claude-docker` (host) vs `claude` (container)
|
||||||
- **Current working state:** Container launches successfully, authentication required each session
|
- **Current working state:** Container launches successfully, authentication required each session
|
||||||
|
- **Auth Persistence Research (2024-12-06):**
|
||||||
|
- Claude Code has known issues with auth persistence
|
||||||
|
- Tokens stored in temp locations that get cleared
|
||||||
|
- Need to find exact token storage location and persist it
|
||||||
|
|
||||||
## Quick References
|
## Quick References
|
||||||
- Install: `./scripts/install.sh`
|
- Install: `./scripts/install.sh`
|
||||||
|
@ -38,12 +38,16 @@ if ! docker images | grep -q "claude-docker"; then
|
|||||||
docker build -t claude-docker:latest "$PROJECT_ROOT"
|
docker build -t claude-docker:latest "$PROJECT_ROOT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure the claude-home directory exists
|
||||||
|
mkdir -p "$HOME/.claude-docker/claude-home"
|
||||||
|
|
||||||
# Run Claude Code in Docker
|
# Run Claude Code in Docker
|
||||||
echo "Starting Claude Code in Docker..."
|
echo "Starting Claude Code in Docker..."
|
||||||
docker run -it --rm \
|
docker run -it --rm \
|
||||||
-v "$CURRENT_DIR:/workspace" \
|
-v "$CURRENT_DIR:/workspace" \
|
||||||
-v "$ENV_FILE:/app/.env:ro" \
|
-v "$ENV_FILE:/app/.env:ro" \
|
||||||
-v "$HOME/.claude-docker/config:/app/.claude:rw" \
|
-v "$HOME/.claude-docker/config:/app/.claude:rw" \
|
||||||
|
-v "$HOME/.claude-docker/claude-home:/home/claude-user/.claude:rw" \
|
||||||
--workdir /workspace \
|
--workdir /workspace \
|
||||||
--name claude-docker-session \
|
--name claude-docker-session \
|
||||||
claude-docker:latest "$@"
|
claude-docker:latest "$@"
|
@ -5,8 +5,9 @@
|
|||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
# Create config directory
|
# Create config directory and claude persistence directory
|
||||||
mkdir -p "$HOME/.claude-docker/config"
|
mkdir -p "$HOME/.claude-docker/config"
|
||||||
|
mkdir -p "$HOME/.claude-docker/claude-home"
|
||||||
|
|
||||||
# Copy example env file if doesn't exist
|
# Copy example env file if doesn't exist
|
||||||
if [ ! -f "$HOME/.claude-docker/.env" ]; then
|
if [ ! -f "$HOME/.claude-docker/.env" ]; then
|
||||||
|
@ -12,6 +12,14 @@ fi
|
|||||||
# Configure Claude Code to use the MCP server
|
# Configure Claude Code to use the MCP server
|
||||||
export CLAUDE_MCP_CONFIG=/app/config/mcp-config.json
|
export CLAUDE_MCP_CONFIG=/app/config/mcp-config.json
|
||||||
|
|
||||||
|
# Check for existing authentication
|
||||||
|
if [ -f "$HOME/.claude/.credentials.json" ]; then
|
||||||
|
echo "Found existing Claude authentication"
|
||||||
|
else
|
||||||
|
echo "No existing authentication found - you will need to log in"
|
||||||
|
echo "Your login will be saved for future sessions"
|
||||||
|
fi
|
||||||
|
|
||||||
# Start Claude Code with permissions bypass
|
# Start Claude Code with permissions bypass
|
||||||
echo "Starting Claude Code..."
|
echo "Starting Claude Code..."
|
||||||
if [ -n "$TWILIO_ACCOUNT_SID" ] && [ -n "$TWILIO_API_KEY" ]; then
|
if [ -n "$TWILIO_ACCOUNT_SID" ] && [ -n "$TWILIO_API_KEY" ]; then
|
||||||
@ -19,5 +27,4 @@ if [ -n "$TWILIO_ACCOUNT_SID" ] && [ -n "$TWILIO_API_KEY" ]; then
|
|||||||
else
|
else
|
||||||
echo "No Twilio credentials found, MCP features will be unavailable"
|
echo "No Twilio credentials found, MCP features will be unavailable"
|
||||||
fi
|
fi
|
||||||
echo "Note: If prompted for authentication, follow the interactive prompts"
|
|
||||||
exec claude --dangerously-skip-permissions "$@"
|
exec claude --dangerously-skip-permissions "$@"
|
Loading…
Reference in New Issue
Block a user