AIコーディングで変更してはいけないファイルを守る方法|権限・ルール・Read Only設計

AIコーディングで変更してはいけないファイルを守る方法|権限・ルール・Read Only設計 AI開発

Claude CodeやGitHub CopilotなどのAIコーディングツールに大規模な変更を任せると、意図していなかったファイルまで変更されることがあります。

たとえば、

意図せず変更されやすいファイル
.env
config/production.yml
package-lock.json
database/migrations/
generated/
vendor/

などです。人間なら「ここは変更してはいけない」と分かっていても、AIエージェントは依頼されたタスクを完了するために、関連していると判断したファイルを変更することがあります。

そこで、

無視されやすい指示例
このファイルは変更しないでください

CLAUDE.mdcopilot-instructions.mdへ書きたくなります。この方法自体は有効ですが、重要なファイルを本当に守る必要があるなら、自然言語のルールだけに依存するのはおすすめできません。

Claude Codeの公式ドキュメントでも、CLAUDE.mdなどのInstructionsはモデルが「何をしようとするか」に影響するものであり、実際に何を許可するかはPermission SystemやHookなどで制御するよう説明されています。GitHub Copilotについても、GitHubはAIの非決定的な性質によってCustom Instructionsが毎回まったく同じように守られるとは限らないと説明しています。

変更してはいけないファイルを確実に保護するなら、

多層防御の考え方
自然言語のルール
↓
AIツールのPermission
↓
実行前Hook
↓
OS・コンテナのRead Only
↓
Git・CIで最終チェック

という複数の層で守る設計が有効です。

この記事では、AIコーディングで特定のファイルやディレクトリを変更させないための方法と、Claude CodeのPermission、GitHub CopilotのCustom Instructions、Read Only、Hook、CIの使い分けを解説します。Claude Codeの権限設定そのものの詳しい書き方は権限・パーミッション設定完全ガイドを、プロンプトインジェクション対策まで含めたセキュリティ全般はセキュリティ完全ガイドを参照してください。この記事では「変更してはいけないファイルをどう守るか」という一点にしぼって解説します。

スポンサーリンク
  1. 「変更しないで」と書くだけでは完全な保護にならない
  2. 最初にファイルを3種類へ分けて考える
  3. 読めるが変更不可ならEditを拒否する
  4. Claude CodeではWriteではなくEditを指定する
  5. Readを禁止すると変更も禁止できる
  6. .envを.gitignoreに入れるだけではAIから守れない
  7. CLAUDE.mdにも「なぜ変更してはいけないか」を書く
  8. GitHub CopilotではCustom Instructionsで変更範囲を伝える
  9. Path-specific Instructionsで対象ディレクトリの扱いを説明する
  10. 「触らない」ではなく「代わりに何をするか」を書く
  11. Permissionだけでも完全なOSレベル保護ではない
  12. 強く守りたいならRead Onlyファイルシステムにする
  13. AIに編集させる範囲だけWrite可能にする
  14. OSのchmodだけで十分とは限らない
  15. Claude CodeではSandboxも組み合わせる
  16. Bashのrmを禁止するだけではファイルを守れない
  17. PreToolUse Hookで変更前に独自チェックする
  18. 「既存Migrationだけ編集禁止」のような条件はHook向き
  19. Hookだけを唯一のSecurity Boundaryにしない
  20. Gitのskip-worktreeを保護機能として使わない
  21. Git Hookは「変更そのもの」ではなくCommitを止める層
  22. CIでも保護ファイルの変更を検出する
  23. Branch ProtectionとRequired Checkまで組み合わせる
  24. Generated Fileは直接編集禁止にして生成元だけ触らせる
  25. Lockfileは「直接編集禁止」と「変更禁止」を分ける
  26. 本番設定ファイルはRepositoryから分離する方法もある
  27. AI用の作業コピーを分けるのも有効
  28. Read Only環境でもAIに必要な情報は読ませられる
  29. 「自動承認」を強くするほどRead Only設計が重要になる
  30. ファイル保護と読み取り保護を混同しない
  31. 重要度によって保護レベルを変える
  32. 「AIに見せるが変更させない」が使いやすい
  33. AIコーディングではルールより「変更できない設計」を優先する
  34. AIコーディングのファイル保護に関するよくある質問

「変更しないで」と書くだけでは完全な保護にならない

まず理解しておきたいのが、

区別すべき2つの概念
AIへの指示
と
システム上の権限制限

は別だということです。たとえばCLAUDE.mdへ、

CLAUDE.md
# Important Files

config/production.ymlは変更しない。

database/migrations以下の既存ファイルは編集しない。

.envは読み書きしない。

と書くことはできます。通常であればClaudeはこの指示を考慮します。しかしこれは、ファイルシステム上で書き込みを禁止したわけではありません。モデルがタスク達成に必要だと判断したり、長いセッションで指示への追従が弱くなったり、別のInstructionsと競合したりすれば、変更を試みる可能性があります。

Claude Code自身も、InstructionsはPermissionを変更しないと明記しています。Permission RuleはClaude Code側で強制され、モデルの判断とは別に処理されます。

重要度の高いファイルでは、AIに「変更するな」と説明するだけでなく、変更しようとしても実行できない状態にする必要があります。

最初にファイルを3種類へ分けて考える

AIコーディング環境を安全にするなら、すべてのファイルを同じ扱いにしないほうが管理しやすくなります。

たとえば通常のソースコードは「読み取り可能・変更可能」とします。設定資料や生成済み仕様などは「読み取り可能・変更不可」とします。秘密情報は「読み取り不可・変更不可」にします。

この区別が重要です。たとえばconfig/production.ymlはAIに内容を読ませたいが、変更はさせたくないかもしれません。一方.envはそもそもAIへ中身を読ませたくない場合があります。この2種類を同じ「触らないで」というルールだけで扱うと、権限設計が曖昧になります。

読めるが変更不可ならEditを拒否する

Claude Codeではファイルの読み取りと変更をPermission Ruleで分離できます。たとえばconfig/production.ymlをClaudeに参照させたいものの、変更させたくないとします。Projectの.claude/settings.jsonに次のような設定を入れられます。

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Edit(/config/production.yml)"
    ]
  }
}

Project Settingsで/pathを使った場合、ProjectのPrimary Working Directoryを基準とするPathとして扱われます。これならClaudeはファイルを読むことはできますが、Built-in File Toolによる変更は拒否されます。ディレクトリ全体を保護するなら、

ディレクトリ単位の保護
{
  "permissions": {
    "deny": [
      "Edit(/config/production/**)"
    ]
  }
}

のようにできます。Permission設定のパス形式やallow・ask・denyの評価順序など、より詳しい書き方は権限・パーミッション設定完全ガイドにまとめています。

Claude CodeではWriteではなくEditを指定する

ここは特に間違えやすいポイントです。ファイルへの書き込みを禁止したいので、

NG: Writeへのパス指定
{
  "permissions": {
    "deny": [
      "Write(/config/production.yml)"
    ]
  }
}

と書きたくなるかもしれません。しかし現在のClaude Codeでは、ファイルPathを対象とするPermission RuleはEdit(path)Read(path)で評価されます。

Anthropic公式ドキュメントでは、Edit RuleがBuilt-inのファイル編集Tool全体へ適用され、Write(path)NotebookEdit(path)MultiEdit(path)などのPath Ruleは受け付けても実際のPath Permission判定では参照されないと説明されています。つまり、特定Pathへの書き込みを防ぐなら、

OK: Editへのパス指定
Edit(/path/**)

を使用します。たとえば、

複数ディレクトリの保護
{
  "permissions": {
    "deny": [
      "Edit(/database/migrations/**)",
      "Edit(/config/production/**)",
      "Edit(/generated/**)"
    ]
  }
}

とできます。これなら対象PathへのBuilt-in EditやWriteをまとめて制限できます。なお、パスを付けないbareのWriteReadはTool全体の許可・禁止として引き続き有効です。壊れるのはパスを指定したWrite(path)のような書き方だけです。

Readを禁止すると変更も禁止できる

秘密情報の場合は、変更だけではなく読み取りも禁止したいことがあります。たとえば.envsecrets/credentials.jsonなどです。この場合はReadをdenyします。

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Read(.env)",
      "Read(**/.env)",
      "Read(/secrets/**)"
    ]
  }
}

現在のClaude Codeでは、Read denyは同じPathへのEditとWriteもBlockします。つまりClaudeに読ませたくないファイルであれば、Readを拒否することで読み書きの両方を制限できます。

考え方としては、「読ませたいが変更されたくない」ならEditをdeny、「読ませたくも変更されたくもない」ならReadをdenyとすると分かりやすいでしょう。

.envを.gitignoreに入れるだけではAIから守れない

.envをGit Repositoryで管理するとき、

.gitignore
.env

としているケースは多いでしょう。しかし.gitignoreはGitのTracking対象を決めるための仕組みです。ファイルシステムへのReadやWrite Permissionではありません。

つまりAIコーディングツールから見ると、「.gitignoreされている」からといって「読み取れない・変更できない」わけではありません。.envがWorkspace内に存在し、Agentに通常のFilesystem Accessがあれば、中身を参照できる可能性があります。

秘密情報対策では、.gitignoreと「AI AgentへのAccess Control」を別の問題として考える必要があります。Claude CodeならRead(.env)などのdeny Ruleを併用したほうが安全です。

CLAUDE.mdにも「なぜ変更してはいけないか」を書く

Permissionで変更を拒否できる場合でも、CLAUDE.md側にもルールを書いておく意味があります。たとえば、

CLAUDE.md
# Protected Files

`config/production.yml`は本番環境専用設定のため変更しない。

`database/migrations/legacy/`以下の既存Migrationは履歴として扱い、変更しない。

必要な変更がある場合は、新しいMigrationを作成する。

`.env`を読み込まない。

とします。Permissionだけ設定している場合、Claudeは保護Fileを何度も編集しようとして拒否される可能性があります。Instructionsにも理由と代替方法を書いておけば、「既存Migrationは編集できない→新しいMigrationを作る」という正しいアプローチを最初から選びやすくなります。

つまり、CLAUDE.mdは正しい行動へ誘導し、Permissionは間違った行動を阻止するという役割分担です。

GitHub CopilotではCustom Instructionsで変更範囲を伝える

GitHub Copilotでも、.github/copilot-instructions.mdへRepository全体のルールを書けます。たとえば、

.github/copilot-instructions.md
Do not modify existing files under `database/migrations/`.

Do not modify `config/production.yml`.

Never read or modify `.env` files.

If a database schema change is required, create a new migration instead of editing an existing migration.

のようにします。GitHub公式ドキュメントでは、.github/copilot-instructions.mdをRepository-wide Custom Instructionsとして利用でき、Path-specific Instructionsも組み合わせられます。ただしGitHub自身も、AIの非決定性によってInstructionsへの追従が毎回保証されるわけではないと説明しています。そのためCustom Instructionsだけをファイル保護機構として扱うのは避けたほうがよいでしょう。copilot-instructions.md自体の基本的な書き方はGitHub Copilot完全ガイドを参照してください。

Path-specific Instructionsで対象ディレクトリの扱いを説明する

GitHub Copilotでは、.github/instructions/*.instructions.mdを利用して特定Path用のInstructionsを作れます。たとえば.github/instructions/migrations.instructions.mdへ、

.github/instructions/migrations.instructions.md
---
applyTo: "database/migrations/**"
---

Existing migration files are immutable.

Never modify or delete an existing migration.

When a schema change is required, create a new migration.

とします。これによりMigrationを扱うRequestでだけ、より具体的なルールをモデルへ渡せます。Repository全体のInstructionsへ細かい禁止事項を大量に詰め込むより、全体方針と特定Path固有のルールを分離するほうが管理しやすくなります。ただし、これもモデルへのInstructionでありOS Permissionではありません。applyToの書き方や見つからないときの確認手順はGitHub Copilotがcopilot-instructions.mdを無視する原因で詳しく解説しています。

「触らない」ではなく「代わりに何をするか」を書く

AIコーディングでは、禁止だけを伝えるより代替手段を指定したほうが安定します。たとえば、

曖昧な指示
package-lock.jsonは変更しない。

だけでは、依存パッケージを追加するタスクと矛盾する可能性があります。そこで、

具体的な指示
package-lock.jsonを直接編集しない。

依存パッケージの変更が必要な場合はnpmコマンドを使用し、生成されたlockfileの変更はユーザー確認後に残す。

のようにします。Migrationなら「既存Migrationは編集しない。変更が必要なら新しいMigrationを追加する」、Generated Fileなら「generated/以下は直接編集しない。生成元のschemaを変更し、generatorを実行する」とします。AIに禁止だけでなく正しい変更経路を教えることで、Permission Errorを繰り返す可能性を減らせます。

Permissionだけでも完全なOSレベル保護ではない

Claude CodeのPermission Ruleは非常に有効ですが、どの範囲まで保護するか理解しておく必要があります。現在のClaude CodeではReadEditのdeny RuleはBuilt-in File Toolだけでなく、Claude Codeが認識する一部のBash File CommandやRedirect、teeの出力先などにも適用されます。

一方で公式ドキュメントでは、任意のSubprocessが内部でFileを開くようなケースまで、Read/Edit Ruleだけで完全に防げるわけではないことも説明されています。たとえばAgentが

間接的な書き込みの例
python update_config.py

を実行し、そのPython Script内部で対象Fileを書き換えるケースです。独自PythonやNode.js Processが間接的にファイルを読み書きする場合には、Read/Edit RuleだけではOSレベルの制限にはならないため、Sandboxを利用するよう案内されています。つまり、Permission RuleはClaude Code Toolレベルの制御であり、OS Read OnlyはProcessそのものの権限です。

強く守りたいならRead Onlyファイルシステムにする

本当に変更されてはいけないDirectoryなら、AI側の設定だけではなくOS側でRead Onlyにする方法があります。たとえばDocker Container内でAI Agentを動かすなら、保護対象DirectoryをRead Only Bind Mountにできます。

docker run(長い形式)
docker run \
  --mount type=bind,source="$(pwd)/config",target=/app/config,readonly \
  my-ai-dev-image

短い形式なら、

docker run(短い形式)
docker run \
  -v "$(pwd)/config:/app/config:ro" \
  my-ai-dev-image

です。Docker公式ドキュメントでも、Bind Mountへreadonlyまたはroを指定するとContainer側から書き込みできない構成になると説明されています。この場合、AIモデルがどのようなToolを使ったとしても、Container Process自身に書き込み権限がありません。重要度の高いRepositoryでは非常に強力な方法です。Claude CodeをDev Containersでネットワークごと隔離する構成はDev Containers完全ガイドにまとめています。

AIに編集させる範囲だけWrite可能にする

「変更禁止ファイルを1つずつ指定する」のではなく、逆の設計もできます。たとえばAIエージェントへsrc/tests/だけをWrite可能として渡します。それ以外のconfig/infrastructure/secrets/production/はRead Onlyにします。

考え方としては「すべて変更可能→危険なものだけdeny」ではなく、「基本はRead Only→必要な場所だけWrite可能」というAllowlist方式です。AIに大規模な自動変更を任せるほど、この方式のほうが安全性を高めやすくなります。

OSのchmodだけで十分とは限らない

LinuxやmacOSでは、

chmodでRead Onlyにする
chmod 444 config/production.yml

のようにFileをRead Onlyにすることもできます。ただしAI Agentが同じ所有User権限で動いている場合、そのUser自身がPermissionを変更できる環境なら、

再び書き込み可能に戻せてしまう
chmod 644 config/production.yml

として再び書き込み可能にできる場合があります。そのため「chmod 444にしたから絶対に安全」とは限りません。強い境界が必要なら、別User・Container・Sandbox・Filesystem ACL・Mount-level Read Onlyなど、Agent Process自身が解除できない権限境界を作るほうが安全です。WindowsでもNTFS ACLなどでWrite Permission自体を制御するほうが強い保護になります。

Claude CodeではSandboxも組み合わせる

Claude CodeにはPermissionに加えてSandboxがあります。AnthropicはPermissionとSandboxを補完関係として説明しています。PermissionはTool単位やPath単位で「Claude Codeが何を許可するか」を制御し、SandboxはBashなどのProcessへOSレベルのFilesystem・Network制限を与えます。

つまりEdit(/config/production/**)をdenyしながら、Shell ProcessもSandbox外の保護Pathへ書き込めないという二重構成にできます。Prompt Injectionや予想外のShell Scriptまで考慮するなら、このようなDefense in Depthが有効です。Sandboxの有効化手順や対応プラットフォームはセキュリティ完全ガイドで解説しています。

Bashのrmを禁止するだけではファイルを守れない

危険操作対策として、

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Bash(rm *)"
    ]
  }
}

と設定する方法があります。これはrmを防ぐ意味では有効です。しかし「rmを禁止した=ファイルが変更されない」ではありません。ファイルを壊す方法はecho > filesedperlpythonnodeteecpmvなど複数あります。

Bash Permission PatternはCommand Textへ依存するためSecurity Boundaryとしては脆弱であり、Filesystemを確実に制限する場合にはSandboxを利用したほうが確実です。保護したい対象が「Command」ではなく「File」なら、Command名を大量にdenyするよりPathを保護したほうが合理的です。

PreToolUse Hookで変更前に独自チェックする

Permissionだけでは表現しにくい条件にはHookを使えます。たとえば「*.generated.tsは編集禁止」や「database/migrations/の既存ファイルは変更禁止だが、新規ファイル追加は許可」といった複雑な条件です。

Claude CodeにはPreToolUse Hookがあり、Tool実行前に内容を検査できます。Hookの基本的な設定方法(matcher・exit code・JSON入出力など)はHooks完全ガイドで詳しく解説しています。ここではファイル保護に絞った例を示します。

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect-files.sh",
            "args": []
          }
        ]
      }
    ]
  }
}

Hook側でClaude Codeからstdinへ渡されるJSONを読み、tool_input.file_pathを検査します。概念的には次のようにできます。

.claude/hooks/protect-files.sh
#!/bin/bash

INPUT=$(cat)

FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

case "$FILE" in
  */config/production.yml)
    echo "production configuration is read only" >&2
    exit 2
    ;;

  */generated/*)
    echo "generated files must not be edited directly" >&2
    exit 2
    ;;
esac

exit 0

Claude CodeではPreToolUse Hookがexit code 2を返すと、対象Tool CallをBlockできます。Permission Ruleで十分ならそちらのほうがシンプルですが、業務独自ルールを入れたい場合はHookが便利です。

「既存Migrationだけ編集禁止」のような条件はHook向き

PermissionでEdit(/database/migrations/**)をdenyすると、既存ファイルだけでなく新しいMigrationの作成まで制限されます。しかし実際のプロジェクトでは「既存Migrationは変更禁止、新規Migrationは作成可能」というルールが多いでしょう。

このような場合、PreToolUse Hookで対象Pathにすでにファイルが存在するかを確認できます。既存FileならBlockし、存在しないFileなら許可します。概念的には、

既存ファイルだけブロックする
if [ -e "$FILE" ]; then
    echo "Existing migration files are immutable. Create a new migration." >&2
    exit 2
fi

exit 0

とできます。自然言語のInstructionsにも「既存Migrationは不変。変更時は新規Migrationを作る」と書いておけば、AIが最初から正しい方法を選びやすくなります。

Hookだけを唯一のSecurity Boundaryにしない

Hookは非常に便利ですが、完全なOS Security Boundaryではありません。PreToolUse HookはClaude Codeが実行するTool Callを検査する仕組みです。Agent Processとは別の外部Processや、Hook対象外の経路からファイルを書き換えられる環境なら、別途保護が必要です。またHook Script自体が削除・編集可能な状態であれば、強い敵対的環境のSecurity Boundaryとしては不十分です。重要なファイルでは、Permission・Hook・OS Read Onlyと重ねるほうが安全です。

Gitのskip-worktreeを保護機能として使わない

ローカル設定ファイルをGitの変更一覧から外す方法として、

skip-worktreeの例
git update-index --skip-worktree config/local.php

が紹介されることがあります。しかしこれはAIによるファイル変更を防ぐ仕組みではありません。Git公式ドキュメントでは、skip-worktreeの主目的はSparse CheckoutなどのためにWorking Treeの扱いを調整することであり、すべてのGit Commandが完全にこのBitを尊重するわけではないと説明されています。つまり「git statusに出したくない」と「AIに変更させたくない」は別問題です。assume-unchangedも同様にSecurity機能ではありません。skip-worktreeやassume-unchangedの具体的な使い分けは管理からファイルを外す方法で解説しています。

Git Hookは「変更そのもの」ではなくCommitを止める層

AIがファイルを書き換えること自体は許しても、「その変更をCommitしてはいけない」というケースもあります。この場合はGit Hookを使えます。たとえばpre-commitでStaged Fileを検査し、config/production.ymlが含まれていたらCommitを中止できます。

Git公式ドキュメントでは、pre-commit Hookが非0で終了するとCommit自体が中止されます。概念的には、

.git/hooks/pre-commit
#!/bin/bash

if git diff --cached --name-only | grep -q '^config/production.yml$'; then
    echo "config/production.yml must not be committed"
    exit 1
fi

exit 0

とできます。ただしLocal Git Hookは--no-verifyで回避できるため、これだけを最終的な保護にするのは避けたほうがよいでしょう。

CIでも保護ファイルの変更を検出する

チーム開発で特に有効なのがCIでの最終チェックです。AIコーディングツールがローカルのルールを突破したとしても、Pull Request上で「変更禁止ファイルがDiffに含まれている」ことを検出できます。たとえばGitHub Actionsで、

保護ファイルの変更を検出する
git diff --name-only origin/main...HEAD

を取得し、config/production.ymldatabase/migrations/legacy/generated/などが含まれていないか確認します。該当すればWorkflowをFailさせます。これは「AIが変更を試みることを防ぐ」仕組みではありませんが、「禁止変更がMain Branchへ入ることを防ぐ」最後のSafety Netになります。AIツール固有の設定に依存しないのもメリットです。

Branch ProtectionとRequired Checkまで組み合わせる

CIを作っても「失敗しているがそのままMerge」できる状態では最終防御にはなりません。GitHubなどのBranch Protectionで、そのCheckをRequiredにすると、Protected File Checkがパスしない限りMerge不可という構成にできます。AI Coding Agentだけでなく、人間の誤操作も同じルールで止められます。本当に変更禁止のファイルがあるなら、AI専用ルールとして考えるよりRepository Policyとして実装するほうが堅牢です。

Generated Fileは直接編集禁止にして生成元だけ触らせる

AIコーディングで特に事故が起こりやすいのが自動生成ファイルです。たとえばgenerated/api.tssrc/graphql/generated/vendor/dist/などです。AIはコードを見ると普通のSource Fileとして修正してしまうことがありますが、次回のGenerator実行で変更が消えるなら意味がありません。

Instructionsでは、

CLAUDE.md
`generated/`以下を直接編集しない。

変更が必要な場合は`schema/`の生成元を変更し、`npm run generate`を実行する。

とします。さらにClaude Codeなら、

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Edit(/generated/**)"
    ]
  }
}

を設定できます。これにより、説明と技術的禁止の両方を実装できます。

Lockfileは「直接編集禁止」と「変更禁止」を分ける

package-lock.jsonpnpm-lock.yamlも扱いに注意したいファイルです。AIへ「package-lock.jsonを変更禁止」とすると、依存関係を正しく変更できなくなる場合があります。

本当に禁止したいのは「テキストエディタで手書き変更すること」であって、「Package Managerによる再生成」は許可したいケースがあります。この場合はInstructionsで、

CLAUDE.md
Lockfileを直接編集しない。

依存関係を変更する場合はPackage Managerを使用してLockfileを再生成する。

としたほうが適切です。変更が発生した場合にはGit DiffやCIで検証します。すべてをRead Onlyにすればよいわけではなく、ファイルの性質によって保護方法を変える必要があります。

本番設定ファイルはRepositoryから分離する方法もある

そもそもproduction.envproduction-secrets.json・本番用秘密鍵などをAIが作業するRepository内に置かない設計も有効です。AIがアクセスできるWorkspaceに存在しなければ、誤って変更する可能性を大きく減らせます。

本番値はSecret Manager・CI/CD Variables・別Repository・Deployment Environmentなどから注入し、Repositoryには.env.exampleconfig.example.ymlだけを置きます。AIコーディング時にはExample Fileを読み書きさせ、本番値そのものへアクセスさせません。これはファイル保護以前に、Secret Managementとしても望ましい構成です。

AI用の作業コピーを分けるのも有効

既存プロジェクトをAIに大きく変更させる場合、本番作業ディレクトリをそのまま渡さず、Git Worktree・Branch・Container内コピー・一時Workspaceへ分ける方法もあります。たとえばAI専用Worktreeを作り、

AI専用Worktreeの作成
git worktree add ../project-ai ai-work

そこでClaude Codeなどを動かします。仮に大量のFileが変更されても、通常のWorking Treeはそのまま残ります。変更内容を確認してからCommit、Cherry-pick、Mergeできます。これは「変更そのものを禁止する」方法ではありませんが、誤変更による被害範囲を小さくできます。

Read Only環境でもAIに必要な情報は読ませられる

Read Onlyというと「AIが何もできなくなる」ように感じるかもしれません。しかし「参照用Repository」と「作業用Directory」を分ける構成もできます。

たとえばContainer内で/referenceに既存本番コードをRead Only Mountし、/workだけWrite可能にします。AIはReference Codeを読みながら/work/patch/work/generatedへ新しいFileを作れます。その後、人間または別のProcessがDiffを確認して正式Repositoryへ適用します。特に自動実行型のAI Agentでは安全性を高めやすい設計です。

「自動承認」を強くするほどRead Only設計が重要になる

AIコーディングツールでは、Permission Promptを毎回確認するManual運用なら、人間が危険な変更を拒否できます。しかしacceptEditsautobypassPermissionsなど自動化レベルを高めるほど、人間が変更ごとに判断する機会は減ります。

Claude CodeではbypassPermissionsがPermission Promptをスキップする強力なModeであり、公式ドキュメントでもContainerやVMなど隔離環境でだけ使うよう注意されています。企業でこのModeを制限する設定はセキュリティ完全ガイドで解説しています。

夜間の自動処理や長時間Agentなどで承認を減らしたいなら、「AIを信頼する」ことで安全性を保つのではなく、「AIが変更できるFilesystem範囲そのものを狭くする」ほうが堅牢です。

ファイル保護と読み取り保護を混同しない

重要ファイルには大きく2種類あります。たとえばarchitecture.md・API仕様書・production config templateはAIに読ませる価値があります。これらは「Read OK・Write NG」でよいでしょう。

一方、.envprivate-key.pemcredentials.jsonは「Read NG・Write NG」にするべきです。すべてをRead OnlyにするだけではSecretの漏えい対策にはなりません。Secret FileはRead Access自体を禁止するか、最初からAgent Workspaceへ置かない必要があります。

重要度によって保護レベルを変える

たとえばFormatterが生成するFileなら、誤変更されても再生成できます。この程度ならInstructionsだけでも十分な場合があります。既存Migrationなら「Instructions+Edit denyまたはHook+CI」まで入れる価値があります。本番Credentialなら「AI Workspaceに置かない+Read Permission拒否+OS Access Control」のような強い保護が必要です。

すべてのFileに最高レベルのSecurityを付ける必要はありません。変更されたときの影響度を基準にProtection Layerを選ぶと運用しやすくなります。

「AIに見せるが変更させない」が使いやすい

AIコーディングで何でもAccess禁止にすると、AgentがCodebaseを理解できず作業効率が低下します。そのため一般的な設計では「Referenceとして必要→Read可能→Edit不可」というRead Only領域を作るのが使いやすくなります。Claude Codeなら、

参照OK・変更NGの設計
{
  "permissions": {
    "deny": [
      "Edit(/docs/specifications/**)",
      "Edit(/config/production/**)",
      "Edit(/generated/**)"
    ]
  }
}

とできます。一方、Secretsだけは、

読み取りも禁止する設計
{
  "permissions": {
    "deny": [
      "Read(**/.env)",
      "Read(/secrets/**)"
    ]
  }
}

とします。これにより、AgentのContext確保と安全性を両立しやすくなります。

AIコーディングではルールより「変更できない設計」を優先する

Claude CodeのCLAUDE.mdやGitHub Copilotのcopilot-instructions.mdへ「このファイルを変更しない」と書くことには意味があります。モデルが不要な変更を試みる可能性を減らせるためです。しかしInstructionsはSecurity Boundaryではありません。

変更禁止Fileを守るなら、まずInstructionsで「なぜ変更してはいけないか」「代わりに何を変更するか」をAIへ説明します。Claude CodeならEdit(path)Read(path)のdeny Ruleを使って、実際のAccessを制限します。複雑な業務ルールならPreToolUse HookでTool実行前にPathを検査します。さらに強い保護が必要なら、Sandbox、ContainerのRead Only Mount、OS ACLなどでProcess自体のWrite Accessを制限します。最後にGit HookやCIでDiffを検査し、禁止FileがPull Requestへ混入していないか確認します。

特に重要なのは、「AIが変更しないだろう」と期待するのではなく、「AIが変更しようとしても変更できない」状態を作ることです。

AIコーディングの自動化レベルが高くなるほど、プロンプトやInstructionsよりも、Permission、Read Only Filesystem、Sandbox、CIといったシステム側の制約が重要になります。長時間動作するAIエージェントや自動承認を利用するなら、編集可能なWorkspaceを必要最小限へ限定し、保護対象はRead OnlyまたはAccess不可として分離する設計が安全です。

AIコーディングのファイル保護に関するよくある質問

QCLAUDE.mdに「変更しないで」と書くだけでは不十分ですか

Aそれだけでは不十分です。CLAUDE.mdなどのInstructionsはモデルが何をしようとするかに影響しますが、実際に何が実行できるかを決めるのはPermission SystemやSandboxです。長いセッションで指示への追従が弱くなったり、別のInstructionsと競合したりすれば、モデルが変更を試みる可能性があります。重要なFileはEdit(path)などのdeny Ruleと組み合わせてください。

QClaude CodeでWrite(path)を指定してもファイルを保護できないのはなぜですか

A現在のClaude Codeでは、ファイルPathを対象とするPermission Ruleは Edit(path) と Read(path) だけで評価されるためです。Write(path)・NotebookEdit(path)・MultiEdit(path)のようにパスを指定しても、設定自体は受け付けられますが実際の判定には使われません。特定のFileへの書き込みを防ぎたい場合は必ずEdit(path)を使用してください。

Q.envを.gitignoreに入れておけばAIから守れますか

A守れません。.gitignoreはGitの追跡対象を決めるための仕組みであり、ファイルシステムのRead・Write Permissionとは無関係です。AIエージェントに通常のFilesystem Accessがあれば、.gitignoreされていても中身を読める可能性があります。Claude CodeであればRead(.env)などのdeny Ruleを別途設定してください。

QPreToolUse Hookとdeny Ruleはどちらを使うべきですか

A単純に特定のFileやDirectoryへの変更を禁止したいだけならdeny Ruleのほうがシンプルです。「既存Fileだけ編集禁止だが新規作成は許可する」のようにPermission Ruleだけでは表現しにくい条件がある場合にPreToolUse Hookを使うと柔軟に制御できます。両方を組み合わせても構いません。

QchmodでRead Onlyにすれば十分ですか

A弱い保護としては有効ですが、AI Agentが同じUser権限で動いている場合、そのUser自身がPermissionを変更できてしまうため絶対的ではありません。より強い境界が必要な場合は、別User・Container・Sandbox・Filesystem ACL・Mountレベルのread onlyなど、Agent Process自身が解除できない仕組みを使ってください。

Qgit update-index –skip-worktreeでファイルをAIから守れますか

A守れません。skip-worktreeはSparse CheckoutなどのためにGitがWorking Treeをどう扱うかを調整する仕組みであり、書き込みを防ぐPermissionではありません。すべてのGit Commandがこのbitを尊重するわけでもありません。AIによる変更を防ぎたい場合はPermissionやOSレベルのRead Onlyを使ってください。

Q重要なファイルはすべてRead Onlyにしておけば安全ですか

A一律には言えません。architecture.mdや設定テンプレートのようにAIに読ませたいファイルは「Read可能・Edit不可」で十分ですが、.envや秘密鍵のような機密情報はRead自体を禁止するか、そもそもAIが作業するWorkspaceに置かないほうが安全です。ファイルの性質に応じて保護レベルを変える設計が実用的です。