Spencer Niemi

ElasticのOTelを使用してClaude Code/Coworkを大規模に監視

Elasticの情報セキュリティチームが、Claude CodeとClaude CoworkのネイティブOTelエクスポート機能とElasticのOTel取り込みインフラストラクチャを使用して、監視パイプラインを構築した方法。

8分で読めますEnablement, Generative AI

AIコーディングアシスタントがエンジニアリングワークフローにおける標準ツールとなるにつれ、セキュリティチームは新たな課題に直面しています。それは、組織全体でAIエージェントが何をしているのか(そしてなぜそうしているのか)をどのように可視化し続けるかということです。これらのエージェントがシェルコマンドを実行したり、ファイルを読んだり、APIを呼び出したり、MCPコネクタを介して内部システムとやり取りしたりできる場合、脅威の検出、インシデント対応、およびコンプライアンスをサポートするために、リアルタイムの可観測性が必要になります。

この記事では、Elastic の情報セキュリティチームが、Claude CodeClaude CoworkのネイティブなOpenTelemetry (OTel)エクスポート機能と Elastic 独自の OTel 取り込みインフラストラクチャを使用して、監視パイプラインを構築した方法について解説します。本稿では、テレメトリスキーマ、ゲートウェイの展開、カスタムElasticsearchマッピングと取り込みパイプライン、管理された構成配信、およびこのデータによって実現されるセキュリティのユースケースについて解説します。

Elasticの情報セキュリティチームがAIエージェントを監視する理由

Elasticでは、「カスタマーゼロ」と呼ぶ理念を実践しています。InfoSecチームはElastic製品の最も初期かつ最も要求の厳しいユーザーであり、常に最新バージョンを本番環境で使用しています。私たちの目標は、可能な限り自社製品を活用してセキュリティ体制を強化することです。

Claude CodeとCoworkは現在、Elasticのエンジニアリング組織全体で積極的に活用されています。Claude Codeは、開発者のマシン上でローカルに動作する、CLIベースのAIコーディングアシスタントです。CoworkはClaudeデスクトップアプリの一部であり、ローカル環境でも動作します。MCPコネクタを介して、ファイルの読み取り、サンドボックス内でのコード実行、ウェブ検索、Slack、GitHub、Jira、Googleカレンダーなどの接続済みサービスとの連携が可能です。どちらのツールも内部システムへの接続をサポートしているため、セキュリティチームが監視する必要のある信頼境界内で動作します。

Claude CodeとCoworkがOpenTelemetry経由でエクスポートするもの

両製品とも、標準のOpenTelemetryプロトコルを介してテレメトリデータをエクスポートし、同じ5種類のイベントを出力します。

  • api_request — モデル、コスト、トークン数、レイテンシ
  • tool_result — ツール名、MCPサーバーとツール名、成功/失敗、所要時間
  • tool_decision — 自動承認 vs ユーザー承認
  • user_prompt ―ユーザーがエージェントに依頼したこと
  • api_error — エラーメッセージ、ステータスコード

すべてのイベントには、ユーザーID( user.emailorganization.id )、セッションコンテキスト( session.idprompt.idevent.sequence )、およびAPIリクエストイベントのコスト/トークンフィールドが含まれます。Claude Code のテレメトリはオプトイン方式で、デフォルトではプロンプトとツール引数が削除されます。 OTEL_LOG_USER_PROMPTS=1OTEL_LOG_TOOL_DETAILS=1を使用して有効にしてください。コワーキングスペースはAnthropicの管理ポータルで一元的に設定され、詳細情報も自動的に含まれます。

テレメトリの完全なスキーマについては、 Claude Code Monitoring のドキュメントClaude Cowork Monitoring のドキュメントを参照してください。

アーキテクチャ:データをElasticsearchに取り込む

Claude CodeとCowork OTelのデータをElasticsearchに取り込む方法は2つあります。弊社はまずセルフマネージドゲートウェイ方式を導入しましたが、Elastic Cloudユーザーにはよりシンプルな選択肢があります。

オプション1:EDOT OTelゲートウェイ(自己管理型)

これは私たちが社内で採用したアプローチです。Elastic社の情報セキュリティチームは、自己管理型のECK(Elastic Cloud on Kubernetes)クラスターを運用しているため、ゲートウェイとしてOpenTelemetry Collector(EDOT)のElastic Distributionを導入しました。Claude CodeとCoworkはどちらもユーザーのマシン上でローカルに実行され、OTLP/HTTPをゲートウェイに送信します。ゲートウェイはリクエストを認証し、Elasticsearchに書き込みます。

EDOTコレクターイメージ( docker.elastic.co/elastic-agent/elastic-otel-collector )を使用したopentelemetry-collector Helmチャートを使用しました。EDOTイメージはネイティブのElasticデータストリームルーティング機能を提供しており、追加の設定なしにログを適切なデータストリームに取り込むために重要です。

ゲートウェイはデプロイメントモードで動作し、 bearertokenauth拡張機能を介してベアラートークン認証を使用します。

コアコレクターの設定は以下のとおりです。

config:
  extensions:
    bearertokenauth:
      scheme: "Bearer"
      token: "${env:OTEL_GATEWAY_TOKEN}"
  receivers:
    otlp:
      protocols:
        http:
          endpoint: "0.0.0.0:4318"
          auth:
            authenticator: bearertokenauth
  processors:
    transform/route:
      log_statements:
        - context: log
          conditions:
            - resource.attributes["service.name"] == "claude-code"
          statements:
            - set(resource.attributes["data_stream.dataset"], "claude_code")
        - context: log
          conditions:
            - resource.attributes["service.name"] == "cowork"
          statements:
            - set(resource.attributes["data_stream.dataset"], "claude_cowork")
  exporters:
    elasticsearch:
      endpoints: ["https://your-elasticsearch:9200"]
      user: "${env:ES_USERNAME}"
      password: "${env:ES_PASSWORD}"
  service:
    extensions: [bearertokenauth]
    pipelines:
      logs:
        receivers: [otlp]
        processors: [transform/route]
        exporters: [elasticsearch]

オプション2:Elastic CloudマネージドOTLPエンドポイント(ゲートウェイ不要)

Elastic Cloud(サーバーレスまたはホスト型)を使用している場合は、ゲートウェイを完全に省略できます。ElasticのマネージドOTLP(mOTLP)エンドポイントは、OTLPデータを直接受け入れる、回復力が高く自動スケーリング可能な取り込みレイヤーを提供します。コレクターインフラストラクチャを導入または保守する必要はありません。

これを使用するには、Claude CodeのOTLPエクスポーターをElastic CloudのmOTLPエンドポイントに直接指定してください。

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT="https://<your-motlp-endpoint>"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey <your-api-key>"
export OTEL_RESOURCE_ATTRIBUTES="data_stream.dataset=claude_code"

ここで重要なのは、 data_stream.datasetリソース属性です。これは、どのデータストリームがログを受信するかを制御します。これがないと、データは汎用的なOTelデータストリームに格納され、カスタムインデックステンプレートや取り込みパイプラインは適用されません。正しいフィールドマッピングを使用してデータが専用のlogs-claude_code.otel-*またはlogs-claude_cowork.otel-*ストリームにルーティングされるように、 claude_codeまたはclaude_coworkに設定してください。

mOTLPを使用すると、自動データストリームルーティングを備えたネイティブOTLP取り込み、インデックス作成時の問題発生時にデータを保護する組み込みの障害ストア、およびAPMサーバー不要というメリットが得られます。

管理エンドポイントは、以下に説明するすべてのカスタムインデックステンプレートと取り込みパイプラインをサポートしていますが、ゲートウェイを操作する必要はありません。

セットアップの詳細については、 Elastic Cloud Managed OTLP のドキュメントを参照してください。

カスタムElasticsearchマッピングとデータ取り込みパイプライン

デフォルトでは、OTel属性はElasticsearchでキーワードとしてインデックス化されます。それはフィルタリングやグループ化には有効ですが、数値集計には適していません。キーワードフィールドの合計や平均を計算することはできません。フィールドの型を修正するためのカスタムマッピングと、JSON文字列フィールドを構造化オブジェクトに解析するための取り込みパイプラインを作成しました。

コンポーネントテンプレート

コンポーネントテンプレートは、数値フィールドとブール型フィールドのデフォルトのキーワードマッピングを上書きし、JSONエンコードされたツールパラメータにflattened型のマッピングを追加します。

PUT _component_template/logs-claude_code.otel@custom
{
  "template": {
    "mappings": {
      "properties": {
        "cost_usd":                  { "type": "float" },
        "duration_ms":               { "type": "long" },
        "input_tokens":              { "type": "long" },
        "output_tokens":             { "type": "long" },
        "cache_creation_tokens":     { "type": "long" },
        "cache_read_tokens":         { "type": "long" },
        "prompt_length":             { "type": "long" },
        "tool_result_size_bytes":    { "type": "long" },
        "success":                   { "type": "boolean" },
        "tool_parameters_flattened": { "type": "flattened" },
        "tool_input_flattened":      { "type": "flattened" }
      }
    }
  }
}

ここではflattened型が重要です。tool_parameterstool_inputmcp_server_namemcp_tool_namebash_command 、またはcommandのようなネストされたキーを含む JSON 文字列として届きます。それらをflattenedフィールドに解析することで、無制限の数のマッピングされたフィールドを作成することなく、個々のキーをクエリできます。

今後の機能強化として、これらのJSONペイロードから高価値フィールド(MCPサーバー名、ツール名、bashコマンドなど)を抽出し、専用のマッピングフィールドに配置することで、これらの値に基づいてより高度な分析、集計、検出ルールを直接実行できるようにする予定です。

インデックステンプレート

インデックステンプレートは、すべての標準OTelコンポーネントテンプレートに加えて、当社独自のテンプレートで構成されています。これはlogs-claude_code.otel-*logs-claude_cowork.otel-*の両方に一致するため、両方のデータストリームは同じフィールドマッピングを共有します。

PUT _index_template/logs-claude_code.otel
{
  "index_patterns": [
    "logs-claude_code.otel-*",
    "logs-claude_cowork.otel-*"
  ],
  "composed_of": [
    "logs@mappings",
    "logs@settings",
    "otel@mappings",
    "otel@settings",
    "logs-otel@mappings",
    "semconv-resource-to-ecs@mappings",
    "logs@custom",
    "logs-otel@custom",
    "logs-claude_code.otel@custom",
    "ecs@mappings"
  ],
  "priority": 150,
  "data_stream": {},
  "allow_auto_create": true,
  "ignore_missing_component_templates": [
    "logs@custom",
    "logs-otel@custom"
  ]
}

パイプラインを投入

取り込みパイプラインは、JSON文字列からtool_parameterstool_inputを解析してオブジェクトに変換し、元のキーワードマッピング属性との競合を避けるために、別々の*_flattenedターゲットフィールドに書き込みます。

PUT _ingest/pipeline/logs-claude_code.otel@custom
{
  "description": "Parse JSON string fields in Claude Code/Cowork OTel telemetry",
  "processors": [
    {
      "json": {
        "field": "attributes.tool_parameters",
        "target_field": "tool_parameters_flattened",
        "if": "ctx.attributes?.tool_parameters != null && ctx.attributes.tool_parameters.startsWith('{')",
        "ignore_failure": true
      }
    },
    {
      "json": {
        "field": "attributes.tool_input",
        "target_field": "tool_input_flattened",
        "if": "ctx.attributes?.tool_input != null && ctx.attributes.tool_input.startsWith('{')",
        "ignore_failure": true
      }
    }
  ]
}

これら3つのリソースを作成すると、 logs-claude_code.otel-*およびlogs-claude_cowork.otel-*データストリームに流入する新しいデータには、正しい数値フィールド型と検索可能な構造化ツールパラメータが設定されます。

テレメトリエクスポートの設定

Claude CodeとCoworkは設定が異なります。Claude Codeは標準のOpenTelemetry環境変数を使用します。Cowork OTelのエクスポートは、Anthropic管理ポータルで管理者が一元的に設定します。

Claude Codeは、IT部門によって展開され、ユーザーが上書きできない管理設定をサポートしています。設定は、 envブロックを含むJSONファイルです。

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_LOG_TOOL_DETAILS": "1",
    "OTEL_LOG_USER_PROMPTS": "1",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://your-otel-gateway:443",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer your-token"
  }
}

この管理設定ファイルは、MDM(Jamf、Intune)、Claude.ai管理コンソールを介したサーバー管理設定、またはファイルベースの展開によって配信できます。配信メカニズムとそのセキュリティ特性の完全なリストについては、 Claude Codeの管理設定に関するドキュメントを参照してください。

ローカルテストの場合は、組織全体に展開する前に、 ~/.claude/settings.jsonと同じ構成を自分のマシンに配置できます。

コワーキングスペース

Cowork OTelのエクスポートは、Anthropic管理ポータルで管理者が一元的に設定します。管理者は管理コンソールでOTLPエンドポイントと認証ヘッダーを設定すると、Coworkインスタンスは自動的にその設定を取り込みます。プロンプトの内容とツールの詳細は、追加のフラグを必要とせずにデフォルトで含まれています。

Coworkはサンドボックス環境で動作するため、OTelゲートウェイエンドポイントは、サンドボックス環境からのアウトバウンドネットワークアクセスを許可リストに登録する必要があります。これがないと、テレメトリデータのエクスポートはエラーメッセージを表示せずに失敗します。

セキュリティのユースケース

イベントの種類、識別情報フィールド、およびツールパラメータを組み合わせることで、セキュリティ運用に役立つ豊富なデータセットが作成されます。以下に、当社が検出および調査機能を構築する際に想定しているユースケースを示します。

ツール呼び出しの監査。ツール呼び出しはすべて、ツール名と入力パラメータとともにログに記録されます。MCPツールの場合、これにはMCPサーバー名とツール名が含まれます(例: slack_send_messagegithub/search_issues )。不正なデータアクセス、異常なシェルコマンド、または予期しないMCPサーバーとのやり取りを検出できます。attributes.tool_name + attributes.tool_parametersフィールドを使用してください。

セッションの再構築。session.idフィールドとevent.sequenceを組み合わせることで、各セッション内で単調増加するカウンターが提供されます。Claudeセッションの完全なシーケンスを再構築できます。ユーザーが何を要求したか、どのツールが実行されたか、どのデータにアクセスしたか、どのAPIが呼び出されたかなどです。これはインシデント対応において非常に役立ちます。不審なツール呼び出しを検出した場合、セッションの完全なコンテキストを取得できるからです。

許可決定分析。attributes.event.name : tool_decisionイベントは、各ツールの使用がどのように承認されたかについての洞察を提供します。これにより、ユーザーが危険なツールカテゴリを自動承認しているかどうかを検出したり、フリート全体で異常な権限パターンを特定したりできます。

意思決定源意味
config設定またはポリシーにより自動的に許可されます
hook設定済みのフックスクリプトによって決定されます
user_temporaryユーザーはこの呼び出しに対して「承認」をクリックしました
user_permanentユーザーがこのツールに対して「常に許可する」をクリックしました
user_abortユーザーがセッションを中止しました
user_rejectユーザーはツールの使用を明示的に拒否しました

コスト異常検知。api_requestイベントのcost_usdフィールドを使用すると、リクエストごと、セッションごと、およびユーザーごとのコスト追跡が可能になります。異常に高額なセッションを検知してアラートを発信したり、消費パターンが異常に多いユーザーを特定したりできます。

EDRデータとの相関関係。エンドポイントでElastic Defendを実行している場合は、ClaudeのOTelテレメトリをEDRプロセスおよびファイルイベントと関連付けることで、全体像を把握できます。Claude Code が Bash コマンドを実行すると、OTel tool_resultイベントは、エージェントが実行することを決定した内容とその理由 (前述のuser_promptを介して) を通知します。対応するElastic Defendプロセスイベントには、ホスト上で何が起こったか(生成された子プロセス、書き込まれたファイル、確立されたネットワーク接続など)が正確に記録されています。タイムスタンプとホストに基づいてこれら2つのデータソースを結合することで、意図(AIエージェントのテレメトリから)と影響(エンドポイントのテレメトリから)の両方を単一の調査で把握できます。

MCPサーバーへのアクセス監視。組織がMCPを通じてAIエージェントを内部システムに接続するにつれて、どのサーバーにどのようなツールでアクセスされているかを監視することが非常に重要になる。tool_parameters_flattened.mcp_server_nameフィールドとtool_parameters_flattened.mcp_tool_nameフィールドは、この可視性を提供します。

例えば、Slack のツール呼び出しを確認するには、 tool_name: "mcp_tool" AND tool_parameters_flattened.mcp_tool_name:slack*をクエリします。

OTelを超えて:Claudeエンタープライズ監査ログ

Claude CodeとCoworkのテレメトリはエンドポイント上のエージェントのアクティビティをカバーしますが、すべてを捕捉するわけではありません。完全な可視性を確保するためには、組織はコンプライアンスAPIからClaudeエンタープライズ監査ログも収集する必要があります。これは、Webインターフェース(claude.ai)上でのアクティビティ、およびログインアクティビティ、権限変更、組織レベルの管理といった従来のセキュリティ監査イベントの唯一の情報源です。両方のデータソースを組み合わせることで、セキュリティチームはClaude製品全体にわたる包括的な状況把握が可能になります。

まとめ

AIコーディングアシスタントや自律型エージェントは、企業の標準的なツールキットの一部になりつつある。セキュリティチームがこれらのツールが何をしているのかを把握できていないとしたら、そこに欠陥が生じます。Claude CodeとCoworkにはOpenTelemetryのサポートが同梱されており、セキュリティチームが必要とするまさにその種類のテレメトリ(ID、セッションコンテキスト、ツール呼び出しの詳細、コストデータ、権限決定など)を提供します。ElasticのネイティブOTel取り込み機能は、Elastic Cloud上のマネージドOTLPエンドポイントを使用する場合でも、自己管理環境のEDOTコレクターを使用する場合でも、このデータを簡単にElasticsearchに取り込むことができます。Elasticsearchでは、データの検索、ダッシュボードの構築、検出ルールの作成などが可能です。

利用を開始したい場合は、 Elastic Cloudの無料トライアルに登録してマネージドOTLPエンドポイントを試すか、既存の環境にEDOT OTel Collectorをインストールしてください。

参照資料

この記事を共有する