enforceAvailableModelsでDefaultモデルの抜け穴を塞ぐ — Claude Code
enforceAvailableModelsはavailableModelsだけでは効かないDefaultモデルの選択を許可リストの範囲に収める設定です。個人設定での使い道と、設定を間違えたときの倒れ方まで扱います。
enforceAvailableModelsは何を解決する設定か
enforceAvailableModelsは、モデルピッカーの「Default」オプションが解決する先まで、availableModelsの許可リストの範囲に収める設定です。単独では動かず、availableModelsと組み合わせて初めて効きます。Claude Code v2.1.175以降で使え、既定値はfalseです。
有効化すると、Defaultが許可リスト外のモデルへ解決される構成では、許可リストの先頭にあるモデルへ自動で切り替わります。falseのまま(既定)なら、Defaultは従来どおりアカウント種別のランタイム既定値にそのまま解決され、許可リストの外側にあっても素通りします。availableModelsだけを先に配って様子を見て、影響範囲を確認してからenforceAvailableModelsを有効にする、という段階導入もこの既定値のおかげで選べます。Defaultの実体がアカウント種別でどう変わるかや、有効化前後の詳しい比較はClaude Code v2.1.175の解説にまとめてあります。ここではenforceAvailableModelsという設定キー自体の挙動と、個人利用での使い道に絞ります。
なぜavailableModelsだけでは足りないのか
availableModelsは、モデルを名指しする経路のほぼ全てに効きます。/model・--modelフラグ・ANTHROPIC_MODEL環境変数、サブエージェントやスキルのfrontmatter、フォールバックチェーンまで対象です。ただし効くのは名指しされた選択だけです。
モデルピッカーの「Default」は、組織が既定モデルを別途指定していない限り、アカウント種別のランタイム既定値にそのまま解決されます。この経路はavailableModelsの対象に含まれません。許可リストにsonnetとhaikuしか入れていなくても、利用者が何も選ばず「Default」のままセッションを始めると、許可リストの外にあるOpusが使われる余地が残ります。この抜け穴を塞ぐのがenforceAvailableModelsの役割です。
個人の設定でも組織の管理設定でも使える
多くの解説は組織のmanaged-settings.json前提で書かれますが、enforceAvailableModelsのスコープはavailableModelsと同じ「Any file」です。ユーザー設定・プロジェクト設定・ローカル設定・管理設定のどこに書いても読み込まれます。
ただし、組織がなんらかの管理設定を配布している環境では話が変わります。Claude Codeはこのキーを管理設定ソースからだけ読み、他のファイルに書いた値を無視します。個人の設定で上書きしようとしても効きません。
管理設定が一切ない個人利用では、この制約は当てはまりません。~/.claude/settings.jsonにavailableModelsとenforceAvailableModelsを自分で書けば、コスト管理のために自分自身のDefaultを安価なモデルへ固定する、といった使い方ができます。並行してセッションを何本も走らせているとき、うっかりDefaultのままOpusクラスのモデルで長時間タスクを回してしまう、という事故を防ぐ効果もあります。
Defaultだけを絞りたいが、必要なときは自分で高いモデルへ手動で切り替えたい、という場合はリストに複数のモデルを並べます。
{
"availableModels": ["haiku", "sonnet", "opus"],
"enforceAvailableModels": true
}enforceAvailableModelsが参照する「最初の許可モデル」はリストの並び順で決まるので、この例ではDefaultがhaikuに固定されます。一方でhaiku・sonnet・opusはいずれも許可リストに含まれているため、/model opusのように名指しで選ぶこと自体は引き続きできます。普段は安く、必要なときだけ手動で重いモデルに切り替える、という運用が1つの設定ファイルで完結します。
| 利用形態 | 効くか | 備考 |
|---|---|---|
| 個人利用(管理設定なし) | 効くか自分の設定がそのまま効く | 備考Defaultを安価なモデルに固定するコスト対策に使える |
| 組織(管理設定を配布) | 効くか管理設定側の値だけが有効 | 備考個人のuser/project設定に書いても無視される |
| 組織所属だが管理設定が未到達の端末 | 効くか個人設定がそのまま有効 | 備考統制対象から外れている可能性が高い状態 |
設定方法
組織でモデル利用を統制する場合は、managed-settings.jsonに次の形で書きます。
{
"availableModels": ["sonnet", "haiku"],
"enforceAvailableModels": true
}配置先は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
管理設定を配布していない個人利用では、同じ2つのキーを~/.claude/settings.json(ユーザー設定)に書くだけで動きます。プロジェクト単位で縛りたい場合は、リポジトリの.claude/settings.jsonに書けば、そのプロジェクトを開いたときだけ適用されます。
順番を間違えやすいのが、availableModelsを書かずにenforceAvailableModelsだけtrueにするケースです。availableModelsが未設定または空のままだと、enforceAvailableModelsは何もしません。許可したいモデルをavailableModelsに書いてから有効化する、という順番を守る必要があります。
設定値が不正なときの扱われ方
managed-settings.jsonの値がスキーマ違反で読み込めないとき、Claude Codeはキーごとに異なるフォールバックを適用します。availableModelsとenforceAvailableModelsは、どちらも制限を強める側に倒れる設計です。
availableModelsの値全体が不正な場合: 空の許可リストとして扱われ、Defaultしか使えない状態になります。個別のエントリだけが不正なら、そのエントリだけが取り除かれ、残りの許可リストは有効なままですenforceAvailableModelsの値が真偽値でないなど不正な場合:trueとして扱われます
managed-settings.jsonのスキーマ違反時はこの2キーとも制限を強める側に寄せて扱われますが、これは壊れたファイルをどう解釈するかの話です。ファイルが正しく読み込めても、許可リストの構成そのものが行き詰まる場合は別の経路があります。availableModelsが空でないのに、どのエントリも許可され利用可能なモデルに解決できない構成では、enforcement自体がスキップされ、Defaultはアカウント種別の既定値に戻ります。この警告は--debugでしか見えません。availableModels: []のように空配列で指定した場合は、アカウント種別のDefaultがそのまま使え続けるため、この設定だけで全モデルを締め出すことはできません。許可リストには、確実に使える(そのアカウントで利用可能な)モデルを最低1つ残しておくと、このenforcementスキップを避けられます。
関連する設定と組み合わせるときの注意点
enforceAvailableModelsは単体で完結せず、いくつかの関連設定と絡みます。
model: セッションの既定モデルを固定するキーです。値(--modelフラグやANTHROPIC_MODEL環境変数の指定も含む)がavailableModelsの許可リスト外だと、起動時に警告が出て要求したモデルと実際に使われるモデルの両方が示され、セッションは既定モデルで始まります。この既定モデルが許可リスト外になり得る点が、まさにenforceAvailableModelsで塞ぐ抜け穴ですfallbackModel: 過負荷時の自動切り替え先です。チェーンの各エントリも許可リストで絞り込まれるため、フォールバック先を許可リストの外に置くと、いざというときに切り替え先が残りません。詳細はClaude Code fallbackModelで過負荷に備えるにまとめていますmodelOverrides: Bedrock等のプロバイダー固有IDへのマッピングで、許可リストとは別軸の設定ですmodelPicker(v2.1.242以降):/modelピッカーに出す選択肢そのものをカスタマイズするキーで、enforceAvailableModelsの判定には関与しませんmaxEffortLevel(v2.1.267以降): モデルの制限とeffortの制限は別軸です。モデルを絞っても、effortは別にキャップしない限り高いレベルのまま動きます
組織の既定モデルそのものの決め方(ロール別の優先順位など)はClaude組織のデフォルトモデル設定とロール別の優先順位で扱っています。
availableModelsが制限する対象はメインセッションだけではありません。サブエージェント・スキル・advisorが指定するモデルにも同じ許可リストが及びますが、外れたときの扱いは2種類に分かれます。サブエージェントやチームメイトのオーバーライドが許可リスト外の場合は、リクエストを失敗させる代わりにフォールバックモデルで実行されます。一方、スキルやコマンドのオーバーライド(ブロック対象のモデルファミリーのエイリアス指定を含む)が許可リスト外の場合は、その指定自体が無視され、セッションのモデルで実行されます(サブエージェント内で走るスキル・コマンドは前者の挙動に従います)。個人設定で許可リストを絞っているときほど、外部から取り込む定義の中身も確認しておくと想定外の挙動を避けられます。
適用されているかを確認する方法
設定が意図どおり効いているかは、/statusで確認します。管理設定が選択されていれば、Setting sources行にEnterprise managed settingsとソースの種類が表示されます。個人設定だけで運用している場合は、管理ソースが存在しないためこの行自体が出ないのが正常です。
/status設定ファイルの中身がどう解釈されたかまで見たい場合は、ターミナルからclaude doctorを実行します。不正な値がストリップされていれば、ここに一覧で表示されます。
claude doctor組織で配布した直後は、1台の端末で/statusのソース行を確認してから残りの端末へ展開すると、トラブルの早期発見につながります。
Setting sources行が期待と違うソースを示しているときは、Skipped sourcesという2行目も確認します(Claude Code v2.1.242以降で表示されます)。Claude Codeが端末上に複数の管理設定ソースを見つけたのに、そのうちの1つしか選ばなかった場合、選ばれなかったソースはここに列挙されます。配布したmanaged-settings.jsonが効いていないように見えるとき、原因が「そもそも届いていない」のか「届いてはいるが、より優先度の高い別のソースに上書きされている」のかを、この行で切り分けられます。
v2.1.175からv2.1.176でどう抜け道が塞がれたか
enforceAvailableModelsが追加されたのはv2.1.175です。このバージョンがDefault経由の抜け穴を塞いだ経緯とアカウント種別ごとのDefaultの実体、有効化前後の詳しい比較はClaude Code v2.1.175の解説にまとめています。
直後のv2.1.176では、enforceAvailableModelsとは別の抜け道が塞がれました。エイリアスで選んだモデルがANTHROPIC_DEFAULT_*_MODEL環境変数を経由してブロック対象のモデルへ振り替えられる余地が残っていましたが、この版で拒否されるようになりました。許可リストで統制する組織は、v2.1.175とv2.1.176をそろえて適用しておくと、Default経由と環境変数経由の両方の抜け穴がふさがった状態になります。
組織全体の統制設計(配信経路・バージョン強制・サンドボックス強制との組み合わせ)はClaude Code組織管理ガイドで扱っています。
まとめ
enforceAvailableModelsは、availableModelsの許可リストをDefaultにも適用させる設定で、v2.1.175以降、availableModelsと組み合わせて初めて効きます。スコープは個人設定にも及びますが、組織が管理設定を配布している環境ではそちらの値だけが採用されます。設定値が壊れていても、許可リストは狭まる方向にしか動きません。効いているかどうかは/statusとclaude doctorで確認できます。個人開発でコストを抑えたい場合も、組織でモデル利用を統制したい場合も、availableModelsとセットで書く、という基本は変わりません。設定してすぐ有効になるので、本番環境の端末に配る前に自分の端末で挙動を確かめておくと安全です。