Claude Code Security: How to Use AI Coding Assistants Safely
Security best practices for Claude Code. Learn about permission modes, secrets management, MCP security, and how to prevent AI-powered attacks.
Claude Code Security: How to Use AI Coding Assistants Safely
AI coding assistants are powerful. That power comes with responsibility. I've seen teams accidentally expose secrets, delete production databases, and create security vulnerabilities. Here's how to avoid those mistakes.
The Security Landscape
Claude Code has extensive capabilities:
- Read and write files
- Execute shell commands
- Access APIs and databases
- Connect to external services
Without proper safeguards, you risk:
- Secret exposure
- Data breaches
- Unauthorized access
- Infrastructure damage
Permission Modes
Claude Code has granular permission controls.
Permission Levels
| Mode | File Access | Shell | Network | Destructive |
|---|---|---|---|---|
--no-tool |
Read-only | ❌ | ❌ | ❌ |
--tool |
Read/Write | Safe only | ✅ | ❌ |
--dangerous |
Full | Full | Full | ✅ |
Choosing the Right Mode
# Safe development
claude --tool
# When you need destructive commands
claude --dangerous
# Read-only review
claude --no-tool
Interactive Prompts
For sensitive operations, Claude Code prompts:
? Run command: rm -rf node_modules
[y] Yes [n] No [a] Always [q] Quit
Recommendation: Use a (Always) for known-safe commands, n for anything suspicious.
Secrets Management
Never Commit Secrets
❌ Never do this:
// Hardcoded API key
const API_KEY = "sk-1234567890abcdef";
✅ Do this instead:
// Environment variable
const API_KEY = process.env.OPENAI_API_KEY;
Use .env Files
# .env (add to .gitignore)
OPENAI_API_KEY=sk-1234567890abcdef
DATABASE_URL=postgres://...
STRIPE_KEY=sk_test_...
Claude Code + Secrets
Claude Code understands .env files:
# Works - Claude Code sees your .env
claude "Use the database connection to run migrations"
# Won't work - No .env
claude "Use the database" # No credentials!
Secret Scanning
Before running Claude Code:
# Check for exposed secrets
git secrets --scan
claude "review code for exposed secrets"
MCP Security
MCP servers can access external systems. Protect yourself.
Permission Scopes
MCP servers declare their permissions:
{
"name": "github-server",
"permissions": ["network:github.com", "read:repos"]
}
Review Before Installing
Before installing an MCP server:
- Who built it? (Trusted author?)
- What permissions? (Read-only or write?)
- What does it access? (Network, filesystem?)
- Is it maintained? (Recent updates?)
Restrict Access
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"allow": ["read:user", "read:repo"],
"deny": ["delete:*"]
}
}
}
Token Management
GitHub Tokens:
- Use Fine-grained tokens
- Limit to specific repos
- Set expiration dates
- Never commit to git
Slack Tokens:
- Use bot tokens, not user tokens
- Limit channel access
- Rotate regularly
File System Protection
Directory Restrictions
{
"permissions": {
"filesystem": {
"allow": ["/projects/**", "/docs/**"],
"deny": ["/secrets/**", "/.env", "/production/**"]
}
}
}
Destructive Operations
# Prompts for confirmation
rm -rf build
# Skips confirmation (if allowed)
rm -rf node_modules
Recommendation: Always review before running rm -rf
Backup Before Large Operations
# Backup before refactoring
cp -r ./src ./src.backup
# Now safe to let Claude Code work
claude "Refactor the entire /src directory"
Network Security
API Access Control
{
"permissions": {
"network": {
"allow": ["api.github.com", "api.stripe.com"],
"deny": ["*.internal", "localhost"]
}
}
}
Rate Limiting
Many APIs have rate limits. Claude Code can hit them fast:
❌ "Query the API 1000 times"
✅ "Query the API once, cache results"
Sensitive Endpoints
# Claude Code will prompt for dangerous endpoints
POST /api/admin/delete-all-users
# Safer: Explicit permission
claude "Delete test data, not production"
Git Security
Dangerous Git Operations
# Dangerous - Could lose work
git push --force
git reset --hard HEAD~1
# Safer - Claude Code prompts
git push
git commit
Branch Protection
Configure in settings:
{
"git": {
"protectBranches": ["main", "production"],
"warnForcePush": true,
"requirePR": true
}
}
Review Before Push
"Show me all changes before pushing"
Code Review Security
Security-Focused Prompts
"Review this code for:
1. SQL injection vulnerabilities
2. XSS vulnerabilities
3. Authentication bypass
4. Authorization issues
5. Secrets exposure"
Common Vulnerabilities
| Vulnerability | Pattern | Risk |
|---|---|---|
| SQL Injection | query(userInput) |
Critical |
| XSS | innerHTML = userData |
High |
| Auth Bypass | Missing middleware | Critical |
| Secret Exposure | Hardcoded keys | High |
Automated Scanning
# Run security scan
claude -p "Scan this codebase for OWASP Top 10 vulnerabilities"
CI/CD Security
Pipeline Best Practices
# GitHub Actions
- name: Security Scan
run: |
claude -p "Review PR for security issues"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Limit permissions
permissions:
contents: read
pull-requests: write
Secrets in CI
Never pass secrets to Claude Code in CI:
# ❌ Dangerous
- run: claude "Deploy with $DEPLOY_KEY"
# ✅ Safe
- run: claude "Deploy" # Uses environment
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
Approval Workflows
# Require approval for production
- name: Deploy Production
condition: environment == 'production'
approval_required: true
run: claaude "Deploy v$VERSION"
Team Security Policies
Setting Up Policies
Create a CLAUDE.md with security guidelines:
# Security Guidelines
## Never Allowed
- Push directly to main
- Delete branches without approval
- Access production database directly
- Commit secrets to git
## Always Required
- Code review before merge
- Security scan on PR
- Test coverage above 80%
## Sensitive Operations
- Database migrations require approval
- Infrastructure changes require approval
- Secret rotation requires approval
Permission Matrix
| Role | Local Dev | Staging | Production |
|---|---|---|---|
| Developer | Full | Read-only | ❌ |
| Senior Dev | Full | Full | Read-only |
| DevOps | Full | Full | Full |
| Claude Code | Configurable | Configurable | Configurable |
Incident Response
If a Secret is Exposed
- Immediate: Rotate the exposed secret
- Short-term: Review access logs
- Long-term: Update security policies
# Check git history for secrets
git log --all -S "sk-123456" --oneline
# Remove from history
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch secret-file' \
--prune-empty --tag-name-filter cat -- --all
If Code was Damaged
# Check git reflog
git reflog
# Restore from backup
git checkout HEAD@{10}
# Or restore specific file
git checkout HEAD~5 -- path/to/file
Security Checklist
Before Using Claude Code
- [ ] Review permission settings
- [ ] Configure filesystem restrictions
- [ ] Set up .gitignore for secrets
- [ ] Review MCP server permissions
- [ ] Enable audit logging
During Development
- [ ] Review plans before execution
- [ ] Use --no-tool for reviews
- [ ] Check diffs before committing
- [ ] Run security scans on PRs
- [ ] Monitor API usage
After Development
- [ ] Review change logs
- [ ] Check for exposed secrets
- [ ] Rotate any exposed credentials
- [ ] Update security documentation
Tools & Integrations
Security Scanning
| Tool | Use Case |
|---|---|
| Git Secrets | Secret detection |
| Snyk | Vulnerability scanning |
| SonarQube | Code quality & security |
| Semgrep | Static analysis |
Monitoring
| Tool | Use Case |
|---|---|
| GitHub Audit Log | Track actions |
| CloudTrail | AWS API calls |
| Datadog | Application monitoring |
Summary
- Start restrictive - Use --tool mode by default
- Protect secrets - Never commit, use env vars
- Review MCP permissions - Know what you're installing
- Backup before large ops - git reflog saves lives
- Audit regularly - Check logs and history
Quick Reference
Safe Defaults
# Development
claude --tool
# Review only
claude --no-tool
# When you need destructive
claude --dangerous
Security Prompts
"Review for SQL injection"
"Check for exposed secrets"
"Scan for XSS vulnerabilities"
"Verify authentication"
Emergency Contacts
- Secret exposed? → Rotate immediately
- Code damaged? → git reflog
- Unauthorized access? → Review audit logs
Security is everyone's responsibility. Questions? Leave a comment.