AIコーディング 2026.04.19
Claude Code制御ルールが機能しない原因と5つの検証方法【コード例付き】
「ルールを設定した=安全」は誤解
CLAUDE.mdに「本番DBへの接続禁止」「外部APIキーをコードに書かない」と書いても、それはAIへのお願いであって、強制ではありません。Claude Codeが生成したコードにハードコードされたAPIキーが混入していても、設定ファイルは何も教えてくれません。
# これは「守ってほしい」指示にすぎない(強制ではない)
# CLAUDE.md
# 禁止: APIキーをコードに直接書かない
# 禁止: .envファイルを読み取らない
# 必須: 環境変数経由でシークレットを渡す
問題1:ルールが適用されているか確認できない
CLAUDE.mdのルールがClaude Codeの動作にどう反映されたかを見るログが存在しません。確認できるのは最終的に生成されたコードだけです。
生成されたコード ← 「これがルールを守っているか」を人間が判断するしかない
↑
Claude Code(CLAUDE.mdを読む)
↑
CLAUDE.md(ルールが書かれている)
解決策1:--allowedToolsでツール使用を制限する
操作ツールのレベルでは--allowedToolsが有効です:
# 読み取りと特定ファイルの編集のみを許可(ファイル削除・シェル実行は禁止)
claude --allowedTools "Read,Edit(src/**)" \
-p "src/auth/login.ts のバグを修正して"
# 読み取り専用(コードレビューのみ、変更禁止)
claude --allowedTools "Read" \
-p "このコードのセキュリティ問題を列挙して"
# Gitコマンドを完全に禁止
claude --disallowedTools "Bash(git *)" \
-p "テストを追加して"
解決策2:生成コードをpre-commitフックでスキャン
# .git/hooks/pre-commit(実行権限: chmod +x .git/hooks/pre-commit)
#!/bin/bash
set -e
echo "Claude Code生成コードのセキュリティスキャン中..."
# APIキー・シークレットのパターンを検出
PATTERNS=(
'sk-[a-zA-Z0-9]{32,}' # Anthropic APIキー
'ghp_[a-zA-Z0-9]{36}' # GitHub Personal Access Token
'AKIA[0-9A-Z]{16}' # AWS Access Key
'password\s*=\s*["\047][^\047"]{4,}' # ハードコードされたパスワード
'api_key\s*=\s*["\047][^\047"]{8,}' # ハードコードされたAPIキー
)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
for file in $STAGED_FILES; do
for pattern in "${PATTERNS[@]}"; do
if grep -qE "$pattern" "$file" 2>/dev/null; then
echo "❌ 危険なパターン検出: $file"
echo " パターン: $pattern"
echo " コミットを中止します"
exit 1
fi
done
done
echo "✅ セキュリティスキャン通過"
解決策3:生成コードをPythonで自動スキャン
# scan_generated_code.py
import subprocess
import re
import sys
from pathlib import Path
DANGER_PATTERNS = [
(r'sk-[a-zA-Z0-9]{32,}', 'Anthropic APIキー'),
(r'ghp_[a-zA-Z0-9]{36}', 'GitHub PAT'),
(r'AKIA[0-9A-Z]{16}', 'AWS Access Key'),
(r'password\s*=\s*["\047][^\047"]{4,}', 'ハードコードパスワード'),
(r'subprocess\.call\([^)]*shell=True', 'shell=True (コマンドインジェクション危険)'),
(r'eval\(', 'eval() 使用'),
(r'exec\(', 'exec() 使用'),
(r'__import__\(', '動的インポート'),
]
def scan_file(filepath: Path) -> list[dict]:
findings = []
try:
content = filepath.read_text(encoding='utf-8')
for pattern, description in DANGER_PATTERNS:
matches = re.finditer(pattern, content, re.IGNORECASE)
for match in matches:
line_num = content[:match.start()].count('\n') + 1
findings.append({
'file': str(filepath),
'line': line_num,
'pattern': description,
'snippet': match.group()[:50],
})
except (UnicodeDecodeError, PermissionError):
pass
return findings
def scan_git_diff() -> list[dict]:
"""git diffで変更ファイルのみをスキャン"""
result = subprocess.run(
['git', 'diff', '--cached', '--name-only', '--diff-filter=ACM'],
capture_output=True, text=True
)
changed_files = result.stdout.strip().split('\n')
all_findings = []
for filepath_str in changed_files:
if filepath_str:
all_findings.extend(scan_file(Path(filepath_str)))
return all_findings
if __name__ == '__main__':
findings = scan_git_diff()
if findings:
print(f"⚠️ {len(findings)}件の問題を検出:")
for f in findings:
print(f" {f['file']}:{f['line']} - {f['pattern']}")
print(f" → {f['snippet']}")
sys.exit(1)
else:
print("✅ スキャン通過 - 問題なし")
sys.exit(0)
# GitHub Actionsでの自動実行
# .github/workflows/scan.yml
name: Claude Code Security Scan
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Scan for dangerous patterns
run: python scan_generated_code.py
解決策4:CLAUDE.mdのバージョン管理
ルール変更を追跡するには、CLAUDE.mdをgitで管理してバージョン履歴を残します:
# CLAUDE.mdの変更をgit logで追跡
git log --oneline -- CLAUDE.md
# 変更内容の確認
git diff HEAD~1 HEAD -- CLAUDE.md
# どのバージョンのルールで開発されたかをコミットメッセージに記録
git log --format="%H %s" | grep -i "claude"
<!-- CLAUDE.md のバージョン管理例 -->
# CLAUDE.md
# version: 2026-08-19
# last-updated: 2026-08-19
# チームでの変更は必ずレビュー必須
## 禁止事項(v3から追加)
- 本番DBへの直接接続禁止(事故防止のため)
- APIキーのハードコード禁止
解決策5:多段階の検証フロー
Claude Code生成
↓
pre-commitフック(シークレット・危険パターン自動検出)
↓
コードレビュー(人間によるロジック確認)
↓
SAST(Snyk / Semgrep などの静的解析)
↓
ステージング環境テスト
↓
本番デプロイ
# Semgrepによる静的解析をCIに追加
semgrep --config=auto src/ --json | jq '.results[] | {path, message, severity}'
# Snykでの依存関係スキャン
snyk test --json | jq '.vulnerabilities[] | {title, severity, packageName}'
リスク別の対策まとめ
| リスク | 影響 | 対策 |
|---|---|---|
| シークレットの混入 | APIキー漏洩 | pre-commitフック |
| 危険なコードパターン | セキュリティ脆弱性 | SAST(Semgrep/Snyk) |
| ルールの形骸化 | ガバナンス崩壊 | CLAUDE.mdバージョン管理 |
| 意図しない操作 | データ消失 | --allowedTools制限 |
| 監査証跡なし | インシデント調査困難 | git commitメッセージ記録 |
CLAUDE.mdのルールは「指示」です。その指示が実際に守られているかを確認するのは人間とツールの仕事です。設定と検証をセットで運用することが、Claude Codeを安全に使うための基本です。
あわせて読みたい
- Claude CodeのHooks機能でAWS本番環境を守るガードレールの作り方
- AI生成コードの脆弱性チェック完全ガイド【Snyk・CVSS・GitHub Actions統合】
- Claudeがコミット履歴に記録される時代、AIコード生成の落とし穴と安全な使い方