Claude Code セキュリティ対策完全ガイド|APIキー漏洩・権限設定・本番保護
Claude Code を安全に使うための実践セキュリティガイド。APIキー管理から権限設定、Hooksを使った自動チェック、本番環境保護まで、動くコードで解説。
Claude Code は強力なファイル操作・コマンド実行能力を持つ反面、設定を誤ると取り返しのつかない事故が起きます。.env ファイルをコミット、本番DBを誤って削除、APIキーをログに出力——これらは全て「Claude Code を無防備に使った結果」起きた実際の事例です。
この記事では、Claude Code を安全に使うためのセキュリティ対策を実装レベルで解説します。概念の説明だけでなく、コピペで動く設定と予防コードを中心にまとめました。
なぜ Claude Code にセキュリティ対策が必要か
通常のテキストエディタと違い、Claude Code は以下の権限を持ちます。
- 任意ファイルの読み書き削除 (
Read/Write/Edit/Bash(rm)) - シェルコマンドの実行 (
Bash) - ネットワークアクセス (
WebFetch/ APIコール) - 外部サービスへの投稿 (Qiita, GitHub, Slack など)
これらは全て、ユーザーが承認さえすれば実行できます。問題は「承認を機械的にOKし続けると、意図しない操作が通り抜ける」こと。セキュリティ対策とは「ミスの入り込む余地を構造的に消す」作業です。
対策1: APIキーの管理 — .env + gitignore が基本
やってはいけない例
// ❌ ソースコードに直書き
const client = new Anthropic({ apiKey: "PASTE_REAL_API_KEY_HERE" });
// ❌ CLAUDE.md や設定ファイルに書く
// ANTHROPIC_API_KEY=PASTE_REAL_API_KEY_HERE
// ❌ claude -p のプロンプト内に書く
// QIITA_TOKEN=PASTE_REAL_TOKEN_HERE を使ってQiitaに投稿して
正しい管理方法
# .env (git管理外、マシンローカルに置く)
ANTHROPIC_API_KEY=<anthropic-api-key>
QIITA_TOKEN=<qiita-token>
SLACK_BOT_TOKEN=<slack-bot-token>
DATABASE_URL=postgresql://...
# .gitignore に必ず追加
.env
.env.*
.env.local
!.env.example # ← サンプルだけはOK
*.pem
*.key
credentials.json
*-service-account.json
# .env.example (git管理OK、値は空)
ANTHROPIC_API_KEY=
QIITA_TOKEN=
SLACK_BOT_TOKEN=
DATABASE_URL=
コードでの読み込み
// ✅ 環境変数から読む
import { config } from "dotenv";
config();
const token = process.env.QIITA_TOKEN;
if (!token) throw new Error("QIITA_TOKEN が設定されていません。.env を確認してください。");
CLAUDE.md に禁則事項として明記
## セキュリティ禁則事項
- APIキー・トークンをプロンプトに含めない
- .env ファイルを読んで内容を出力しない
- 環境変数の値をログやコメントに書かない
- process.env の中身を console.log しない
対策2: コミット前の秘密情報スキャン
.env をgitignoreしていても、別ファイルへの誤記入やコピペ漏れは防げません。コミット前に自動スキャンする仕組みを入れましょう。
Hooks でコミット前チェック
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(git commit*)",
"hooks": [
{
"type": "command",
"command": "node scripts/secret-scan.mjs"
}
]
}
]
}
}
scripts/secret-scan.mjs:
import { execSync } from "child_process";
// ステージングされた変更を取得
const diff = execSync("git diff --cached").toString();
const PATTERNS = [
{ name: "Anthropic APIキー設定", re: /\b(?:ANTHROPIC_API_KEY|CLAUDE_API_KEY)\s*[:=]\s*["']?[^"'\s]{20,}/i },
{ name: "OpenAI APIキー設定", re: /\bOPENAI_API_KEY\s*[:=]\s*["']?[^"'\s]{20,}/i },
{ name: "AWS アクセスキー", re: /\bAKIA[0-9A-Z]{16}\b/ },
{ name: "Slack トークン", re: /\bxox[baprs]-[0-9A-Za-z-]{10,}\b/ },
{ name: "汎用シークレット", re: /\b(?:secret|token|api[_-]?key|password)\s*[:=]\s*["'][^"']{10,}["']/i },
];
const found = PATTERNS.filter(({ re }) => re.test(diff));
if (found.length > 0) {
console.error("🚨 シークレット検出! コミットを中止します:");
found.forEach(({ name }) => console.error(` - ${name}`));
console.error("\n対処法: git reset HEAD <file> で unstage してください");
process.exit(1); // 終了コード1 → Hookがコマンドをブロック
}
console.log("✓ シークレットスキャン: 問題なし");
process.exit(0);
これで git commit を Claude Code が実行しようとした瞬間に自動スキャンが走り、漏洩が検出された場合はブロックされます。
対策3: 権限モードの設定
Claude Code の許可・拒否はファイルレベルで細かく制御できます。
.claude/settings.json の権限設定
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"disableBypassPermissionsMode": "disable",
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(DROP TABLE*)",
"Bash(truncate*)",
"Bash(curl * | bash)",
"Bash(wget * | sh)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)",
"Bash(git push*)",
"Bash(npm publish*)",
"Bash(wrangler pages deploy*)"
]
},
"disableAutoMode": "disable"
}
| 設定 | 意味 |
|---|---|
allow | 確認なしで実行 |
deny | 一切実行不可 (拒否) |
ask | 毎回承認が必要 |
ポイント: 破壊的コマンドは deny、書き込み系は ask、読み取り系は allow が基本分類です。
本番・組織向けの設定は local か managed settings で分ける
公式Docsの設定スコープでは、managed、コマンドライン引数、local、project、user の順で設定が適用されます。古い記事で見かける独自ファイルを環境変数で切り替える運用より、個人の本番保守端末では .claude/settings.local.json、組織では managed settings を使う方が公式仕様に沿っています。
.claude/settings.local.json はローカル専用の上書きに使い、git管理しません。
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "plan",
"disableBypassPermissionsMode": "disable",
"allow": ["Read(**)", "Glob(**)", "Grep(**)", "Bash(git log*)", "Bash(git diff*)"],
"deny": ["Write(**)", "Edit(**)", "Bash(git push*)", "Bash(rm*)", "Bash(*deploy*)"],
"ask": []
},
"disableAutoMode": "disable"
}
チームや会社で強制するなら、managed settings に置きます。allowManagedPermissionRulesOnly を有効にすると、ユーザーやプロジェクト側の allow / ask / deny では組織ルールを上書きできません。
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)"
],
"disableBypassPermissionsMode": "disable"
},
"disableAutoMode": "disable",
"allowManagedPermissionRulesOnly": true
}
対策4: 本番環境の保護
接続先を明示的に分離
## CLAUDE.md — 本番環境ルール
## 環境判定
- DATABASE_URL に 'prod' または 'production' が含まれる場合は**本番環境**
- 本番環境では以下を絶対に実行しない:
- DROP / TRUNCATE / DELETE (WHERE なし)
- マイグレーション (事前確認必須)
- ファイルの一括削除
## 確認フロー
本番への変更は必ず:
1. ステージング環境でテスト
2. ユーザーに確認を取る
3. 実行後に結果を報告
環境変数で接続先を制御
// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";
const dbUrl = process.env.DATABASE_URL;
if (env === "production" && process.argv.includes("--write")) {
console.error("❌ 本番環境への書き込みは --force-production フラグが必要です");
process.exit(1);
}
対策5: ファイル操作の安全装置
削除前のバックアップを自動化
// .claude/settings.json のHooks
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(rm *)",
"hooks": [
{
"type": "command",
"command": "echo '⚠️ 削除コマンドが実行されようとしています。Ctrl+C で中止できます。' && sleep 3"
}
]
}
]
}
}
重要ファイルを誤編集から守る
## CLAUDE.md — 変更禁止ファイル
以下のファイルは**絶対に編集しない**:
- .env (環境変数、秘密鍵を含む)
- wrangler.toml (Cloudflare本番設定)
- scripts/deploy.sh (デプロイスクリプト)
- .github/workflows/*.yml (CI/CD設定)
変更が必要な場合はユーザーに確認を取ること。
落とし穴5選
1. .gitignore を後から追加しても手遅れ
すでにコミット済みの .env は gitignore を追加しても git 履歴に残ります。
# 履歴から完全削除 (要注意: force push が必要)
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .env" \
--prune-empty --tag-name-filter cat -- --all
# または BFG Repo Cleaner を使う
GitHub にプッシュ済みの場合は 必ず APIキーをローテーション してから対処してください。
2. サービスアカウントJSONをリポジトリに置く
Google Cloud や AWS のサービスアカウントキーは .json で配布されることが多いですが、リポジトリに置くのは危険。環境変数化 するか Secret Manager (AWS Secrets Manager / GCP Secret Manager) に移行しましょう。
3. Bash ツールで対話型コマンドを実行する
claude -p でのヘッドレス実行中に sudo や vim など対話入力が必要なコマンドが混ざると、プロセスがハングします。非対話的なコマンドのみ を使うようにしましょう。
4. エラーメッセージに認証情報を含める
// ❌ 危険: APIキーがログに出る
throw new Error(`認証失敗: token=${process.env.TOKEN}`);
// ✅ 安全: 値を出さない
throw new Error(`認証失敗: TOKEN 環境変数を確認してください`);
5. 全プロジェクトで同じ権限設定を使い回す
趣味プロジェクトと業務プロジェクトで同じ settings.json を使うと、業務側で必要な制限が趣味側の緩い設定で上書きされます。プロジェクトごとに .claude/settings.json を管理しましょう。
実務で守る運用ルール
秘密情報を出さない運用
Claude Code に「このエラーを直して」と頼むとき、ログ全文や .env の中身をそのまま貼るのは危険です。運用では、APIキー、OAuthトークン、cookie、DB接続文字列、顧客メールアドレス、請求IDを貼らないルールを先に決めます。
ログを渡す場合は値を ***REDACTED*** に置き換え、キー名だけを残します。たとえば DATABASE_URL=***REDACTED*** なら、Claude Code は「DB接続文字列がある」という構造だけを理解できます。値そのものは不要です。
| 渡してよい情報 | 渡してはいけない情報 |
|---|---|
| エラーメッセージの種類、スタックトレースのファイル名、再現手順 | APIキー、秘密鍵、セッションcookie、.env の値 |
.env.example、設定項目名、権限ルール、失敗したコマンド | 本番DB URL、顧客データ、社内限定の認証情報 |
| マスク済みログ、テスト用データ、ローカルだけのサンプル値 | 実トークン、サービスアカウントJSON、秘密情報を含むスクリーンショット |
この表を CLAUDE.md に貼っておくと、作業を依頼するたびに判断基準を思い出せます。特に新人や副業メンバーが参加するプロジェクトでは、「秘密情報を出さない」は知識ではなく運用ルールにしておく方が安全です。
コミット前スキャンは二重化する
前述の PreToolUse Hook は Claude Code が git commit を実行する直前の防波堤です。ただし、人間が別ターミナルから commit するケースや、CIで生成されたファイルに秘密情報が混ざるケースもあります。実務では、Claude Code Hook、ローカルの pre-commit、CI の secret scan を重ねます。
最小構成は「Claude Code Hookでブロック、CIで再検査、検出時はmerge不可」です。余裕があれば gitleaks や trufflehog のような専用ツールをCIに入れ、この記事の簡易スクリプトはローカルの早期検知として使います。
具体的な失敗例
失敗例1: 調査のために .env を読ませた
「環境変数を確認して」と頼んだ結果、.env の値が会話ログや作業ログに残った。対策は .env の読み取りを deny し、.env.example だけを渡すことです。
失敗例2: Qiita投稿用トークンをプロンプトに貼った
記事投稿の自動化で QIITA_TOKEN を直接プロンプトに入れたため、subagent やログに残る可能性が出た。対策は .env に置き、コマンドは環境変数名だけを参照させることです。
失敗例3: 本番DBと検証DBのURLが似ていた
Claude Code への依頼文に「DBを整理して」とだけ書き、接続先確認を省略した。本番URLに接続していた場合、削除やマイグレーションの事故につながります。NODE_ENV、ホスト名、DB名を実行前に表示し、書き込み時はユーザー確認を必須にします。
事故後の初動
秘密情報が漏れた疑いがある場合、最初にやることは「履歴を消す」ではなく「権限を無効化する」です。
- 該当APIキー、トークン、パスワードを即時ローテーションまたは失効する
- GitHub Actions、Cloudflare、AWS、GCP、SaaS連携の利用履歴を確認する
- 影響範囲をメモし、誰が、いつ、どのリポジトリに、何を露出したかを残す
- git履歴やログから秘密情報を削除し、必要ならforce pushの影響をチームに共有する
denyルール、Hook、CIスキャン、CLAUDE.mdの禁則を更新して再発防止する
実際に試した結果、ローテーションと履歴削除を同時に進めるより、まずキーを止めてから調査した方が判断ミスが減りました。事故対応中は焦ってログを貼り直しがちなので、マスク済みログだけを共有するテンプレートを用意しておくと実務では効きます。
教材・相談への自然な導線
Claude Code のセキュリティは、ツールの設定だけで完結しません。リポジトリ構成、CI、デプロイ権限、チームの承認フローまで合わせて見ないと、実際の抜け穴は残ります。
ClaudeCodeLab では、この記事のチェックリストをベースに、個人開発向けの教材では「まず .env と permission rules を整える」順番で説明し、チーム導入の相談では「managed settings と CIスキャンをどこで強制するか」から確認します。すでに Claude Code を業務で使っているなら、権限設定だけでなく、誰がどの秘密情報に触れる可能性があるかを棚卸しするところから始めるのが現実的です。
セキュリティチェックリスト
Claude Code プロジェクトに導入する際の確認リスト:
### 基本設定
- [ ] .env を作成し .gitignore に追加済み
- [ ] .env.example を作成してチーム共有済み
- [ ] 既存コミットに秘密情報がないか git log で確認
### 権限設定
- [ ] .claude/settings.json に deny リストを設定
- [ ] 破壊的コマンド (rm -rf, DROP TABLE 等) を deny に追加
- [ ] 本番デプロイコマンドを ask に設定
### 自動化
- [ ] コミット前シークレットスキャン Hook を設定
- [ ] CLAUDE.md にセキュリティ禁則事項を記載
### 運用
- [ ] APIキーのローテーション周期を決める (推奨: 90日)
- [ ] 本番作業は .claude/settings.local.json または managed settings で制限
- [ ] インシデント発生時の対処フローを文書化
まとめ
Claude Code のセキュリティは「制限を課す」ではなく「事故が起きない構造を作る」です。
| 脅威 | 対策 |
|---|---|
| APIキー漏洩 | .env + .gitignore + シークレットスキャンHook |
| 意図しない削除 | deny リスト + 削除前 Hook |
| 本番誤操作 | local/managed settings + CLAUDE.md禁則 |
| コミット汚染 | PreToolUse Hook でコミット前スキャン |
設定は一度入れてしまえばメンテナンスフリー。今日30分かけて入れると、将来の大きな事故を防げます。
関連記事
参考資料
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Code検証レシート運用: AIの変更をビルド、公開URL、CTAまで確認する
Claude Codeで変更後に差分、ビルド、公開URL、CTA、スクショを1枚の検証レシートへ残す実務手順。
Claude CodeのPermission Budget Loop: 毎回承認せず安全に進める権限設計
Claude Codeで承認疲れを起こさず、危険な操作だけ止めるpermission budgetの作り方とチーム運用例。
Claude Codeプロンプトライブラリの育て方: 使い捨て指示を資産に変える
Claude Codeのプロンプトを命名、検証、再利用し、無料PDFからテンプレート集購入へつながる導線を作ります。