Claude Code セキュリティベストプラクティス:安全な AI 支援開発ワークフローの構築
Claude Code 開発者のための必須セキュリティプラクティス。権限管理から環境分離まで、安全な AI 支援開発ワークフローを構築します。
AI 支援開発におけるセキュリティはオプションではなく、基本です。Claude Code が開発ワークフローの不可欠な部分になるにつれて、セキュリティベストプラクティスを理解することが、コード、データ、ユーザーを保護するために重要になります。
このガイドでは、すべての Claude Code 開発者が実装すべき実践的なセキュリティプラクティスを提供します。
セキュリティマインドセット
なぜ AI 開発には特別な注意が必要か
AI 支援開発には独自の考慮事項があります:
- より広いアクセス:AI ツールは有用であるために、より広いファイルシステムアクセスが必要になることが多い
- トークン露出:API キーと認証情報が誤ってコンテキストに現れる可能性がある
- 権限境界:AI が何にアクセスできて何にアクセスできないかを理解する
- 監査証跡:どのような変更が行われ、なぜ行われたかを追跡する
主要原則:AI 支援開発を、本番システムに適用するのと同じ厳格さで扱います。
1. 権限管理
最小権限の原則
Claude Code を最小限必要な権限で設定します:
{
"permissions": {
"allow": [
"Read(src/**)",
"Write(src/**)",
"Edit(src/**)",
"Bash(npm run:*)",
"Bash(npm test:*)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git log:*)"
],
"deny": [
"Read(.env*)",
"Read(**/secrets/**)",
"Read(**/*.pem)",
"Read(**/*.key)",
"Read(**/*credential*)",
"Write(.env*)",
"Edit(.env*)",
"Bash(rm -rf:*)",
"Bash(*--force*)",
"Bash(*DROP*)",
"Bash(*DELETE FROM*)"
]
}
}
権限レイヤー
Claude Code は4層の設定階層を使用します:
| レイヤー | 場所 | 目的 |
|---|---|---|
| エンタープライズ | /etc/claude-code/ | 組織全体のポリシー |
| ユーザー | ~/.claude/ | 個人の設定 |
| プロジェクト | .claude/settings.json | プロジェクト固有のルール |
| セッション | ランタイム | 一時的なオーバーライド |
ベストプラクティス:適切な最高レベルでセキュリティルールを定義します。コンプライアンスにはエンタープライズ、特定のニーズにはプロジェクトを使用。
定期的な権限監査
# 現在の権限を確認
cat .claude/settings.json | jq '.permissions'
# 過度に許可的なパターンをチェック
grep -r "allow.*\*\*" .claude/
2. 環境変数の保護
シークレットを決して公開しない
CLAUDE.md には明示的に記載します:
## シークレット処理
### 絶対禁止
- コードに API キー、トークン、パスワードをハードコード
- コミットメッセージにシークレットを含める
- シークレットをコンソールやファイルにログ出力
- エラーメッセージにシークレットを含める
### 常に
- シークレットには環境変数を使用
- 安全な設定管理を通じてシークレットを参照
- 認証情報を定期的にローテーション
- 環境ごとに異なる認証情報を使用
環境ファイルセキュリティ
# .env ファイルの正しい権限
chmod 600 .env
chmod 600 .env.local
chmod 600 .env.production
# 権限の確認
ls -la .env*
# 表示されるべき: -rw------- (所有者のみ読み書き可能)
例:安全な設定
// ❌ 絶対にやってはいけない
const API_KEY = "sk-ant-abc123...";
// ✅ 常にこうする
const API_KEY = process.env.ANTHROPIC_API_KEY;
if (!API_KEY) {
throw new Error("ANTHROPIC_API_KEY 環境変数が必要です");
}
3. ファイルシステム分離
プロジェクト境界
Claude Code がプロジェクト境界内に留まるようにします:
{
"permissions": {
"deny": [
"Read(/etc/**)",
"Read(/var/**)",
"Read(~/.ssh/**)",
"Read(~/.aws/**)",
"Read(~/.config/**)",
"Write(/**)"
]
}
}
Gitignore ベストプラクティス
# シークレット - 決してコミットしない
.env
.env.local
.env.*.local
*.pem
*.key
secrets/
credentials/
# Claude Code 成果物 - 通常コミットしない
.claude/memory.json
CLAUDE.local.md
.auto-cycle/
# ビルド出力
dist/
build/
node_modules/
シンボリックリンクへの意識
シンボリックリンクがディレクトリ制限を迂回する可能性があることに注意:
# プロジェクト内のシンボリックリンクをチェック
find . -type l -ls
# プロジェクト外部を指すシンボリックリンクがないことを確認
find . -type l -exec realpath {} \; | grep -v "$(pwd)"
4. 安全な開発ワークフロー
Pre-Commit セキュリティチェック
#!/bin/bash
# .git/hooks/pre-commit
# 潜在的なシークレットをチェック
if git diff --cached --name-only | xargs grep -l -E "(sk-ant-|ANTHROPIC_API_KEY=|password\s*=\s*['\"][^'\"]+['\"])" 2>/dev/null; then
echo "❌ ステージされた変更で潜在的なシークレットを検出"
exit 1
fi
# 過度に許可的なファイル権限をチェック
for file in $(git diff --cached --name-only); do
if [[ -f "$file" ]]; then
perms=$(stat -f "%OLp" "$file" 2>/dev/null || stat -c "%a" "$file" 2>/dev/null)
if [[ "$perms" == "777" || "$perms" == "666" ]]; then
echo "❌ ファイル $file の権限が過度に許可的: $perms"
exit 1
fi
fi
done
echo "✅ セキュリティチェック通過"
コードレビューガイドライン
AI 生成コードをレビューする際のチェック項目:
## AI コードレビューチェックリスト
### 入力検証
- [ ] すべてのユーザー入力が検証されている
- [ ] 検証がホワイトリスト方式を使用
- [ ] サーバー側の検証が存在(クライアント側だけでなく)
### 認証と認可
- [ ] ハンドラーの開始時に認証チェック
- [ ] 各アクションに対して認可が検証
- [ ] 権限昇格パスがない
### データ処理
- [ ] 機密データがログに記録されない
- [ ] エラーメッセージが内部情報を漏らさない
- [ ] PII が適切に処理されている
### 依存関係
- [ ] 不要な新しい依存関係がない
- [ ] 依存関係が適切にメンテナンスされている
- [ ] 既知の脆弱性がない(npm audit)
5. セキュアコーディングパターン
入力検証
import { z } from 'zod';
// 厳密なスキーマを定義
const UserInputSchema = z.object({
email: z.string().email().max(255),
name: z.string().min(1).max(100).regex(/^[a-zA-Z\s]+$/),
age: z.number().int().min(0).max(150),
});
// すべての入力を検証
function handleUserInput(input: unknown) {
const result = UserInputSchema.safeParse(input);
if (!result.success) {
throw new ValidationError(result.error.message);
}
return result.data; // 型安全で検証済み
}
SQL インジェクション防止
// ❌ 脆弱
const query = `SELECT * FROM users WHERE email = '${email}'`;
// ✅ 安全 - パラメータ化クエリを使用
const user = await prisma.user.findUnique({
where: { email }
});
// ✅ 安全 - プリペアドステートメントを使用
const user = await db.query(
'SELECT * FROM users WHERE email = $1',
[email]
);
XSS 防止
// ❌ 脆弱 - 直接 HTML 注入
<div dangerouslySetInnerHTML={{ __html: userContent }} />
// ✅ 安全 - React が自動エスケープ
<div>{userContent}</div>
// ✅ 安全 - HTML が必要な場合は先にサニタイズ
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }} />
エラー処理
// ❌ 脆弱 - 内部情報を露出
catch (error) {
return res.status(500).json({
error: error.message,
stack: error.stack
});
}
// ✅ 安全 - 内部でログ、一般的なメッセージを返す
catch (error) {
logger.error('内部エラー', {
error: error.message,
stack: error.stack,
requestId: req.id
});
return res.status(500).json({
error: '内部エラーが発生しました',
requestId: req.id // サポート参照用
});
}
6. MCP セキュリティ考慮事項
信頼できる MCP サーバーのみを使用
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem", "/path/to/project"],
"trustLevel": "limited"
}
}
}
コンテキスト分離
複数の MCP サーバーを使用する場合、コンテキスト分離を考慮:
## MCP セキュリティガイドライン
1. **MCP サーバーを最小限に** - 必要なものだけを有効化
2. **アクセス範囲を限定** - 各サーバーに最小パスを設定
3. **定期的に監査** - MCP サーバーのアクセスログをレビュー
4. **迅速に更新** - MCP サーバーを最新に保つ
ネットワーク対応 MCP
ネットワークリクエストを行う MCP サーバーの場合:
{
"mcpServers": {
"api-client": {
"command": "node",
"args": ["./mcp-api-client.js"],
"env": {
"ALLOWED_HOSTS": "api.example.com,api.trusted.com"
}
}
}
}
7. 監査とモニタリング
セッションログ
セキュリティ監査のためにセッションログを有効化:
# すべての Claude Code セッションをログ
export CLAUDE_LOG_LEVEL=info
export CLAUDE_LOG_FILE=~/.claude/sessions.log
アクセス監視
ファイルアクセスパターンを追跡:
## セキュリティモニタリングチェックリスト
### 毎日
- [ ] 機密ディレクトリへのアクセスをレビュー
- [ ] 異常な権限変更をチェック
- [ ] レビューなしで新しい依存関係が追加されていないか確認
### 毎週
- [ ] セッションログの異常を監査
- [ ] 権限設定をレビュー
- [ ] 依存関係の脆弱性スキャンを実行
### 毎月
- [ ] CLAUDE.md の完全なセキュリティレビュー
- [ ] 権限拒否リストを更新
- [ ] 露出した認証情報をローテーション
自動アラート
セキュリティイベントのモニタリングを設定:
# 機密ファイルアクセス試行を監視
tail -f ~/.claude/sessions.log | grep -E "(\.env|secrets|credentials)" &
# 権限拒否イベントのアラート
tail -f ~/.claude/sessions.log | grep "permission denied" | while read line; do
echo "セキュリティアラート: $line" | mail -s "Claude Code セキュリティアラート" admin@example.com
done
8. インシデント対応
認証情報が露出した場合
## 認証情報露出対応
1. **即座に**
- 露出した認証情報を取り消す
- 新しい認証情報を生成
- それを使用するすべてのシステムを更新
2. **1時間以内**
- ログを監査して不正使用を確認
- データ流出をチェック
- セキュリティチームに通知
3. **24時間以内**
- インシデント後レビュー
- 再発防止のため手順を更新
- 学んだ教訓を文書化
悪意のあるコードが生成された場合
## 悪意のあるコード対応
1. **実行しない** - すぐに停止
2. **記録** - スクリーンショットを撮りコードを保存
3. **ロールバック** - 行われた変更を元に戻す
4. **報告** - セキュリティチームに通知
5. **レビュー** - パターンを探すため最近のセッションを監査
9. チームセキュリティプラクティス
セキュリティトレーニングトピック
## Claude Code ユーザー必須トレーニング
1. **権限モデル**(30分)
- 権限の仕組み
- 安全に設定する方法
- 避けるべき一般的な間違い
2. **シークレット管理**(30分)
- シークレットを決してハードコードしない
- 環境変数のベストプラクティス
- ローテーション手順
3. **AI のためのコードレビュー**(45分)
- 何を見るべきか
- AI 生成コードの一般的な脆弱性
- レビューチェックリストの使用
4. **インシデント対応**(30分)
- いつエスカレートすべきか
- 対応手順
- 文書化要件
セキュリティチャンピオン
チームメンバーをセキュリティチャンピオンとして指名:
## セキュリティチャンピオンの責任
- 毎月の権限設定レビュー
- セキュリティトレーニングセッションの実施
- セキュリティ問題の最初の対応者
- セキュリティ文書の維持
- Claude Code セキュリティ機能の更新を把握
10. 継続的改善
セキュリティメトリクス
時間経過とともにこれらのメトリクスを追跡:
| メトリクス | 目標 | 測定 |
|---|---|---|
| 権限違反 | 0 | 毎日のログレビュー |
| シークレット露出 | 0 | Pre-commit hooks |
| 依存関係の脆弱性 | 0 クリティカル | 毎週の npm audit |
| セキュリティインシデント | 0 | インシデント追跡 |
定期レビュー
## 月次セキュリティレビューアジェンダ
1. [ ] 権限設定のレビュー
2. [ ] セッションログの監査
3. [ ] 新しいパターンの拒否リスト更新
4. [ ] Claude Code アップデートの確認
5. [ ] このチェックリストのレビューと更新
6. [ ] チームとの学びの共有
始めよう
今日(15分)
- ✅
.claude/settings.jsonに拒否ルールを設定 - ✅
.envファイルの権限が正しいことを確認(600) - ✅ シークレットを
.gitignoreに追加
今週(1時間)
- ✅ pre-commit hooks を設定
- ✅ チームセキュリティガイドラインを作成
- ✅ MCP サーバー設定をレビュー
今月(2時間)
- ✅ チームセキュリティトレーニングを実施
- ✅ モニタリングとアラートを確立
- ✅ インシデント対応手順を文書化
主なポイント
- 最小権限 - 必要な権限のみを付与
- 多層防御 - 複数のセキュリティ制御層
- 信頼しない、常に検証 - 入力を検証し、出力をレビュー
- すべてを監査 - ログを維持し定期的にレビュー
- 最新を保つ - Claude Code と依存関係を最新に
セキュリティは一度きりの設定ではなく、継続的なプロセスです。これらのプラクティスを日々のワークフローに組み込むことで、AI 支援でより安全なソフトウェアを開発できます。
セキュリティプラクティスは、組織の特定の要件とコンプライアンスニーズに合わせて調整する必要があります。