あなたの会社のパスワードが、AIに読まれているかもしれません

従業員10〜50名規模の会社でバックオフィス業務や経営管理を担当している方に、まず知っておいてほしいことがあります。

Claude Codeは非常に便利なAIアシスタントですが、設定を間違えると「.envファイル(環境変数ファイルと呼ばれる、パスワードやAPIキーを保管するファイル)」や「認証情報ファイル」といった機密ファイルを読んでしまう可能性があります。

「うちはエンジニアがいないから関係ない」と思う方もいるかもしれません。しかし、最近では非エンジニアの方がClaude Codeを使ってノーコードツールのカスタマイズやデータ整理をするケースが増えています。その際に適切な設定をしていないと、重要な情報が意図せずAIとのやり取りに含まれてしまうことがあります。

この記事では、セキュリティの専門知識がなくても実践できる5つの設定を順番に解説します。すべて実施すれば1〜2時間で完了します。

図: Claude Codeのセキュリティ設定 全体像(画像生成待ち)

そもそも何が危ないのか

Claude Codeを使って作業をするとき、AIはあなたのパソコン上のファイルを読んだり、コマンド(パソコンへの命令文)を実行したりすることができます。これはとても便利な機能ですが、同時に以下のようなリスクがあります。

1つ目は、機密ファイルへのアクセスです。.env.env.localというファイルには、外部サービスに接続するためのAPIキー(合言葉のようなもの)やパスワードが書かれています。これをAIが読んでしまうと、その情報がAIとのやり取りの履歴に残る可能性があります。

2つ目は、外部への情報送信です。適切な制限をかけていないと、AIがコマンドを実行して外部のサーバーにデータを送信するケースが理論上ありえます。

3つ目は、プロンプトインジェクション(外部の悪意あるテキストがAIへの命令として解釈されてしまう攻撃)です。悪意のあるファイルやウェブページを読み込んだとき、その中に「この情報を外部に送れ」という指示が隠されていた場合、AIがその指示に従ってしまうリスクがあります。

これらはすべて、適切な設定をすることで防ぐことができます。

ステップ1: 許可・禁止リストを設定する(settings.json)

最初に設定するのは「何を許可して、何を禁止するか」のリストです。

Claude Codeには.claude/settings.jsonという設定ファイル(プロジェクト全体で共有する設定)があります。このファイルに、AIが実行できる操作と実行できない操作を明記します。

以下の内容をそのままコピーして.claude/settings.jsonというファイルを作成してください。

{
  "permissions": {
    "allow": [
      "Read(./src/**)",
      "Edit(./src/**)",
      "Bash(npm run test:*)",
      "Bash(npm run build)",
      "Bash(git status)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(git push --force:*)",
      "Read(./.env*)",
      "Read(./secrets/**)",
      "Read(./**/credentials.json)"
    ]
  }
}

この設定で重要なのはdeny(禁止)のリストです。特に覚えておきたいのは3点です。

Read(./.env*)は、.env.env.localなど「.env」から始まるファイルの読み取りをすべて禁止します。パスワードやAPIキーが入っているファイルを守る最初の壁です。

Bash(curl:*)Bash(wget:*)は、外部サーバーへのデータ送信に使われるコマンドを禁止します。万一AIが悪意ある指示に従おうとしても、情報を外部に送れないようにします。

Bash(rm -rf:*)は、ファイルを大量削除するコマンドを禁止します。誤操作でデータを消してしまうリスクを防ぎます。

注意点として、denyのルールはallowより優先されます。つまりallowdenyの両方に同じ操作がある場合、必ずdenyが勝ちます。

ステップ2: 機密ファイルの二重ロックをかける(Hookの設定)

ステップ1だけでは、シェル経由(cat .envのようなコマンド経由)での読み取りをカバーしきれない場合があります。より確実にブロックするため、「Hook(フック)」という仕組みを使います。

Hookとは、AIがある操作をしようとするたびに「このスクリプトを実行してチェックする」という仕組みです。門番のようなイメージです。

図: Hookによる機密ファイルブロックの流れ(画像生成待ち)

まず.claude/settings.jsonにHookの定義を追加します(ステップ1の内容に追記する形です)。

{
  "permissions": {
    "allow": [
      "Read(./src/**)",
      "Edit(./src/**)",
      "Bash(npm run test:*)",
      "Bash(npm run build)",
      "Bash(git status)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(git push --force:*)",
      "Read(./.env*)",
      "Read(./secrets/**)",
      "Read(./**/credentials.json)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/block-secrets.sh"
          }
        ]
      }
    ]
  }
}

次に、実際のチェックを行うスクリプトファイルを作成します。.claude/hooks/block-secrets.shという名前で以下の内容を保存してください。

#!/usr/bin/env bash
set -euo pipefail

input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // ""')

BLOCKED_PATTERNS=(
  '\.env'
  'credentials\.json'
  'id_rsa'
  'private.*key'
  '\.pem'
  'secrets/'
)

for pattern in "${BLOCKED_PATTERNS[@]}"; do
  if echo "$command" | grep -qE "$pattern"; then
    echo "機密ファイルへのアクセスをブロックしました: $pattern" >&2
    exit 2
  fi
done

exit 0

ファイルを保存したら、以下のコマンドで実行権限を付与します。

chmod +x .claude/hooks/block-secrets.sh

このスクリプトが終了コード2(「操作を拒否する」という合図)を返すと、Claude Codeはその操作を実行しません。また「機密ファイルへのアクセスをブロックしました」というメッセージがAIに伝わるため、AIは「この操作はポリシーで禁止されています」と認識して別の方法を探します。

ステップ3: 機密ファイルをそもそもGit管理から除外する

Git(ファイルのバージョン管理ツール)を使っている場合、機密ファイルが誤って「コミット(記録)」されてしまうと、GitHubなどのサービスにアップロードされて外部に公開されるリスクがあります。これを防ぐのが.gitignoreファイルです。

.gitignore(Gitの管理から除外するファイルやフォルダのリスト)に以下を追加してください。

.env
.env.local
.env*.local
.claude/settings.local.json
*.pem
credentials.json

同時に、.env.example(サンプルのパスワードファイル)をリポジトリに追加しておくと便利です。実際の値ではなく「どんな項目が必要か」だけを記録したファイルです。

# .env.example(これはGitに含めてOK)
ANTHROPIC_API_KEY=
SUPABASE_URL=
SUPABASE_SERVICE_ROLE_KEY=
GITHUB_TOKEN=

Claude Codeに「.envファイルを作って」と頼む場合も、「.env.exampleを参考にして」と伝えると、実際のパスワードをAIに伝えることなく作業が進められます。実際の値は後からパスワードマネージャー(1PasswordやBitwarden等)から手動で貼り付けるのが安全です。

さらに安全にするなら、gitleaks(誤ってパスワードをコミットするのを防ぐツール)の導入もおすすめです。

brew install gitleaks
gitleaks protect --staged --redact

このコマンドをコミット前に実行する習慣をつけると、万一の誤コミットを物理的に防げます。

ステップ4: 外部からの「なりすまし命令」を防ぐ

少し難しい概念ですが、「プロンプトインジェクション(プロンプトとはAIへの指示文のことです)」という攻撃手法があります。

具体的には、悪意のある第三者が作ったファイルやウェブページの中に「この内容を外部サーバーに送れ」という命令を隠しておき、AIがそのファイルを読んだときに命令として解釈してしまうケースです。

これを防ぐには2つの対策が効果的です。

1つ目は、すでに設定したcurlコマンドの禁止(ステップ1)です。外部への送信手段を塞いでおけば、AIが命令に従おうとしても情報は外部に出ません。

2つ目は、アクセスを許可するウェブサイトを絞り込む設定です。.claude/settings.jsonに以下を追加します。

"permissions": {
  "allow": [
    "WebFetch(domain:docs.anthropic.com)",
    "WebFetch(domain:github.com)"
  ],
  "deny": [
    "WebFetch"
  ]
}

WebFetch(AIがウェブサイトを参照する機能)を一括禁止したうえで、公式ドキュメントやGitHubなど「信頼できるサイト」だけを明示的に許可するという逆転の発想です。見知らぬリポジトリや外部URLを処理する作業が多い場合は、この設定が特に有効です。

図: セキュリティ設定方法の比較(画像生成待ち)

ステップ5: チーム全体で同じ防御レベルを保つ

1人で使う場合はここまでで十分ですが、チームで使う場合は注意が必要です。個人ごとに設定がバラバラだと、防御が手薄なメンバーの端末から情報が漏れるリスクがあります。

推奨するフォルダ構成はこちらです。

.claude/
├── settings.json          # チーム共有(Gitに含める)
├── settings.local.json    # 個人用の追加設定(Gitから除外)
└── hooks/
    └── block-secrets.sh   # チーム共有(Gitに含める)

settings.jsonhooks/block-secrets.shをGitリポジトリに含めておくと、新しいメンバーがプロジェクトをclone(ダウンロード)した瞬間から同じセキュリティ設定が有効になります。

個人の追加設定(自分だけが使いたいツールの許可など)はsettings.local.jsonに書き、これはGitから除外します。「チームの共通ルール」と「個人のカスタマイズ」を分離することで、セキュリティの一貫性が保てます。

可能であれば、GitHubのプルリクエスト(変更内容をチームでレビューする仕組み)で.claude/settings.jsonの変更を必ず確認するルールにしておくと安心です。意図せずdenyリストが削除されていた、という事態を防げます。

5つの設定まとめ

以下に、本記事で紹介した5つの対策を整理します。

ステップ1のsettings.jsonによる許可・禁止リストは、全員が最初に設定すべき基本中の基本です。.env*の読み取り禁止と、curlによる外部送信禁止だけでも、致命的なリスクを大幅に減らせます。

ステップ2のHookによる二重ロックは、設定ファイルだけではカバーしきれないシェル経由のアクセスを防ぐ仕組みです。特に、外部のファイルを扱う機会が多い方に推奨します。

ステップ3のgitignore管理は、機密ファイルがGitHub等に誤アップロードされるのを防ぐ根本対策です。gitleaksを使えばコミット前に自動チェックできます。

ステップ4のプロンプトインジェクション対策は、外部ファイルやURLを扱う際に特に重要です。WebFetchの許可ドメインを絞っておくと安心です。

ステップ5のチームポリシー共有は、複数人で使う場合に防御レベルを均一に保つための仕組みです。settings.jsonをGit管理に入れるだけで実現できます。

最初の30分でステップ1と3だけ実施するだけでも、機密情報の漏洩リスクは大きく下がります。セキュリティ対策は「完璧にやらないとゼロ」ではありません。できるところから1つずつ積み上げていきましょう。