1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code の社内導入で情シスに聞かれる3つの質問に、管理設定と実機検証で答える

1
Posted at

Claude Code を職場で使おうとすると、情シスやセキュリティ担当からよく聞かれる質問があります。たとえばこちらの Qiita 記事では、情シスに必ず聞かれる質問として次の3つが挙げられています。導入の苦労を書いた他の記事でも、同じ種類の質問が繰り返し出てきます。

  1. 危険な操作を勝手にされないか
  2. AI が何をしているか見えるか
  3. 何かあったとき説明できるか

その手前で必ず「コードは学習に使われないのか」も聞かれます。

「CLAUDE.md に禁止と書いてあります」では答えになりません。あれはお願いで、強制力がないからです。この記事では、利用者が上書きできない管理設定(managed settings) で答えます。実際に効くかどうかは手元で試しました。どこまで止まり、どこから止まらないかも、試した結果のとおりに書きます。

  • 検証環境:Claude Code 2.1.294、Linux(コンテナ、root で実行)、claude -p(非対話モード)、2026-10-08
  • 方法:使い捨てのプロジェクトにダミーの .env・削除用のディレクトリ・ローカルの push 先を置き、条件ごとに作り直して1回ずつ実行しました

前提:管理設定とは

管理設定は、端末の管理者が置く設定ファイルです。利用者自身の設定(~/.claude/settings.json)、プロジェクトの設定、起動時の --settings のどれを使っても上書きできません。公式の説明は「Nothing in your own settings files or --settings overrides a managed key」です(settings)。

OS 置き場所
macOS /Library/Application Support/ClaudeCode/managed-settings.json
Linux・WSL /etc/claude-code/managed-settings.json
Windows C:\Program Files\ClaudeCode\managed-settings.json

出典:managed-settings(2026-10-08 確認)。MDM で配ることもできます。Team / Enterprise プランなら、claude.ai の管理画面から全員に配る方式もあります(server-managed-settings)。

質問0:コードは学習に使われるのか

答えは 契約の種類で変わります。ここを曖昧にしたまま話を進めると、後でこじれます。

契約 モデルの学習への利用 Anthropic 側の保持期間
商用(Team / Enterprise / API) 使わない(明示的に参加を申し込んだ場合を除く) 標準 30 日。ゼロデータ保持(ZDR)は Enterprise の対象組織だけで、組織ごとに有効化
個人向け(Free / Pro / Max) 本人の設定しだいで使われる 学習を許可すると 5 年、許可しないと 30 日

出典:data-usage(2026-10-08 確認。規約は変わるので、提出前に最新版を確認してください)。

情シスに伝えるべき点は2つです。

  • 個人契約のまま業務コードを扱わないことが最初の線引きになります
  • 手元の PC にも会話が ~/.claude/projects/ に平文で残ります(既定 30 日、cleanupPeriodDays で変更可。デスクトップ版・Cowork のセッションは別の設定)。端末の紛失対策の範囲に入れておきます
  • 「30 日」には例外があります。/feedback(/bug・/share も同じ経路)で送った会話は 5 年保持されます。セッション後のアンケートで会話の共有に「Yes」と答えると、ソースコードを含む会話が送られ、最大 6 か月保持されます。止めるには環境変数 DISABLE_FEEDBACK_COMMAND=1 と CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 を管理設定の env で配ります(同ページ。この2つは今回試していません)

質問1:危険な操作を勝手にされないか

管理設定の deny は、利用者の許可より優先された

まず比較用に、管理設定なしで、起動オプション --allowedTools で rm -rf victim・git push・cat を許可しました。指示どおり3つとも実行され、.env の中身も出力に出ました。

次に、同じ許可のまま管理設定に次を置きました。

{
  "permissions": {
    "deny": ["Bash(rm -rf:*)", "Bash(git push:*)", "Read(./.env)", "Read(**/.env)"]
  }
}
試したこと 結果
rm -rf victim 拒否(ディレクトリは残った)
git push origin HEAD:main 拒否(push 先にコミットは届かず)
cat .env 拒否(中身は出ず)
echo start && git push origin HEAD:main(複合コマンド) 拒否

利用者がその場で許可しても、管理設定の deny が勝ちました。

なお Bash(rm -rf:*) は「rm -rf で始まるコマンド」に一致する書き方で、書き方の揺れを吸収しません。追加で試した結果(2026-10-11、Claude Code 2.1.296):

deny 実行させたコマンド 結果
Bash(rm -rf:*) rm -rf victim 拒否
Bash(rm -rf:*) rm -fr victim 実行されて消えた
Bash(rm -rf:*) rm -r -f victim 実行されて消えた
Bash(rm:*) rm -r -f victim 拒否
Bash(git push --force:*) git push -f origin HEAD:main push された
Read(**/.env) cat .env.local 値が出力された

実際に配るときは、rm や git push は全体を deny か ask に入れ、.env は Read(**/.env.*) も足してください。手元の設定にこうした穴がないかは、設定チェッカーに貼るとまとめて確認できます。

さらに allowManagedPermissionRulesOnly: true を足すと、利用者側の allow(許可)ルールそのものが無視されます。--allowedTools "Bash(rm -rf victim)" を付けても、確認待ちとして止まりました。

確認を全部飛ばす --dangerously-skip-permissions は、"disableBypassPermissionsMode": "disable" で使えなくなります(permissions)。これは今回試せていないので、公式の記述として載せます。

落とし穴:Read の deny だけでは、秘密ファイルは守れない

上の設定のまま、別の読み方を試しました。

試したこと 結果
python3 -c "print(open('.env').read())" .env の中身が出力された
grep -r DUMMY . .env の中身が出力された

これは不具合ではなく仕様です。公式も、Read の deny は cat などには効くが、別のプロセスが間接的に読む場合には効かないと書いています(「They don't apply to… arbitrary subprocesses that read or write files indirectly」、permissions)。

ちなみに、ネットでときどき見かける .claudeignore は公式の機能ではありません。置いても効きません(同ページ「has no effect」)。

サンドボックスを有効にしたら、OS レベルで止まった

管理設定にサンドボックスを足しました。

{
  "permissions": { "deny": ["Read(**/.env)"] },
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "autoAllowBashIfSandboxed": false
  }
}

同じ python3 と grep -r を(起動オプションで許可したうえで)試すと、どちらも Permission denied で失敗し、中身は出ませんでした。サンドボックスは Read の deny ルールの対象パスも読めなくしていました。(この2つは autoAllowBashIfSandboxed の行を足す前に試しました。足した後の完成形でも python の読み取りは失敗します)

設定の意味は次のとおりです(sandboxing)。

  • failIfUnavailable:サンドボックスを起動できない環境では、Claude Code 自体を起動しない。これを付けないと、サンドボックスなしで黙って動きます
  • allowUnsandboxedCommands: false:失敗したコマンドを、サンドボックスの外で再試行させない
  • autoAllowBashIfSandboxed: false:これを忘れると逆効果になります。既定値は true で、サンドボックスの中で動く Bash コマンドは確認なしで実行されます(settings-reference)。実際、既定値のままでは、許可していない rm victim/a.txt が確認なしで実行され、ファイルが消えました。false にすると拒否されました(非対話モードでは確認できないため拒否になります)。止まるのは deny に書いたものだけ、ではなく、通常の確認の流れに戻すための設定です

使える OS は macOS・Linux・WSL2 です。Windows ネイティブと WSL1 では使えません。Linux・WSL2 では bubblewrap と socat が必要です。また、ファイル操作ツール・MCP・hooks はサンドボックスの外で動きます。

もう1つ注意があります。サンドボックスの設定には、利用者が自分の設定で広げられるものがあります。公式は excludedCommands(サンドボックスの外で動かすコマンド)や filesystem.allowWrite について「have no managed-only lock」と書いています(sandboxing)。たとえば利用者が python3 を除外すれば、上の読み取りはまた通るはずです(公式の記述からの推論で、試してはいません)。サンドボックスは「うっかり」や AI の暴走を止める柵で、利用者本人の意図的な回避まで防ぐものではありません。

質問2:AI が何をしているか見えるか

管理設定のフックで、拒否された試みまで記録できた

ツールを使う直前に呼ばれる PreToolUse フックで、入力を1行ずつファイルに追記しました。allowManagedHooksOnly: true を付けると、利用者やプロジェクトが足したフックは動かなくなります。

試した結果は次のとおりです。

  • 利用者が --settings で足したフックは動かなかった。allowManagedHooksOnly を外した比較では動いた
  • 記録には実行したコマンドだけでなく、拒否された rm -rf と git push も残った

記録された1行の例です(値は短くしています)。

{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git push origin HEAD:main","description":"..."},"permission_mode":"default","session_id":"...","cwd":"..."}

この記録には、Bash コマンドの引数や、ファイルに書き込んだ内容もそのまま入ります。秘密情報を含みうるファイルとして、権限と保管期間を決めておきます。

組織全体で集めるなら OpenTelemetry

フックの記録は端末の中に残るので、利用者が消せます。組織として集めるなら OpenTelemetry です(monitoring-usage)。

  • 有効にする:CLAUDE_CODE_ENABLE_TELEMETRY=1 と送り先(OTEL_METRICS_EXPORTER、OTEL_LOGS_EXPORTER、OTEL_EXPORTER_OTLP_ENDPOINT)を設定する。管理設定の env で全員に配れる
  • 分かること:セッション数、コストとトークン数、コミット数・PR 数、ツールの実行と許可・拒否のイベント
  • 既定で記録されないもの:プロンプト本文(OTEL_LOG_USER_PROMPTS)と、Bash コマンドなどのツール引数(OTEL_LOG_TOOL_DETAILS=1 で記録される)

「入力した内容を管理者に読まれるのか」もよく聞かれる質問です。既定では読まれず、設定すれば記録できる、が正確な答えです。どちらにするかは規程で決めて、利用者に知らせておきます。

質問3:何かあったとき説明できるか

ここは設定1つで解決するものではありません。説明に使える材料をそろえておく、というのが答えになります。

  • 何を止めているか:管理設定のファイルそのもの。誰でも読める場所に置く
  • 何が起きたか:フックの記録、または OpenTelemetry のイベント。それに git の履歴
  • 何を止めていないか:下の「限界」を、先に書面で伝えておく

3つ目が一番大事です。「全部防げます」と言ってから穴が見つかるより、「ここまでは止まり、ここからは止まらない」を先に出すほうが信用されます。

今回の設定の完成形

上の検証を1つにまとめたものです。このファイルで、git push の拒否、python による .env 読み取りの失敗、許可していない rm victim/a.txt の拒否、許可した ls の実行、拒否分を含む記録を確認しました(2.1.294、Linux)。rm は、上の追加検証を受けて Bash(rm -rf:*) から Bash(rm:*) に変えています(rm -fr・rm -r -f も拒否されることを 2.1.296 で確認)。

認証情報の保護をさらに広げたい場合は、公式リポジトリの設定例(examples/settings/settings-hipaa.json)が、~/.git-credentials・~/.netrc・~/.config/gh などの読み書きの拒否や、環境変数の秘密を隠す設定まで含んでいるので、あわせて参考にしてください。

managed-settings.json
{
  "permissions": {
    "deny": [
      "Bash(rm:*)",
      "Bash(git push:*)",
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "autoAllowBashIfSandboxed": false
  },
  "allowManagedHooksOnly": true,
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "mkdir -p \"$HOME/.claude-audit\" && (cat; echo) >> \"$HOME/.claude-audit/tool-use.jsonl\"" }
        ]
      }
    ]
  }
}

記録のフックは入力をそのまま書くので、Write で書いた中身やコマンド中のトークンも記録に残ります(実測)。記録を見せる・残す前提なら、中身を書かずにツール名・コマンド・ファイル名だけを選んで書く形にしてください。

git push まで禁止すると困るチームも多いはずです。deny に何を入れるかは、チームの運用に合わせて選んでください。Read(**/.env.*) は .env.example も読めなくするので、テンプレートを読ませたい場合は調整してください。

情シスに渡す回答表(ひな形)

質問 答え 根拠(設定・文書) 限界
コードは学習に使われるか 商用契約(Team / Enterprise / API)では使われない。標準の保持期間は 30 日 data-usage(確認日を書く) 個人契約では設定しだい。/feedback で送った会話は 5 年保持(環境変数で止める)
危険な操作を勝手にされないか 管理設定の deny で拒否。利用者は上書きできない managed-settings.json パターンに合わない書き方は通りうる。deny は「うっかり」を防ぐ柵
秘密ファイルを読まれないか Read の deny+サンドボックスで OS レベルで拒否 sandbox 設定 Windows ネイティブ・WSL1 ではサンドボックスが使えない。利用者が自分の設定で除外コマンドを足すと外れうる
何をしているか見えるか ツールの実行を記録(拒否分も含む)。組織では OpenTelemetry で収集 hooks/env 設定 プロンプト本文は既定で記録しない(記録するかは規程で決める)。記録ファイル自体が秘密を含みうる
何かあったとき説明できるか 設定ファイル・記録・git 履歴で説明する 上記一式 端末内の記録は利用者が消せる

限界と注意(ここまで含めて伝える)

  • 使う製品によって、管理設定の届き方が違います。公式によると、Cowork は管理画面からの配信(server-managed settings)を受け取りません。端末の管理設定ファイルは読みますが、VM サンドボックスで動かす場合とリモートの Cowork では読まれません(managed-settings)。Anthropic のクラウドで動くセッションも、端末のファイルではなく管理画面からの配信だけが効きます
  • 管理設定が期待どおりに効かないという報告もあります(例:管理設定の env で配った OpenTelemetry の変数が効かない #67657、Cowork で hooks が効かない #40495。どちらも未検証)。今回確かめたのは CLI だけです。デスクトップ版・IDE 拡張・Cowork を使わせるなら、それぞれで確かめてください
  • WSL では /etc/claude-code を利用者が書き換えられます(公式に明記、managed-settings)。WSL を強制の手段にはできません
  • deny はパターンマッチです。今回は複合コマンドでも止まりましたが、書き方しだいで通るものがありえます。止めたいものは複数の層(deny、サンドボックス、git のブランチ保護)で止めます
  • 今回の検証は各条件1回、Linux の CLI だけです。版が上がったら試し直してください

手元の設定に、ここで見たような穴がないかは、無料の設定チェッカーに貼るとまとめて確かめられます:https://acerola-tools.acerola.workers.dev/check/?from=qiita-claude-code-managed-settings-security-qa
本記事は Zenn にも掲載しています:https://zenn.dev/acerola_jp/articles/claude-code-managed-settings-security-qa

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?