OTEL_LOG_MANAGED_SETTINGSで管理設定の解決結果を監査ログに残す
OTEL_LOG_MANAGED_SETTINGSでmanaged_settings_resolvedイベントに追加される内容と、SHA-256ダイジェストの使い道、project/local設定から有効化できない理由を扱います。
OTEL_LOG_MANAGED_SETTINGSとは何か
OTEL_LOG_MANAGED_SETTINGSは、Claude Codeのmanaged_settings_resolvedイベントに、redact済みの管理設定内容と、redact前のSHA-256ダイジェストを追加する環境変数です。既定は無効で、Claude Code v2.1.274以降が対象になります。
managed_settings_resolvedイベント自体はOTEL_LOG_MANAGED_SETTINGSの設定に関係なく常に送られます。この変数が変えるのは、イベントに「どの管理設定ソースが動いているか」だけでなく「その設定の中身」まで乗せるかどうかです。
managed_settings_resolvedイベントが発生する3つのタイミング
managed_settings.trigger属性は次の3値のいずれかを取ります。
| trigger | 発生条件 |
|---|---|
startup | 発生条件セッション開始時 |
change | 発生条件セッション中に管理設定またはポリシーヘルパーの状態が変わったとき |
refused | 発生条件管理設定のポリシーによってセッションが起動・継続できなかったとき |
changeイベントは、直前に送ったイベントと異なる属性があるときだけ送られます。設定値が変わったこと自体はOTEL_LOG_MANAGED_SETTINGSが無効でもchangeイベントとして検知できます。
各イベントにはevent.timestamp(ISO 8601形式)と、プロセス単位で採番されるevent.sequenceが付きます。startup→change→refusedのように同一セッションで複数のイベントが送られたときも、この2つで発生順を並べ直せます。
refusedイベントにはerror.typeが付き、原因を7種類に分類します。helper_failed(ポリシーヘルパーの実行失敗)、policy_invalid(管理設定の構文エラー)、consent_rejected(サーバー管理設定の承認ダイアログをユーザーが拒否)、force_refresh_failed(forceRemoteSettingsRefreshが要求する取得の失敗)、gateway_rejected(Claude apps gatewayがHTTP 403を返した)、version_below_minimum(必要な最小バージョンを満たしていない)、_OTHERです。信頼していないフォルダでの対話セッションでは、このrefusedイベント自体が送信されません。
有効化しなくても常に載る情報
OTEL_LOG_MANAGED_SETTINGSが無効でも、managed_settings_resolvedイベントには次の属性が常に付きます。有効化して追加できるのは中身の詳細だけで、「どのソースが動いているか」の骨格はopt-inの外にあります。
| 属性 | 内容 |
|---|---|
managed_settings.sources | 内容有効な管理ソースを優先度順に列挙した配列。値はremote(サーバー管理設定)・plist/hklm(MDMやOSレベルのポリシー)・file(管理設定ファイルとdrop-in)・parent(埋め込みホストが供給)・hkcu(Windows HKCUレジストリ) |
managed_settings.source_behavior | 内容managedSourcesBehaviorの値。first-winsかmerge。どのソースもキーを設定していなければfirst-wins |
managed_settings.helper.state | 内容ポリシーヘルパーの状態。ok(正常)、none(未設定)、またはbad_path・not_a_file・exit_nonzero・timed_out・oversize・parse_failed・envelope_invalid・schema_rejectedのいずれか(失敗の内訳) |
managed_settings.helper.applied | 内容ヘルパーの出力を管理設定として採用したらoutput、していなければnone |
managed_settings.helper.path | 内容設定されたpolicyHelperのpath。ヘルパーが選択されていれば、OTEL_LOG_MANAGED_SETTINGSの有無に関わらず記録される |
managed_settings.source_behaviorが示すfirst-winsとmergeは、複数の管理ソースを配布したときの合成ルールです。既定のfirst-winsでは、ポリシーキーを持つ最優先ソース1つだけが採用され、それより下位のソースは無視されます。"merge"にすると、配布した全ての管理ソースがそれぞれのキーを持ち寄って1つのポリシーに合成されます。イベント上でsource_behaviorが想定と違えば、複数の管理ソースのどれが実際に効いているかの前提から見直す必要があります。
managed_settings.sourcesだけを見ても、「このマシンはfileソースのはずなのにremoteが動いている」といった配布経路のずれは検知できます。policyHelperで動的にポリシーを取得する設定を使っている環境では、managed_settings.helper.stateがok以外に倒れていないかを継続的に見る価値があります。
helper.stateの失敗値は、ヘルパーの何が壊れたかにそのまま対応します。
| state | 実際の原因 |
|---|---|
bad_path | 実際の原因policyHelper.pathの命名規則に違反 |
not_a_file | 実際の原因pathに通常ファイルが無い(ネットワークマウントの応答遅延も含む) |
exit_nonzero | 実際の原因ヘルパーが非ゼロで終了 |
timed_out | 実際の原因timeoutMs超過、または実行可能でなく起動自体に失敗 |
oversize | 実際の原因stdout・stderrへの出力が1MiBを超えた |
parse_failed | 実際の原因stdoutが単一のJSONオブジェクトでない |
schema_rejected | 実際の原因managedSettingsがClaude Codeで修復できないスキーマ違反 |
起動時のヘルパー実行が失敗すると、Claude Codeは理由を表示してセッションの起動そのものを拒否します。この拒否は対話セッション・claude -p・Agent SDK・バックグラウンドセッションのほぼ全経路に及びます。一方、セッション中のバックグラウンド更新が失敗した場合は直前に成功したポリシーを維持し、/statusが失敗中の更新とその理由を表示し続けます。managed_settings_resolvedのchangeイベントは、この維持と復旧の切り替わりを外部の監視基盤からも追える形にします。
有効化すると何が追加されるか
OTEL_LOG_MANAGED_SETTINGS=1を設定すると、managed_settings_resolvedイベントに次の2属性が加わります。
| 属性 | 内容 |
|---|---|
managed_settings.settings | 内容解決済み管理設定の名前と形をredactしたJSON文字列(refusedイベントには付かない) |
managed_settings.resolved_sha256 | 内容redact前の管理設定をキーでソートし空白なしでシリアライズした値のSHA-256 |
managed_settings.settingsのredactルールは設定のスキーマ由来です。permissions.defaultModeのような固定選択肢の値、真偽値、数値はそのまま出力されます。modelやapiKeyHelper、envの各値、URL、コマンドなど任意の文字列はすべて"[REDACTED]"に置き換わります。envのキー名やプラグインIDのようなマップのキー名だけは、値をredactしたままキー名は残ります。permissions.allow/deny/askのルールは、組み込みツールかmcp__参照であればツール名を残し中身だけredactします(Read([REDACTED])のような形)。それ以外のルールはルール全体が"[REDACTED]"になります。hooksも同じ考え方で、typeやtimeoutのような固定項目は見え、コマンド・URL・matcher・if条件はredactされます。
公式ドキュメントが示す出力例は次の形です。
{"apiKeyHelper":"[REDACTED]","env":{"HTTPS_PROXY":"[REDACTED]","CLAUDE_CODE_ENABLE_TELEMETRY":"[REDACTED]"},"permissions":{"deny":["Read([REDACTED])"]}}設定の値そのものは消えても、どのキーが何個設定されているかという形は残ります。この設計を踏まえると、managed_settings.settings単体で個々のポリシーの中身までは追跡できませんが、「マシンによって設定の形が違う」ことは検知できる情報だと分かります。
SHA-256ダイジェストは何に使えるか
managed_settings.resolved_sha256は、同じ値なら同じポリシーが動いている、という比較に使うためのものです。数百台規模のマシンが同じ管理設定を配布されているはずの環境で、一部のマシンだけダイジェストが違えば、配布の失敗や古いキャッシュの残留を疑う根拠になります。
ダイジェストはOTEL_LOG_MANAGED_SETTINGSが無効のときは送られません。短いポリシーはハッシュ値から総当たりで内容を推測できてしまうため、opt-inにしてあるという理由が公式ドキュメントに明記されています。ポリシーの文字数が短い組織ほど、この値を外部のログ基盤へ送る前にそのアクセス権限を絞る必要があります。
project/local設定からは有効化できない
OTEL_LOG_MANAGED_SETTINGSは、シェルの環境変数、user settings、またはmanaged settingsのいずれかで設定します。project設定やlocal設定に書いても有効になりません。
理由は明快です。project設定・local設定はリポジトリの一部としてクローンされます。この2つのソースから有効化できてしまうと、リポジトリを共有しただけで「管理設定の中身をイベントに乗せる」設定が第三者の手元でも有効になってしまいます。managed settingsの複数ソース統合を扱うmanagedSourcesBehaviorも同じくManagedスコープの設定で、project設定・local設定からは変更できません。
サーバー管理設定(server-managed settings)は、この変数をセキュリティ承認ダイアログを出さずに設定できます。組織が自分自身のredact済みポリシーを、すでに受け取っているイベントに追加するだけだからです。
承認ダイアログが出るかどうかは変数の種類で決まります。OTEL_LOG_MANAGED_SETTINGSのような機能のオン・オフを切り替えるトグルは、承認なしで適用される側に分類されます。対照的に、プロキシ・ベースURL・OTEL_EXPORTER_OTLP_ENDPOINTのような値を持つ変数は、空でない値であれば常に承認ダイアログの対象です。送信先を変える設定は承認が要り、送信先はそのままに監査ログの詳細度だけを上げるOTEL_LOG_MANAGED_SETTINGSは承認が要らない、という区分です。
有効化の手順
ユーザー単位で試すだけなら、シェルで直接設定できます。
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=otlp
export OTEL_LOG_MANAGED_SETTINGS=1
claude組織全体に配るなら、managed settingsファイルのenvブロックに書きます。
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_LOG_MANAGED_SETTINGS": "1",
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": "https://siem.example.com:4318/v1/logs"
}
}確認は簡単です。バックエンド側でclaude_code.managed_settings_resolvedイベントのmanaged_settings.settings属性が埋まっていれば成功です。何も届かない場合はclaude --debug-file <path>でセッションを起動し、書き出されるログに[3P telemetry]のエクスポートエラーが出ていないかを見ます。
何を監査したいかで立てる変数が変わる
managed_settings_resolvedイベント自体はOTEL_LOG_MANAGED_SETTINGSなしでも、どのソースが動いているか(managed_settings.sources)とポリシーヘルパーの状態(managed_settings.helper.state)は常に記録します。何を追加で見たいかで、立てる変数の使い分けが変わります。
| 見たいこと | 設定する変数 | 記録される内容 |
|---|---|---|
| ポリシーの形とハッシュ | 設定する変数OTEL_LOG_MANAGED_SETTINGS | 記録される内容redact済み設定内容 + SHA-256 |
| 誰の操作か | 設定する変数(標準属性、既定で付与) | 記録される内容user.email / user.account_uuid等 |
| ツール呼び出しの詳細 | 設定する変数OTEL_LOG_TOOL_DETAILS | 記録される内容Bashコマンド・MCPサーバー名/ツール名・入力パラメータ等 |
| プロンプト本文 | 設定する変数OTEL_LOG_USER_PROMPTS | 記録される内容ユーザーの入力テキスト |
managed_settings_resolvedは「どのポリシーが動いているか」を追う専用のイベントで、「誰が何をしたか」を追うtool_resultやtool_decisionとは役割が異なります。OTELイベントのユーザー特定と組み合わせて初めて、「誰が」「どのポリシー下で」操作したかが揃います。イベントをSIEMへ送る手順はClaude Code SIEM連携にまとめてあります。
よくある質問
有効にするとログの転送量は大きく増えるか
増分は小さめです。managed_settings.settingsはredact済みのJSON文字列で、値の中身ではなくキーの構造だけを表します。同じくopt-inのOTEL_LOG_RAW_API_BODIES(Anthropic Messages APIのリクエスト・レスポンス本文をまるごとログに出す変数、既定60KB切り詰め)と比べると、OTEL_LOG_RAW_API_BODIESは会話全体を運ぶ設計のため、転送量への影響の桁が違います。監査目的で両方を検討する組織は、まず影響の小さいOTEL_LOG_MANAGED_SETTINGSから有効化し、必要に応じて他の変数を足す順序になります。
user settingsだけで有効にしたら組織全体に効くか
効きません。user settingsはその開発者自身のマシンでのセッションにしか適用されません。組織のマシン全部でmanaged_settings.settingsとresolved_sha256を記録したいなら、managed settingsのenvブロックか、MDMで配布するプロファイルに書く必要があります。個人の端末で先に動作確認してから管理設定側に展開する手順が実務的です。
まとめ
OTEL_LOG_MANAGED_SETTINGSは、managed_settings_resolvedイベントにredact済みの管理設定とSHA-256ダイジェストを追加するopt-inの変数です。既定では管理設定のソースとポリシーヘルパーの状態しか分からず、中身の比較や配布ミスの検知にはこの変数が要ります。project・local設定からは有効化できず、user settingsか管理設定のenvブロック、または起動環境から設定します。Claude Code v2.1.274以降が対象で、それより古いバージョンが混在する環境では一部のマシンで属性自体が欠けます。数百台規模の管理設定配布を運用していて、マシンごとの設定内容の差分を突き止めたい組織にとって、有効化する価値がある設定です。