AIセキュリティ入門【実践編】|「AIに機密ファイルを読まれたら?」と不安な方へ

.envなどの機密ファイルの読み取りや危険なコマンドの実行をブロックし、それ以外はルールで抑える。そんなClaude Codeのセキュリティ設定を、コピペ1回で入れられるようにしました。実行ブロックをチャットに貼り付けるだけで、セキュリティルール(CLAUDE.md)と強制ブロック設定(settings.json)の2点セットが入ります。

はじめに

セキュリティ設定の導入前と導入後の対比図。導入後は盾が機密フォルダを守る

AI導入のご相談で、「AIが勝手に機密ファイルを読んだり、危険なコマンドを実行したりしないか」という不安をよく聞きます。Claude Codeの場合、この不安には設定ファイル2つで対処できます。

この記事では、その2つに何を書くのか、なぜそれをブロックするのかを先に説明します。中身を確認したうえで導入したい方は、ページ最下部の「Claude Codeへの指示」セクションにある実行ブロック(点線で囲まれた部分)をコピーして、Claude Codeのチャットに貼り付けるだけで設定が入ります。AIが既存の設定をバックアップした上で、2つのファイルに必要な内容を追記します。

※設定の変更はご自身の環境に対するものです。内容を本文で確認の上、自己責任でお願いします。

実行中にファイル作成の許可を確認するダイアログが出た場合は、許可してください。環境によっては自動実行がブロックされることがあります。その場合は、AIに書き込ませる代わりに、実行ブロック内「ファイル始まり」〜「ファイル終わり」で囲まれた部分をご自身でコピーし、指定のパスにファイルとして保存していただいても結果は同じです。

※この手動の方法で設置できるのはCLAUDE.mdのルール部分です。settings.jsonのブロック設定はJSONの編集をともなうため、AIに実行してもらってください。

必要なもの

全体の流れ

コピー、貼り付け、AIが設定、動作確認の4ステップのフロー図

  1. ページ最下部の実行ブロックをコピーする
  2. Claude Codeのチャットに貼り付ける
  3. AIが既存設定をバックアップしてから、2つのファイルに追記する
  4. 動作確認をする(/permissions でルール一覧を確認し、テスト用の.envを読ませて拒否されるかを見る)

導入は1回だけで、2回目以降の作業はありません。設定は~/.claude/(ホームディレクトリ配下のグローバル設定)に入るため、どのプロジェクトで起動しても適用されます。ファイル系のブロックは起動したフォルダ配下のファイルに効き、~/.ssh/~/.aws/は場所を指定して常にブロックします。

何がインストールされるのか

CLAUDE.mdはお願いの点線の壁、settings.jsonは強制ブロックの壁として機密書類を守る二重の壁の図解

追記されるのは2ファイルで、役割が違います。

1点目は~/.claude/CLAUDE.mdへのセキュリティルールの追記です。破壊的な操作の前に確認を取る、機密ファイルを読まない、外部送信の前に確認する、公開範囲を変える前に確認する、個人情報をマスキングする、認証情報をハードコードしない、判断に迷ったら止まる、の7カテゴリを追記します。

もう1つ「ブロックされた時は、安全な代替案を示す」というルールも入れます。設定で止められた時に、AIが回避策を探すのではなく、目的を安全に達成する別のやり方を提案してくれるようにするためです。

CLAUDE.mdはAIが毎回読み込む指示書ですが、公式ドキュメントが明言しているとおり厳密な遵守は保証されません。つまりこれは「お願い」の層です。

2点目が~/.claude/settings.jsonへのpermissions.deny設定の追加です。

読み取りのブロック対象は2種類あります。1つは.envsecrets/credentials/と、秘密鍵や証明書(*.pem*.key*.p12*.pfx)です。

もう1つが、認証情報が平文で保存されやすい場所です。~/.ssh/~/.aws/~/.netrc~/.git-credentials~/.npmrcに加え、GitHub CLI・Docker・Kubernetesの設定と、GPGの秘密鍵が対象になります。

実行のブロック対象は2種類です。取り返しがつかない操作(rm -rfgit push --forcegit reset --hardgit clean)と、ネットワーク経由の送信(curlwget)になります。

あわせてsudoなど権限昇格のコマンドと、GitHubで公開範囲に関わるコマンドはpermissions.askに入れます。こちらはブロックではなく、実行前に必ず確認を挟む設定です。どちらも正当な用途が多いため、一律禁止ではなく「毎回自分の目で確認する」形にしています。

公開範囲を入れているのは、これが一番取り返しがつかないからです。非公開のリポジトリは、コマンド1つで公開に切り替えられます。

公開した瞬間に誰でも閲覧・複製でき、検索エンジンやキャッシュ、他の人のコピーに残ります。後から非公開に戻しても、完全には取り消せません。

逆に非公開のままなら、うっかり認証情報をコミットしても被害は自分の範囲に留まります。そのためこの設定では、新規作成は非公開を既定としてAIが提案するようにしています。

こちらはAIの判断を経由しない「強制」の層で、お願いが破られた時の受け皿になります。この設定は当社のテスト環境で実機検証済みです(.env系のファイルはすべて読み取り拒否になり、対照実験で通常のファイルは問題なく読めることを確認しました)。

自動モードだからこそ、この設定が効きます

Claude Codeは現在、自動モードがデフォルトです。これは操作のたびに人へ確認を出すのではなく、分類器が自動で許可・拒否を判断するモードです。

Anthropicが公表している数字では、ユーザーは権限確認の97%を承認しています。1,053人のテスターによる実験でも、AIが提案した危険なコマンドに人間の承認者が気づけたのは13.6%でした(自動モードの分類器は89%)。確認ダイアログを人が見て止める、という前提はすでに現実的ではありません。

そして重要なのが、公式ドキュメントが明記しているとおり、自動モードでもpermissionsのルールは分類器より先に評価されるという点です。今回入れるdeny設定は、自動モードで動かしていても確実に効きます。

既存のCLAUDE.md・settings.jsonがある場合も安心してください。実行ブロックは、日時つきのバックアップを作ってから追記のみを行い、既存の内容には触れない設計にしています。

注記

この設定で防げる範囲(ツール経由の読み書き)と防げない範囲(サブプロセスの直読・パターンの迂回)の境界図

この2点セットで防げる範囲には限界があります。導入前に知っておいてください。

  • deny設定がブロックするのはClaude Codeのツール経由の読み書きです。Pythonスクリプトなどのサブプロセスがファイルを直接開く経路までは防げません(そこまで塞ぐにはOSレベルの隔離機能=sandboxが必要です)
  • コマンドのdenyは文字列パターンの一致で判定されるため、パターンに一致しない別の書き方までは対象になりません
  • 読み取りのdenyは、同じパスへの変更(Edit/Write)もあわせてブロックします。読めないだけでなく書き換えもできなくなる、と理解してください
  • そのため、たとえば「.env.exampleから.envを作って」「.envにキーを追加して」といった作業はAIに頼めなくなります。ご自身で編集するか、settings.jsonから"Read(**/.env)"の行を外してください
  • 環境変数(KUBECONFIGDOCKER_CONFIGGNUPGHOMEなど)で設定ファイルの保存先を変えている場合、標準パス向けのルールは効きません
  • CLAUDE.mdのルールは、AIが読み違えたり従わなかったりする可能性が常にあります。だからこそdeny設定とのセットにしています
  • 設定の書式や挙動はバージョンアップで変わることがあります。導入後の/permissionsでの確認は省略しないでください
  • .env.example.env.sampleのような、秘密を含まないサンプルファイルも読めなくなります。denyはallowで上書きできない仕様のため、必要な場合は該当行を調整してください
  • curlwgetもブロック対象に含めています。普段Claude CodeのBashでcurlを使う方は、導入後にsettings.jsonの該当行("Bash(curl *)""Bash(wget *)")を削除すれば外せます。なおPythonやNode経由の通信までは止まりません
  • サブプロセスの直読まで含めて塞ぎたい場合は、この設定の次のステップとしてOSレベルの隔離機能(sandbox)を検討してください

※効果は環境・使い方によって変わります。この設定を入れれば何でも安全になる、というものではありません。

おわりに

導入後は、新しいセッションで/permissionsを実行してdenyルールが並んでいることを確認し、テスト用フォルダに中身がダミーの.envを作って読ませてみてください。拒否されれば設定が効いています。

この設定は、安全側に寄せて厳しめにしてあります。使っていて「これは止めなくていい」と感じた項目は、settings.jsonから該当の行を削れば外せます。全部入れたまま使い続ける必要はないので、実際に使いながらご自身の運用に合う形へ調整してください。

元に戻したい時は、実行時に作られたバックアップファイル(CLAUDE.md.bak-日時settings.json.bak-日時)を元の名前に戻すだけです。導入前にファイルが無かった場合はバックアップも作られないので、その時は作られたファイルごと削除すれば元どおりです。Claude Codeに「この記事で入れたセキュリティ設定を外して」と頼んでも戻せます。

そもそもどの情報をAIに渡してよいのか、という判断基準は考え方編にまとめています。設定とセットで使ってください。

なお、どの項目をなぜブロックしているのかは次にまとめました。興味のある方は覗いてみてください。

ブロックする項目と理由

読み取りをブロックするもの(20項目)

設定 何のファイルか 漏れると困る理由
Read(**/.env) サービスの合鍵を書いておくファイル 他人があなたのアカウントで有料サービスを使えてしまう
Read(**/.env.*) 上の使い分け版(本番用・テスト用など) 名前が違うだけで中身は同じく合鍵
Read(**/secrets/**) 「秘密」という名前のフォルダ 名前のとおり、鍵やパスワードを入れておく場所
Read(**/credentials/**) 「認証情報」という名前のフォルダ ログイン情報の置き場として使われる
Read(**/*.pem) サーバーに入るための鍵ファイル これがあれば誰でもそのサーバーを操作できる
Read(**/*.key) 名前のとおり鍵ファイル 上と同じく、持っている人が中に入れる
Read(**/*.p12) 鍵と身分証をまとめたファイル 本人になりすませてしまう
Read(**/*.pfx) 上と同じ中身の別名ファイル Windowsでよく使われる呼び方
Read(**/.npmrc) プログラム部品を公開する時の設定 勝手に部品を公開・書き換えされる恐れがある
Read(~/.ssh/**) サーバーにログインする鍵の保管庫 自分のサーバーに自由に入られてしまう
Read(~/.aws/**) Amazonのクラウドを操作する権限 勝手にサーバーを作られ、費用が発生することもある
Read(~/.netrc) サイトごとのIDとパスワードの一覧 パスワードがそのままの文字で書かれている
Read(~/.git-credentials) GitHubなどのパスワード代わりの文字列 ソースコードを見られたり書き換えられたりする
Read(~/.config/git/credentials) 上と同じもの(置き場所違い) 環境によってはこちらに保存される
Read(~/.npmrc) 上のnpm設定のパソコン共通版 プロジェクト側と同じ内容が入る
Read(~/.config/gh/hosts.yml) GitHubのログイン情報 保管庫が使えない環境では文字のまま保存される
Read(~/.docker/config.json) Dockerのログイン情報 設定によっては中身がそのまま保存される
Read(~/.kube/config) 複数のサーバーをまとめて操作する権限 会社のシステム全体を触れてしまうことがある
Read(~/.gnupg/private-keys-v1.d/**) 電子署名に使う鍵 本人が署名したように偽装できてしまう
Read(~/.claude/.credentials.json) Claude Code自身のログイン情報 WindowsとLinuxではここに保存される

実行をブロックするもの(8項目)

設定 何をする操作か 止める理由
Bash(rm -rf *) フォルダをまるごと削除する ゴミ箱に残らず、元に戻せない
Bash(rm -fr *) 上とまったく同じ削除 書き方が違うだけなので一緒に止める
Bash(git push --force *) 過去の作業記録を上書きする 他の人の作業まで消えることがある
Bash(git push -f *) 上とまったく同じ操作 短い書き方でも止められるように
Bash(git reset --hard *) 保存前の変更を捨てる まだ保存していない作業が消える
Bash(git clean *) 記録していないファイルを削除する 作りかけのファイルが消え、元に戻せない
Bash(curl *) インターネット経由でやりとりする 手元の情報を外部に送れてしまう
Bash(wget *) 上と同じことができる別のコマンド curlだけ止めても意味がないため対で塞ぐ

実行前に確認を求めるもの(7項目)

禁止ではなく、毎回確認が入る設定です。どれも必要な場面があるので、止めるのではなく気づける形にしています。

設定 何をする操作か 確認する理由
Bash(sudo *) 管理者として実行する 権限が上がると、上のブロックを飛び越えられる
Bash(doas *) 上と同じ働きの別コマンド 別の名前でも同じことができる
Bash(pkexec *) 管理者権限を得る別の方法 経路を1つ塞いでも他が残るため
Bash(su *) 管理者に切り替わる 古くからある方法で、今も使える
Bash(gh repo create *) GitHubに保管場所を新しく作る 公開設定で作ると、中身が全世界から見える
Bash(gh repo edit *) 保管場所の設定を変える 非公開から公開へ、コマンド1つで切り替わる
Bash(gh gist create *) コードの断片を共有する 公開を選ぶと誰でも見られる状態になる

Claude Codeへの指示(このセクションが実行対象)

下の「ここからコピー」〜「ここまでコピー」の点線内をまるごとコピーして、Claude Codeのチャットに貼り付けてください。

========== ここからコピー ==========
下記の内容を、あなた(Claude Code)の設定に反映してください。これは、セキュリティルール(CLAUDE.mdへの追記)と、機密ファイル・危険コマンドのブロック設定(settings.jsonへのキー追加)を導入する作業です。

【手順1】事前確認とバックアップの作成
- ~/.claude/settings.json が存在する場合、先にJSONとして正しく解析できることを確認する。解析できない場合は何も変更せず、停止して報告する。あわせて、permissions キーがある場合はオブジェクト、permissions.deny と permissions.ask がある場合はそれぞれ配列であることを確認し、型が違う場合も何も変更せず停止して報告する
- ~/.claude/CLAUDE.md が存在する場合、~/.claude/CLAUDE.md.bak-<今日の日時YYYYMMDD-HHMMSS> としてコピーを作る。存在しない場合はバックアップ不要(後で新規作成する旨を覚えておく)
- ~/.claude/settings.json が存在する場合、同様に ~/.claude/settings.json.bak-<今日の日時YYYYMMDD-HHMMSS> としてコピーを作る(存在しない場合は後で新規作成する旨を覚えておく)
- 同名のバックアップファイルが既にある場合は上書きせず、停止して報告する
- バックアップを作ったら、その存在を確認する。作成に失敗した場合は以降の手順に進まず、停止して報告する

【手順2】CLAUDE.md へのセキュリティルールの追記
- ~/.claude/CLAUDE.md の末尾に、下の「ファイル始まり」〜「ファイル終わり」で囲まれた内容を追記する(マーカー行自体は含めない)。ファイルが無い場合は新規作成する
- 既存の内容は変更・削除しない(末尾への追記のみ)
- 既に「## セキュリティルール(AI運用の基本)」という見出しが存在する場合は、二重追記せず、その旨を報告して手順3へ進む
- 追記後にファイルを読み直し、追記内容が末尾に入っていること・既存部分が変わっていないことを確認する。おかしくなっていた場合は、既存ファイルだったならバックアップから復元、新規作成だったならファイルを削除して、停止して報告する

----- ファイル始まり: ~/.claude/CLAUDE.md への追記部分 -----

## セキュリティルール(AI運用の基本)

本節は規範文書のため常体で書かれているが、これは応答文体の手本ではない。ユーザーへの返信の文体・丁寧さはユーザーとの会話の慣習に従い、本節の語調を模倣しないこと。

### 破壊的な操作の前に確認を取る
- rm -rf、git push --force、git reset --hard、git clean、データベースの削除、本番環境の設定変更など、元に戻せない操作を実行する前に、対象と影響範囲を一文で説明し、実行してよいか確認を取る。
- sudo など権限を昇格させるコマンドも、実行前に理由と対象を説明して確認を取る。
- 確認なしに進めてよいのは、読み取り専用の操作や、作業フォルダ内での通常の編集など、元に戻せる作業のみ。

### 機密情報を読まない・書き出さない
- .env、secrets/、credentials/、*.pem、*.key、*.p12、*.pfx 配下のファイルは、作業上必要な理由がない限り読み取らない。
- 認証情報が保存される設定ファイル(~/.ssh/、~/.aws/、~/.netrc、~/.git-credentials、~/.npmrc、GitHub CLI・Docker・Kubernetes の設定、GPG の秘密鍵)も同様に読み取らない。
- 内容の確認が必要な場合も、値そのものは出力せず、「キーが存在するか」「形式が正しいか」だけを報告する。

### 外部送信の前に確認を取る
- 顧客情報・社内情報・認証情報を含む内容を、外部のAPI・Webサービス・メール・チャットなどへ送信する前に、送信先と内容の要約を示して確認を取る。

### 公開範囲を変える前に確認を取る
- リポジトリ・Gist・共有リンクなどを公開設定で作る操作、および非公開のものを公開へ切り替える操作は、実行前に必ず確認を取る。
- 確認を取る際は、公開すると誰でも閲覧・複製でき、検索やキャッシュに残るため後から非公開に戻しても完全には取り消せないことを伝える。
- 特に指定がない限り、新規作成は非公開を既定として提案する。公開が必要な場合も、認証情報や顧客情報が含まれていないかを確認してから進める。

### 顧客情報・個人情報をマスキングする
- ログ・エラーメッセージ・コミットメッセージ・報告文に、氏名・メールアドレス・電話番号・カード情報などをそのまま書き出さない。必要な場合は一部を伏せ字にする(例: ***@example.com)。

### 認証情報をハードコードしない
- APIキー・トークン・パスワードをコードや設定ファイル、コミットメッセージに直接書かない。環境変数または秘密情報管理の仕組みを経由して扱う。

### 判断がつかない時は止まって確認する
- 上のいずれかに該当するか迷った場合は、実行せずに確認を取る。「たぶん大丈夫」で進めない。

### ブロックされた時は、安全な代替案を示す
- 設定によって操作がブロックされた場合、それを回避する別の経路(スクリプト経由での直接読み取り、パターンに一致しない書き方など)を試さない。
- 代わりに、何がブロックされたかを伝えたうえで、安全を保ったまま目的を達成する方法を提案する。例: ファイルの中身を読む代わりに「そのキーが存在するか」だけを確認する、値を伏せた形で報告する、ユーザー自身に編集してもらう、設定の該当行を一時的に外す判断をユーザーに委ねる。

----- ファイル終わり -----

【手順3】settings.json への deny / ask 設定の追加
- ~/.claude/settings.json が無い場合は {} を初期内容として新規作成する(解析と型の確認は手順1で済んでいる)
- permissions.deny 配列(無ければ作る)に、次のリストのうちまだ入っていない項目だけを追加する。既存の deny・allow・ask の項目や、他のキーには一切触れない:
  "Read(**/.env)"
  "Read(**/.env.*)"
  "Read(**/secrets/**)"
  "Read(**/credentials/**)"
  "Read(**/*.pem)"
  "Read(**/*.key)"
  "Read(**/*.p12)"
  "Read(**/*.pfx)"
  "Read(**/.npmrc)"
  "Read(~/.ssh/**)"
  "Read(~/.aws/**)"
  "Read(~/.netrc)"
  "Read(~/.git-credentials)"
  "Read(~/.config/git/credentials)"
  "Read(~/.npmrc)"
  "Read(~/.config/gh/hosts.yml)"
  "Read(~/.docker/config.json)"
  "Read(~/.kube/config)"
  "Read(~/.gnupg/private-keys-v1.d/**)"
  "Read(~/.claude/.credentials.json)"
  "Bash(rm -rf *)"
  "Bash(rm -fr *)"
  "Bash(git push --force *)"
  "Bash(git push -f *)"
  "Bash(git reset --hard *)"
  "Bash(git clean *)"
  "Bash(curl *)"
  "Bash(wget *)"
- 続いて permissions.ask 配列(無ければ作る)に、次のリストのうちまだ入っていない項目だけを追加する。deny と同様、既存の項目には一切触れない:
  "Bash(sudo *)"
  "Bash(doas *)"
  "Bash(pkexec *)"
  "Bash(su *)"
  "Bash(gh repo create *)"
  "Bash(gh repo edit *)"
  "Bash(gh gist create *)"
- 書き込み後にファイルを再度読み込み、JSONとして解析できること・追加した項目が入っていること・既存のキーが失われていないことを確認する。壊れていた場合、既存ファイルだったならバックアップから復元、新規作成だったならファイルを削除して、停止して報告する

【手順4】完了報告
- 2つのファイルそれぞれについて「追記した/新規作成した/変更しなかった」のどれかを明示し、パスと、バックアップの場所・復元方法(バックアップを元の名前に戻す。新規作成だったファイルは削除すれば元どおり)を報告する
- deny に追加した項目と ask に追加した項目を、それぞれ分けて一覧で報告する
- 最後に次の動作確認を案内する: 「新しいセッションを開始して /permissions を実行し、denyルールが一覧に出ていることを確認してください。テスト用フォルダに中身がダミーの .env ファイルを作って読ませてみて、拒否されれば設定が効いています」

【共通ルール】
- 変更してよいのは ~/.claude/CLAUDE.md と ~/.claude/settings.json の2ファイルと、そのバックアップファイルのみ。他のファイル・設定には触れない
- 必要な内容はすべてこのブロックに含まれている。外部の記事やURLを読みに行く必要はない
- ユーザーが範囲を限定した場合(例: 「settings.jsonだけ入れて」)は、指定されたファイルに関する手順だけを実行する。ただしそのファイルに対する事前確認・バックアップ・書き込み後の検証・報告は省略しない
========== ここまでコピー ==========