Security Best Practices
Harden your Claude Code setup with secrets management, audit logging, and professional security practices.
What you'll accomplish
Implement comprehensive security measures for professional Claude Code usage.
Prerequisites
- Completed previous Claude Code Advanced lessons
- Understanding of environment variables
- Basic security awareness
Security Overview
When using AI coding assistants in professional environments, security is critical. This lesson covers:
- Secrets management
- Audit logging
- Access controls
- Compliance considerations
- Team security policies
Secrets Management
The Golden Rule
Never put secrets in code or prompts.
| Bad | Good |
|---|---|
API_KEY=sk-abc123 in code | Environment variable |
| Passwords in AGENTS.md | Reference to secret manager |
| Tokens in git history | .env file in .gitignore |
| Sharing keys in chat | Per-user credentials |
Environment Variables
The safest approach for local development:
.gitignore for Secrets
Always include:
gitignore# .gitignore # Environment files .env .env.local .env.*.local *.env # Secret files secrets/ *.secret *.pem *.key credentials.json # Claude configuration with secrets .claude/settings.local.json
Pre-Commit Hooks for Secret Detection
Use tools to catch secrets before they're committed:
bash# Install gitleaks brew install gitleaks # macOS # Or download from: https://github.com/gitleaks/gitleaks # Add pre-commit hook cat > .git/hooks/pre-commit << 'EOF' #!/bin/bash gitleaks protect --staged EOF chmod +x .git/hooks/pre-commit
Or use git-secrets:
bash# Install brew install git-secrets # Configure for repo git secrets --install git secrets --register-aws # Catches AWS keys
Audit Logging
Track what Claude Code does for accountability and debugging.
Basic Logging Hook
json{ "hooks": { "pre-execute": { "command": "./scripts/log-action.sh execute '{{command}}'", "failBehavior": "ignore" }, "pre-write": { "command": "./scripts/log-action.sh write '{{file}}'", "failBehavior": "ignore" } } }
With logging script:
bash#!/bin/bash # scripts/log-action.sh ACTION=$1 DETAIL=$2 TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") USER=$(whoami) PROJECT=$(basename $(pwd)) LOG_DIR="$HOME/.claude/audit" mkdir -p "$LOG_DIR" echo "{\"timestamp\":\"$TIMESTAMP\",\"user\":\"$USER\",\"project\":\"$PROJECT\",\"action\":\"$ACTION\",\"detail\":\"$DETAIL\"}" >> "$LOG_DIR/audit.jsonl"
Structured Logging
For better analysis, use JSON Lines format:
jsonl{"timestamp":"2025-01-15T10:30:00Z","user":"dev","project":"webapp","action":"write","detail":"src/auth.ts"} {"timestamp":"2025-01-15T10:30:05Z","user":"dev","project":"webapp","action":"execute","detail":"npm test"}
Query with jq:
bash# All actions today jq 'select(.timestamp | startswith("2025-01-15"))' ~/.claude/audit/audit.jsonl # All writes to auth files jq 'select(.action=="write" and (.detail | contains("auth")))' ~/.claude/audit/audit.jsonl
Session Recording
Record full sessions for review:
json{ "hooks": { "post-session": { "command": "./scripts/save-session.sh" } } }
bash#!/bin/bash # scripts/save-session.sh TIMESTAMP=$(date +%Y%m%d_%H%M%S) SESSION_DIR="$HOME/.claude/sessions" mkdir -p "$SESSION_DIR" # Save git diff of changes git diff > "$SESSION_DIR/$TIMESTAMP.diff" # Save current state summary echo "Session ended: $TIMESTAMP" >> "$SESSION_DIR/$TIMESTAMP.log" echo "Changed files:" >> "$SESSION_DIR/$TIMESTAMP.log" git status --porcelain >> "$SESSION_DIR/$TIMESTAMP.log"
Access Controls
Principle of Least Privilege
Give Claude only the access it needs:
| Bad | Good |
|---|---|
| Full database admin access | Read-only database user |
| Root/admin permissions | Limited user account |
| Access to all repos | Access to current repo only |
| Production credentials | Development credentials |
File System Restrictions
Use hooks to enforce boundaries:
bash#!/bin/bash # scripts/check-write-allowed.sh FILE=$1 # Deny writes outside project if [[ ! "$FILE" == /home/*/projects/* ]]; then echo "BLOCKED: Write outside project directory" exit 1 fi # Deny writes to specific files PROTECTED=( "package-lock.json" "yarn.lock" ".env" "secrets/" ) for pattern in "${PROTECTED[@]}"; do if [[ "$FILE" == *"$pattern"* ]]; then echo "BLOCKED: Protected file: $pattern" exit 1 fi done exit 0
Command Restrictions
Block dangerous commands:
bash#!/bin/bash # scripts/check-command.sh COMMAND=$1 # Block destructive patterns BLOCKED_PATTERNS=( "rm -rf /" "rm -rf ~" "rm -rf \*" "sudo" "> /etc" "chmod 777" "curl.*|.*sh" "wget.*|.*sh" "--force" "git push.*-f" "DROP TABLE" "DELETE FROM.*WHERE 1" ) for pattern in "${BLOCKED_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qiE "$pattern"; then echo "BLOCKED: Dangerous pattern detected: $pattern" exit 1 fi done exit 0
Docker Isolation
For maximum security, run Claude Code in isolated containers:
dockerfileFROM node:20-slim # Non-root user RUN useradd -m -s /bin/bash claude USER claude # Minimal installation RUN npm install -g @anthropic-ai/claude-code WORKDIR /workspace # No network by default # Override with --network when needed
Run with strict limits:
bashdocker run -it \ --network=none \ --read-only \ --tmpfs /tmp \ --memory=2g \ --cpus=1 \ -v ./project:/workspace:rw \ -e ANTHROPIC_API_KEY \ claude-secure
Network Isolation
If Claude needs network access, whitelist specific domains:
yaml# docker-compose.yml services: claude: build: . networks: - restricted networks: restricted: driver: bridge internal: true
Team Security Policies
Shared Configuration
Create a team-wide security baseline:
json// .claude/settings.json (committed to repo) { "autoApprove": { "read": true, "write": false, "execute": false }, "hooks": { "pre-write": { "command": "./scripts/security-check.sh {{file}}", "failBehavior": "block" }, "pre-execute": { "command": "./scripts/command-check.sh {{command}}", "failBehavior": "block" } } }
Code Review Requirements
Add to AGENTS.md:
markdown## Security Requirements When writing code: 1. Never log sensitive data (passwords, tokens, PII) 2. Always validate user input 3. Use parameterized queries for database access 4. Follow OWASP guidelines for web security 5. Do not disable security features (CORS, CSRF, etc.) Before suggesting changes: 1. Consider security implications 2. Note any potential vulnerabilities 3. Flag any changes to authentication/authorization
Training and Awareness
Document for your team:
markdown# Claude Code Security Guidelines ## Do - Use environment variables for secrets - Review all changes before approving - Run Claude in Docker for sensitive projects - Use read-only database credentials - Enable audit logging ## Don't - Use --dangerously-skip-permissions outside containers - Share API keys or credentials in prompts - Approve commands you don't understand - Give Claude access to production systems - Disable security hooks
Compliance Considerations
Data Handling
Understand what data flows through Claude:
- Your code is sent to Anthropic's API
- File contents Claude reads are transmitted
- Command output may be included in context
For sensitive projects:
- Review Anthropic's data handling policies
- Consider what files Claude should not access
- Use
.claudeignorefor sensitive files
Regulatory Requirements
For regulated industries:
| Requirement | Implementation |
|---|---|
| Audit trails | Use logging hooks |
| Access control | Docker isolation, hooks |
| Data encryption | Use HTTPS (default) |
| Retention policies | Rotate logs, clear cache |
Creating a .claudeignore
Similar to .gitignore, prevent Claude from reading sensitive files:
# .claudeignore
# Secrets
.env*
secrets/
*.pem
*.key
# Sensitive data
data/pii/
exports/
backups/
# Compliance
audit-logs/
compliance/
legal/
Incident Response
If Secrets Are Exposed
- Rotate immediately: Generate new credentials
- Revoke old: Disable exposed keys/tokens
- Audit: Check for unauthorized usage
- Update: Change all related passwords
- Review: How did exposure happen?
If Unwanted Changes Occur
- Stop: Exit Claude Code immediately
- Assess:
git diffto see changes - Revert:
git checkout .to undo - Review: What went wrong?
- Prevent: Add hooks/restrictions
Reporting Security Issues
If you find security issues with Claude Code:
- Report to Anthropic via their security contact
- Don't disclose publicly before patching
- Document the issue clearly
Common Issues
Frequently Asked Questions
- Immediately rotate the key at console.anthropic.com
- Remove from git history:
bash
git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch path/to/.env" \ HEAD - Force push (if already pushed)
- Check usage for unauthorized access
- Check your
.claudeignorefile - Add pre-read hooks to block access
- Use Docker with limited volume mounts
- Review autoApprove settings
Consult with your compliance team. Generally:
- Enable audit logging
- Use Docker isolation
- Review Anthropic's compliance documentation
- Document your security controls
- Consider on-premise solutions if available
Use your CI platform's secret management:
- GitHub Actions: Repository secrets
- GitLab: CI/CD variables
- Jenkins: Credentials plugin
Never put secrets in yaml/config files.
Security Checklist
Before using Claude Code professionally:
- API key stored in environment variable, not code
-
.envfiles in.gitignore - Pre-commit hooks for secret detection
- Audit logging enabled
- File write restrictions configured
- Dangerous command blocking enabled
- Team security policy documented
- Incident response plan in place
Track Complete!
You've completed the Claude Code Advanced track if you can:
Congratulations! You've completed the Claude Code Advanced track. You now have the knowledge to use Claude Code safely and effectively in professional environments.