Claude Code becomes powerful when teams use it together. This guide covers shared configuration, permissions, automation, and team workflows.
Team Setup: Shared vs Personal Config
Claude Code uses a 3-level configuration hierarchy:
.claude/settings.json (Shared, in git, team sees it)
.claude/settings.local.json (Personal, NOT in git, your overrides)
~/.claude/config.json (User home, personal defaults)
What Goes in Shared Config (.claude/settings.json)
{
"model": "sonnet",
"maxTokens": 4096,
"tools": {
"allowed": ["Read", "Write", "Edit", "Bash", "Grep"],
"blocked": []
},
"hooks": {
"PreToolUse": [
{
"matcher": "^Bash$",
"command": "bash",
"args": ["./.claude/hooks/pre-bash.sh"]
}
]
},
"rules": [
"./.claude/rules/01-safety.md",
"./.claude/rules/02-coding-standards.md"
]
}
This is VERSION CONTROLLED. Every team member gets the same policies.
What Goes in Personal Override (.claude/settings.local.json)
{
"model": "opus",
"apiKey": "sk-proj-xxx",
"verbose": true
}
This is in .gitignore. Your personal preferences, API keys, debugging flags.
Permission Model
Team admins configure what each team member CAN do:
{
"permissions": {
"write": true,
"bash": true,
"destructive_bash": false,
"dangerous_patterns": ["rm -rf", "DROP TABLE"],
"docker": true,
"deploy": false
}
}
Hooks enforce these policies. A junior developer can't accidentally delete production.
GitHub Actions Integration
Have Claude work in your CI/CD pipeline:
Installation
# 1. Install GitHub app to your repo
claude-code /install-github-app
# 2. Add API key as secret
# Go to Settings > Secrets > New repository secret
# Name: ANTHROPIC_API_KEY
# Value: your-api-key
# 3. Copy workflow file
# From: https://github.com/anthropics/claude-code-action
# To: .github/workflows/claude.yml
Basic Workflow: Auto-Review PRs
# .github/workflows/claude-code-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Claude Code Review
uses: anthropics/claude-code-action@v1
with:
command: review-pr
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Comment Review on PR
if: always()
uses: actions/github-script@v6
with:
script: |
const review = process.env.CLAUDE_REVIEW;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: review
});
Every PR gets a Claude review automatically.
Workflow: Generate Tests
# .github/workflows/claude-generate-tests.yml
name: Generate Missing Tests
on:
pull_request:
paths:
- 'src/**/*.py'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for diff
- name: Find New Code
id: new-code
run: |
# Compare against main to find new functions
NEW_FUNCTIONS=$(git diff main...HEAD --name-only | grep '.py$')
echo "files=$NEW_FUNCTIONS" >> $GITHUB_OUTPUT
- name: Generate Tests with Claude
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
for file in ${{ steps.new-code.outputs.files }}; do
echo "Generating tests for $file"
claude-code -p "Generate pytest tests for the new functions in $file. Save as tests/test_$(basename $file)"
done
- name: Create PR with Tests
uses: peter-evans/create-pull-request@v5
with:
commit-message: 'test: auto-generated tests for new functions'
title: '[Auto] Generated Tests'
body: |
Claude Code generated tests for new functions.
Please review and adjust as needed.
branch: claude-generated-tests
Workflow: Release Notes Generation
# .github/workflows/claude-release-notes.yml
name: Generate Release Notes
on:
release:
types: [created]
jobs:
notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get Commits Since Last Release
id: commits
run: |
COMMITS=$(git log --oneline $(git describe --tags --abbrev=0)..HEAD)
echo "commits<<EOF" >> $GITHUB_OUTPUT
echo "$COMMITS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Generate Release Notes
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude-code -p "Generate release notes from these commits:
${{ steps.commits.outputs.commits }}
Format:
- Features (bulleted)
- Bug Fixes (bulleted)
- Breaking Changes (if any)
Keep it concise and user-friendly."
- name: Update Release
uses: actions/github-script@v6
with:
script: |
github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: context.payload.release.id,
body: process.env.CLAUDE_OUTPUT
});
Headless Mode: Claude Code in Scripts
Run Claude Code without a terminal UI:
# Print output to stdout, exit immediately
claude-code -p "Analyze src/app.py for performance issues"
# Useful in:
# - CI/CD pipelines
# - Automated scripts
# - Monitoring/alerting systems
# - Batch processing
Example: Batch Code Analysis
#!/bin/bash
# analyze-codebase.sh
# Run Claude Code analysis on all Python files
FILES=$(find src/ -name "*.py")
for file in $FILES; do
echo "Analyzing $file..."
claude-code -p "
Review $file for:
- Security issues
- Performance problems
- Code quality
Keep analysis brief (< 200 words)"
echo "---"
done | tee analysis-report.txt
Use in CI/CD:
- name: Analyze Codebase
run: bash scripts/analyze-codebase.sh
- name: Upload Report
uses: actions/upload-artifact@v3
with:
name: analysis-report
path: analysis-report.txt
Cost Management at Scale
Teams can quickly rack up costs. Implement guardrails:
Cost Tracking
# track_costs.py
import json
from datetime import datetime
from pathlib import Path
def log_usage(model, input_tokens, output_tokens):
"""Log token usage for cost tracking"""
# Rough pricing (as of 2026)
COSTS = {
"haiku": {"input": 0.80, "output": 2.40}, # per 1M tokens
"sonnet": {"input": 3.00, "output": 15.00},
"opus": {"input": 15.00, "output": 75.00},
}
cost = COSTS[model]
input_cost = (input_tokens / 1_000_000) * cost["input"]
output_cost = (output_tokens / 1_000_000) * cost["output"]
total_cost = input_cost + output_cost
log_entry = {
"timestamp": datetime.now().isoformat(),
"model": model,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"cost": total_cost
}
# Append to cost log
log_file = Path("costs.jsonl")
with open(log_file, "a") as f:
f.write(json.dumps(log_entry) + "\n")
return total_cost
def daily_cost_report():
"""Generate cost report"""
log_file = Path("costs.jsonl")
if not log_file.exists():
return {}
today = datetime.now().date()
total_cost = 0
by_model = {}
with open(log_file) as f:
for line in f:
entry = json.loads(line)
entry_date = datetime.fromisoformat(entry["timestamp"]).date()
if entry_date == today:
total_cost += entry["cost"]
model = entry["model"]
by_model[model] = by_model.get(model, 0) + entry["cost"]
return {
"date": str(today),
"total_cost": total_cost,
"by_model": by_model,
"budget_remaining": 500 - total_cost # $500/day budget
}
Use in CI/CD:
- name: Check Daily Cost
run: |
python scripts/track_costs.py
COST=$(python -c "from scripts.track_costs import daily_cost_report; import json; print(json.dumps(daily_cost_report()))")
if (( $(echo "$COST > 500" | bc -l) )); then
echo "⚠️ Daily cost budget exceeded!"
exit 1
fi
Budget Alerts
# alert_on_cost.py
import os
from track_costs import daily_cost_report
def alert_if_needed():
report = daily_cost_report()
cost = report["total_cost"]
# Alert at 70%, 90%, 100% of budget
BUDGET = 500
THRESHOLDS = [0.7, 0.9, 1.0]
for threshold in THRESHOLDS:
limit = BUDGET * threshold
if cost >= limit and cost < (limit + 50): # Avoid duplicate alerts
send_slack_alert(f"Cost alert: ${cost:.2f} ({threshold*100:.0f}% of budget)")
def send_slack_alert(message):
import requests
webhook = os.environ.get("SLACK_WEBHOOK")
if webhook:
requests.post(webhook, json={"text": message})
Model Selection Strategy
Optimize cost by choosing the right model per task:
# .claude/settings.json
{
"modelSelection": {
"default": "sonnet",
"tasks": {
"code-review": "sonnet",
"refactoring": "sonnet",
"testing": "haiku",
"bug-investigation": "opus",
"architecture-planning": "opus",
"documentation": "haiku"
}
}
}
Team agrees: use Haiku for documentation (cheap), Opus only for hard problems.
Security & Access Control
Secret Management
Never commit API keys. Use environment variables or secret managers:
# .github/workflows/workflow.yml
- name: Run Claude Code
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: claude-code -p "..."
Permission Policies
Define what each role can do:
{
"roles": {
"junior": {
"can_bash": false,
"can_write": true,
"can_deploy": false,
"max_tokens": 2000
},
"senior": {
"can_bash": true,
"can_write": true,
"can_deploy": true,
"max_tokens": 8000
},
"infra": {
"can_bash": true,
"can_write": true,
"can_deploy": true,
"allowed_dirs": ["infrastructure/", "k8s/"]
}
}
}
Audit Logging
Log all Claude Code actions for compliance:
# .claude/hooks/post-tool-audit.sh
#!/bin/bash
LOG_FILE=".audit.log"
# Log every tool invocation
echo "$(date -Iseconds) $CLAUDE_TOOL_NAME $USER $CLAUDE_SESSION_ID" >> "$LOG_FILE"
# For write/edit, also log what changed
if [[ "$CLAUDE_TOOL_NAME" == "Edit" ]] || [[ "$CLAUDE_TOOL_NAME" == "Write" ]]; then
FILE=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.path')
echo " Modified: $FILE" >> "$LOG_FILE"
fi
Onboarding New Team Members
Checklist
# Claude Code Onboarding Checklist
- [ ] Install Claude Code CLI
- [ ] Get ANTHROPIC_API_KEY from team lead
- [ ] Clone repository
- [ ] Read project CLAUDE.md
- [ ] Review .claude/rules/ (coding standards, safety, etc)
- [ ] Configure .claude/settings.local.json with your API key
- [ ] Run: `claude-code "Summarize this project for me"`
- [ ] Complete first task: Fix a simple issue with Claude Code
- [ ] Code review by senior team member
- [ ] Approved to work independently
Guided First Task
Team lead: "Review my CLAUDE.md and summarize the project architecture"
> claude-code "Read CLAUDE.md. What's the architecture? What are the main components?"
Claude explains the project. If Claude is confused, CLAUDE.md needs improvement.
This validates both the new person's setup AND the quality of project docs.
Team Communication Patterns
Pattern 1: Async Code Review
Pull request → Claude auto-reviews → human reviews Claude's feedback:
1. Author pushes PR
2. GitHub Actions runs: claude-code /review-pr
3. Claude posts review as comment
4. Author reads Claude's feedback + adjusts if needed
5. Reviewers see refined PR
6. Faster review cycle
Pattern 2: Pair Programming with Claude
Two humans + Claude in a session:
Junior: "Help me understand what this function does"
Claude: Explains code
Senior: "Good explanation. Now let's refactor it"
Claude: Suggests refactoring
Junior: Implements suggested changes
Claude: Reviews implementation, suggests tests
Both: Discuss and finalize
Pattern 3: Async Documentation
Claude auto-generates docs:
1. PR merged
2. GitHub Actions: claude-code "Generate API docs"
3. Docs auto-committed to main
4. Website auto-deploys with latest docs
Docs always in sync with code.
Common Team Gotchas
Gotcha 1: Everyone Shares One API Key
# Bad: Shared API key, hard to track usage
# Good: Individual API keys, aggregate cost reports
Give each team member their own key. Track usage per person.
Gotcha 2: Git Conflicts on CLAUDE.md
Multiple people editing CLAUDE.md → merge conflicts
Solution:
- Designate 1 person as CLAUDE.md maintainer
- Other team members suggest changes via issues/PRs
- Maintainer updates once after discussion
Gotcha 3: Stale CLAUDE.md
CLAUDE.md written 6 months ago, project has changed significantly
Claude gets outdated information
Results are wrong
Solution:
- Monthly review of CLAUDE.md
- Update after major changes
- Add "Last Updated" date
Gotcha 4: Model Too Expensive
Team uses Opus (most expensive) for all tasks
Monthly bill is $10,000+
Solution:
- Use Haiku for simple tasks
- Use Sonnet for most work
- Use Opus only when really needed
- Set per-team-member daily budget
Checklist
- Created
.claude/settings.jsonwith shared team policies - Created
.gitignoreentry for.claude/settings.local.json - Set up GitHub Actions for Claude Code workflows
- Installed GitHub app with proper permissions
- Added API key as GitHub Secret
- Created cost tracking script
- Set daily budget alerts
- Defined roles and permissions
- Set up audit logging
- Created onboarding checklist for new team members
- Documented team communication patterns
- Designated CLAUDE.md maintainer
- Scheduled monthly CLAUDE.md review
- Tested that junior developers can't access dangerous operations
- Verified CI/CD workflows work end-to-end
