Claude Media
Claude CodeのpolicyHelperで管理ポリシーを動的に取得する設定

Claude CodeのpolicyHelperで管理ポリシーを動的に取得する設定

policyHelperの仕組みとmanaged-settings.jsonでの登録手順、起動時にセッションを拒否する失敗時の挙動をまとめます。

policyHelperは、Claude Codeの管理ポリシー(managed settings)を静的なファイルではなく実行ファイルの出力から組み立てる設定です。起動のたびにデバイスの状態や識別情報をもとにポリシーを計算し直せます。managed-settings.jsonを書き換える運用では対応しづらい「デバイスごとに条件分岐するポリシー」が組めます。設定できるキーはpath・timeoutMs・refreshIntervalMsの3つで、macOSの構成プロファイル・WindowsのHKLMレジストリ・managed-settings.jsonのいずれかに書きます。

Claude CodeのpolicyHelperとは何か

policyHelperとは、組織が配置した実行ファイルをClaude Codeが起動時に呼び出し、その標準出力をそのセッションの管理ポリシーとして扱う仕組みです。静的なJSONファイルでは表現しにくい「このデバイスは会社支給か」「このユーザーはどの部署か」といった条件を、ヘルパー側のロジックで判定してポリシーに反映できます。

Claude Codeはヘルパーを最初のプロンプトを受け付ける前に実行します。デフォルトでは起動時に1回だけ動きます。refreshIntervalMsを設定した場合だけバックグラウンドで再実行されます。設定を配らない限りヘルパーは動きません。既定値は「unset」で、この状態では通常の静的な管理ポリシーがそのまま使われます。

事前に確認すべき前提条件

policyHelperのスコープはManagedです。ただし読み込まれる配信元は3つだけです。macOSの構成プロファイル、WindowsのHKLMレジストリ、そしてmanaged-settings.jsonです。Claude Codeは既定(first-wins)では複数の管理ソースがある環境で最優先の配信元を1つだけ選び、そこにpolicyHelperキーがあるときだけヘルパーを実行します。managedSourcesBehavior"merge"にした場合(v2.1.242以降)は、配布したすべての管理ソースが1つのポリシーに合成されます。

サーバー管理設定(claude.aiのadminコンソールやゲートウェイ経由)がポリシーを配信している場合、その配信元が優先されヘルパーは起動しません。あとからサーバー管理設定が外れたことを検知すると、次回起動を待たずにその場でヘルパーが実行されます。HKCUレジストリと、埋め込みホスト(Claude Desktopなど)が渡すparent settingsからはpolicyHelperキー自体が読まれません。この2つの経路だけでポリシーを配る組織には向きません。

以下は配信元ごとにヘルパーが動くかどうかの早見表です。

配信元ヘルパーは動くか補足
macOSの構成プロファイル(plist)ヘルパーは動くか動く補足com.anthropic.claudecodeドメインに書く
WindowsのHKLMレジストリヘルパーは動くか動く補足HKLM\SOFTWARE\Policies\ClaudeCodeSettings
managed-settings.json(ファイル配信)ヘルパーは動くか動く補足3系統のうち最も導入しやすい
claude.aiのサーバー管理設定ヘルパーは動くか動かない補足この配信元が選ばれるとヘルパーより優先される
WindowsのHKCUレジストリヘルパーは動くか動かない補足policyHelperキーを読まない配信元
埋め込みホストのparent settingsヘルパーは動くか動かない補足Claude Desktop等が渡す値は対象外

Coworkのセッションでは、動く面がさらに絞られます。ユーザーの手元マシンで動くCoworkセッションはMDMポリシーとmanaged-settings.jsonをそのまま読むため、policyHelperは通常どおり動きます。一方、requireCoworkFullVmSandboxを設定した完全VMサンドボックス内のセッションと、Anthropic管理のVM上で動くリモートCoworkセッションには、デバイス側のMDMポリシーもmanaged-settings.jsonも存在しません。この2つの面では、policyHelperを配ってもヘルパーは呼ばれません。組織にCoworkの利用者がいる場合は、どの実行形態で動いているかを先に確認します。

ヘルパー実行ファイルを書く

ヘルパーは引数なしで実行され、環境変数CLAUDE_CODE_VERSIONを受け取ります。標準出力には1つのJSONオブジェクトを書き、managedSettingsキーの下に実際のポリシーを入れます。managedSettingsキーを持たないオブジェクトを返すと、ヘルパーの出力からはポリシーが適用されず、MDM・ファイルなど他の配信元の管理ポリシーが通常どおり適用されます(エラーも出ません)。動作確認時は必ずmanagedSettingsキーの有無から見直します。

{
  "managedSettings": {
    "permissions": { "deny": ["Read(//etc/secrets/**)"] }
  }
}

出力されたJSONのmanagedSettingsオブジェクトが、そのセッションで使う唯一の管理ポリシーになります。他の配信元は無視されます。通常なら複数の管理ソースから横断的に読まれるキー(サンドボックスのロック系キーやenvのマージなど)も、ヘルパーの出力からしか読まれなくなります。例外はforceRemoteSettingsRefreshで、これだけは起動時の専用ルールに従います。Claude Desktopのようなホストアプリが渡すparent settingsも、ヘルパーが有効な間は一切マージされません。parentSettingsBehaviormergeにしていても無効になるので、Cowork等でホスト側の権限ルールをあてにしている構成では影響を確認します。

managed-settings.jsonでpolicyHelperを登録する

登録の起点はpolicyHelperキーです。持つフィールドは3つだけです。path(必須)、timeoutMs(既定10000ミリ秒、最小1000ミリ秒)、refreshIntervalMs(既定は未設定=起動時のみ実行、設定するなら0か60000ミリ秒以上。0を指定すると再実行そのものを無効化する値として扱われます)です。

{
  "policyHelper": {
    "path": "/usr/local/bin/claude-policy",
    "timeoutMs": 5000,
    "refreshIntervalMs": 300000
  }
}

pathは正規化された絶対パスで、...を含められません。WindowsではドライブレターまたはUNCパスで、.exe拡張子が必須です。この形式から外れると無効なエントリとして扱われます。ヘルパーは起動せず、残りの管理ポリシーだけで起動します。refreshIntervalMsを設定すると、成功した再実行のたびに管理ポリシーがセッションを再起動せずに置き換わります。失敗した再実行はそのポリシーを維持し、直前まで有効だった内容で動き続けます。

ヘルパーを無効化したいときは、設定した配信元からキーそのものを削除します。無効化用の専用フラグはありません。

複数チームがmanaged-settings.d/にファイルを分けて配置している場合は注意が必要です。policyHelperは単一値のキーなので、アルファベット順で後に読まれるファイルの値が前のファイルの値を丸ごと置き換えます。マージはされません。同じディレクトリに2つのチームがそれぞれ別のヘルパーを指定すると、意図せず片方だけが有効になります。

起動時と再実行時の挙動を確認する

失敗と判定される条件は次のいずれかです。

  • pathの形式が不正
  • pathに通常ファイルが存在しない
  • ヘルパーが非ゼロ終了する
  • timeoutMs以内に終了しない
  • 実行できない(実行権限がないなど)
  • 標準出力または標準エラー出力が1MiBを超える
  • 標準出力が単一のJSONオブジェクトでない
  • managedSettingsのスキーマ違反が修復できない

非ゼロ終了時はヘルパーの標準エラー出力(それが空なら標準出力)を理由に含めます。タイムアウト時はヘルパーの出力を一切含めず、timeoutMsの上限値だけを理由として示します。バックグラウンドの再実行が失敗した場合はセッションを止めず、直前に成功したポリシーを保持したまま/statusにその再実行の失敗理由を表示し続けます。

/statusを実行すると、選ばれた配信元がヘルパー経由かどうかを確認できます。ヘルパー由来のときはSetting sourcesの行に(helper)と表示されます。

claude doctor

claude doctorは無効なエントリを配信元とフィールドつきで一覧にします。ポリシーが意図どおりに配られていないときは、まずこのコマンドで却下されたエントリの有無を確認します。対話セッションでは起動時に無効なエントリを列挙するダイアログも表示されます。-pでの非対話実行では、同じ内容が標準エラー出力への要約として出ます。

--debugを付けて起動すると、毎回のヘルパー実行の標準エラー出力がデバッグログに書き込まれます。ヘルパーが失敗はしないものの期待どおりのポリシーを返していないような、ヘルパー自体の不具合を追うときの唯一の手掛かりになります。

よくあるつまずき

  • managedSettingsキーを付け忘れると、ヘルパーの出力からはポリシーが適用されず、MDMやファイルなど他の配信元の管理ポリシーが通常どおり適用されます(エラーも出ません)
  • pathを相対パスで書く、または./..を含めると、無効なエントリとしてヘルパーなしで起動します(パス形式のチェックはコマンドの成否より先に行われます)
  • timeoutMsを最小値の1000ミリ秒未満にすると、これも無効な値として扱われます
  • ヘルパーの出力が1MiBを超えると、内容に関わらず失敗として扱われます
  • サーバー管理設定が有効な組織では、managed-settings.jsonpolicyHelperを書いてもヘルパーは動きません。動かないことを不具合と早合点する前に、/statusの配信元表示を確認します
  • 障害時にセッションが起動できなくなるのは仕様です。ヘルパー自身に可用性が求められる場合は、リモート呼び出しではなく自前のキャッシュから返してexit 0で終わらせる設計にします
  • refreshIntervalMsを設定しなければ、ヘルパーは起動時の1回しか実行されません。ポリシーの変更を稼働中のセッションへ届けたい場合は明示的な設定が必要です

policyHelperと他の配信手段をどう使い分けるか

組織全体でのmanaged settingsの配布方法、availableModelsによるモデル制限、requiredMinimumVersionによるバージョン強制など、より広い統制の設計はClaude Code組織管理ガイドにまとまっています。ここではその中の1つの配信手段であるpolicyHelperの設定に絞っています。

管理設定が壊れた状態での起動拒否という挙動自体は、policyHelper固有のものではありません。通常の管理ポリシーが不正な形式のときの扱いはClaude Code v2.1.259のリリースノートで扱った起動拒否の変更と同じ系統の設計です。

MDMを使った配布の具体的な手順(macOSの構成プロファイルやWindowsのレジストリへの書き込み)は、Claude Code Desktop SSOとデバイス管理ポリシーの設定で扱っています。

まとめ

policyHelperは、静的なファイルでは表現できないデバイスごと・ユーザーごとの条件分岐をポリシーに持ち込みたい管理者向けの設定です。設定できるキーはpathtimeoutMsrefreshIntervalMsの3つだけで、動くのはMDMプロファイル・HKLMレジストリ・managed-settings.jsonのいずれかが選ばれたときに限られます。サーバー管理設定が優先される組織や、HKCU・parent settingsだけでポリシーを配りたい組織では、この設計は選択肢になりません。

導入する前に押さえておくべきは、起動時の失敗がセッションそのものを止めるという一点です。ヘルパーをリモートのAPI呼び出しに直結させると、そのAPIの障害がそのまま全社のClaude Code起動障害になります。自前のキャッシュから返す設計にしておけば、この種の障害を避けられます。すでにmanaged settingsを配布している組織で、デバイスの属性ごとにポリシーを変えたいという要件が出てきた段階で検討するのが妥当です。

この記事を共有:XはてブLinkedIn