Claude Code Simple Integration Plan
Purpose: Practical implementation guide for integrating Claude Code into Sasha using API key authentication
Created: 2025-01-09
Approach: Token-based authentication (proven by multiple open-source projects)
Overview
This document outlines a simple, proven approach to integrate Claude Code CLI into Sasha's Docker environment using API key authentication. This replaces the complex OAuth bridge pattern with a straightforward token-based approach that actually works.
Why This Approach Works
Based on research of successful implementations:
- claude-yolo: Uses
ANTHROPIC_API_KEYenvironment variable - claude-docker: Mounts credentials from host
- Zeeno-atl/claude-code: Simple API key in Docker run command
- Issue #551 fixed: Non-interactive authentication now works (v0.2.59+)
Authentication Method: API Key
How It Works
- User provides their Anthropic API key
- Key is passed to Docker container via environment variable
- Claude Code CLI uses the key automatically
- No OAuth, no popups, no complexity
Getting an API Key
Users can get their API key from: https://console.anthropic.com/settings/keys
Implementation Components
1. Docker Configuration
Update Dockerfile
# Add to the runner stage in Dockerfile
RUN npm install -g @anthropic-ai/claude-code@latest
# Create Claude config directory
RUN mkdir -p /home/nodejs/.claude \
&& chown -R nodejs:nodejs /home/nodejs/.claude
# Set Claude home directory
ENV CLAUDE_HOME=/home/nodejs/.claude
Update docker-compose.test.yml
environment:
# Add Claude API key (provided by user)
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
# Claude configuration
CLAUDE_HOME: /home/nodejs/.claude
volumes:
# Optional: Mount host Claude config if it exists
- ~/.claude:/home/nodejs/.claude:ro
2. Simple Setup UI Component
File: src/components/ClaudeSetup.jsx
import React, { useState } from 'react';
const ClaudeSetup = ({ onComplete }) => {
const [apiKey, setApiKey] = useState('');
const [testing, setTesting] = useState(false);
const [error, setError] = useState('');
const testApiKey = async () => {
setTesting(true);
setError('');
try {
// Simple validation - check if key format is correct
if (!apiKey.startsWith('sk-ant-')) {
throw new Error('Invalid API key format');
}
// Store in localStorage for Docker startup
localStorage.setItem('ANTHROPIC_API_KEY', apiKey);
onComplete(apiKey);
} catch (err) {
setError(err.message);
} finally {
setTesting(false);
}
};
return (
<div className="claude-setup p-6 max-w-md mx-auto">
<h2 className="text-2xl font-bold mb-4">Connect Claude Code</h2>
<p className="mb-4 text-gray-600">
Enter your Anthropic API key to enable Claude Code features.
</p>
<input
type="password"
value={apiKey}
onChange={(e) => setApiKey(e.target.value)}
placeholder="sk-ant-..."
className="w-full p-2 border rounded mb-4"
/>
{error && (
<p className="text-red-500 mb-4">{error}</p>
)}
<button
onClick={testApiKey}
disabled={!apiKey || testing}
className="w-full bg-blue-600 text-white p-2 rounded hover:bg-blue-700 disabled:opacity-50"
>
{testing ? 'Validating...' : 'Connect Claude'}
</button>
<a
href="https://console.anthropic.com/settings/keys"
target="_blank"
rel="noopener noreferrer"
className="block text-center mt-4 text-blue-600 hover:underline"
>
Get your API key β
</a>
</div>
);
};
export default ClaudeSetup;
3. Docker Startup Script
File: docker-entrypoint.sh
#!/bin/bash
# Check if API key is provided
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "β οΈ Warning: ANTHROPIC_API_KEY not set"
echo "Claude Code features will not be available"
else
echo "β
Claude Code API key configured"
# Test Claude CLI is available
if command -v claude &> /dev/null; then
echo "β
Claude Code CLI installed"
# Set up Claude configuration if needed
claude --version
else
echo "β Claude Code CLI not found"
fi
fi
# Start the application
exec "$@"
4. Testing Script for Docker
File: docker-test-claude.sh
#!/bin/bash
# Test Claude Code in Docker with API key
echo "π Testing Claude Code with API key..."
# Check if API key is set
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "Please set ANTHROPIC_API_KEY environment variable"
echo "export ANTHROPIC_API_KEY='your-key-here'"
exit 1
fi
# Run Docker with Claude test
docker compose -f docker-compose.test.yml run --rm \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
sasha-studio-test \
claude --version
echo "β
Claude Code test complete"
Implementation Steps
Phase 1: Docker Setup (30 minutes)
- Update Dockerfile to install Claude Code CLI
- Add environment variables to docker-compose.test.yml
- Create docker-entrypoint.sh script
- Test Claude CLI installation in container
Phase 2: UI Component (1 hour)
- Create ClaudeSetup.jsx component
- Add to onboarding flow after organization setup
- Store API key securely in browser
- Pass to Docker when starting container
Phase 3: Integration (1 hour)
- Modify docker-test.sh to accept API key
- Update backend to handle Claude commands
- Test end-to-end flow
- Document user instructions
Phase 4: Testing (30 minutes)
- Test with valid API key
- Test with invalid API key
- Test persistence across container restarts
- Test Claude commands execution
Security Considerations
API Key Handling
- Never commit API keys to git
- Store in environment variables only
- Don't log API keys
- Use password input fields in UI
- Clear from memory after use
Docker Security
- Run as non-root user (nodejs)
- API key only in runtime environment
- Not baked into Docker image
- Optional read-only mount of host credentials
User Instructions
For Docker Testing
Get your API key:
- Go to https://console.anthropic.com/settings/keys
- Create a new API key
- Copy the key (starts with
sk-ant-)
Set environment variable:
export ANTHROPIC_API_KEY='your-key-here'Start Docker test environment:
./docker-test.shEnter API key when prompted in the UI
For Local Development
Install Claude Code locally:
npm install -g @anthropic-ai/claude-codeSet API key:
export ANTHROPIC_API_KEY='your-key-here'Test it works:
claude --version
Testing Checklist
- Claude Code installs in Docker container
- API key environment variable passes correctly
- Claude CLI responds to commands
- UI component validates API key format
- API key persists across container restarts
- Error handling for invalid keys
- Documentation is clear for users
Success Criteria
- Simple Setup: User provides API key once
- No OAuth Complexity: No popups, callbacks, or browser flows
- Works in Docker: Claude Code runs in container
- Secure: API key handled safely
- Documented: Clear instructions for users
Comparison with Complex OAuth Plan
| Aspect | OAuth Plan | Simple API Key |
|---|---|---|
| Lines of Code | 900+ | ~100 |
| Components | 6 new services | 1 UI component |
| Complexity | High | Low |
| Time to Implement | 2-3 weeks | 2-3 hours |
| Proven to Work | Theoretical | Yes (multiple projects) |
| User Experience | Complex flow | Enter key once |
References
- Claude API Keys
- Claude Code npm package
- Issue #551 (fixed)
- Working examples:
Next Steps
- Immediate: Implement Docker changes
- Today: Create UI component
- Tomorrow: Test end-to-end
- Future: Consider OAuth for enterprise users
This simple approach will get Claude Code working in Docker TODAY, not in 2-3 weeks.