組織は、Copilot Studio エージェントをランタイム脅威検出システムに接続することで、セキュリティのレイヤーを追加できます。 接続後、エージェントは実行時にこのシステムを呼び出します。 エージェントはシステムにデータを提供し、システムがエージェントが呼び出そうとしているツールの正当性を判断できるようにします。 その後、システムは Copilot Studio に対して「承認」または「ブロック」のいずれかの応答を返し、それに応じてエージェントがツールを起動するか、スキップするかを決定します。 エージェントを既存の外部脅威検知システムに接続する方法の詳細については、Copilot Studio カスタムエージェントの外部脅威検知および保護を有効にするを参照してください。
この記事は開発者を対象としており、Copilot Studioエージェント向けのセキュリティ プロバイダーとして、独自の脅威検知機能を統合する方法について説明しています。
この統合は、2 つのエンドポイントで構成される API に基づいています。 実装すべき主なエンドポイントは analyze-tool-execution エンドポイントです。 このエンドポイントを脅威検知システムへのインターフェースとして公開する必要があります。 顧客が御社のシステムを外部脅威検知システムとして構成すると、エージェントはツールを起動しようとするたびにこの API を呼び出します。
analyze-tool-execution エンドポイントのほかに、validate という名前の 2 つ目のエンドポイントも公開する必要があります。
validate エンドポイントは、システムセットアップの一環としてエンドポイントの健全性と準備状況を確認するために使用されます。
以下のセクションでは、各エンドポイントについて詳しく説明します。
POST /検証
目的: 脅威検知エンドポイントが到達可能で機能していることを検証します。 初期設定および設定テストに使用されます。
要求の検証
方法: POST
URL:
https://{threat detection endpoint}/validate?api-version=2025-05-01ヘッダー:
承認: API 認証用のベアラー トークン
x-ms-correlation-id: トレース用の GUID
ボディ: 空
応答の検証
200 OK 応答の例
{
"isSuccessful": true,
"status": "OK"
}
応答エラーの例
エラーが発生した場合 (HTTP ステータスコードが失敗を示す場合)、エンドポイントはエラーコード、メッセージ、およびオプションの診断情報を返します。
{
"errorCode": 5031,
"message": "Validation failed. Webhook service is temporarily unavailable.",
"httpStatus": 503,
"diagnostics": "{\\reason\\:\\Upstream dependency timeout\\}"
}
POST /analyze-tool-execution
目的: リスク評価のためにツール実行コンテキストを提出します。 ツールの実行要求を評価し、その実行を許可するかブロックするかを決定して応答します。
分析ツールの実行リクエスト
方法: POST
URL:
https://{threat detection endpoint}/analyze-tool-execution?api-version=2025-05-01ヘッダー:
- 承認: API 認証用のベアラー トークン
- コンテンツ タイプ: application/json
ボディ: JSON オブジェクト
analyze-tool-execution リクエストの例
POST https://security.contoso.com/api/agentSecurity/analyze-tool-execution?api-version=2025-05-01
Authorization: Bearer XXX……
x-ms-correlation-id: fbac57f1-3b19-4a2b-b69f-a1f2f2c5cc3c
Content-Type: application/json
{
"plannerContext": {
"userMessage": "Send an email to the customer",
"thought": "User wants to notify customer",
"chatHistory": [
{
"id": "m1",
"role": "user",
"content": "Send an email to the customer",
"timestamp": "2025-05-25T08:00:00Z"
},
{
"id": "m2",
"role": "assistant",
"content": "Which customer should I email?",
"timestamp": "2025-05-25T08:00:01Z"
},
{
"id": "m3",
"role": "user",
"content": "The customer is John Doe",
"timestamp": "2025-05-25T08:00:02Z"
}
],
"previousToolOutputs": [
{
"toolId": "tool-123",
"toolName": "Get customer email by name",
"outputs": {
"name": "email",
"description": "Customer's email address",
"type": {
"$kind": "String"
},
"value": "customer@foobar.com"
},
"timestamp": "2025-05-25T08:00:02Z"
}
]
},
"toolDefinition": {
"id": "tool-123",
"type": "PrebuiltToolDefinition",
"name": "Send email",
"description": "Sends an email to specified recipients.",
"inputParameters": [
{
"name": "to",
"description": "Receiver of the email",
"type": {
"$kind": "String"
}
},
{
"name": "bcc",
"description": "BCC of the email",
"type": {
"$kind": "String"
}
}
],
"outputParameters": [
{
"name": "result",
"description": "Result",
"type": {
"$kind": "String"
}
}
]
},
"inputValues": {
"to": "customer@foobar.com",
"bcc": "hacker@evil.com"
},
"conversationMetadata": {
"agent": {
"id": "agent-guid",
"tenantId": "tenant-guid",
"environmentId": "env-guid",
"isPublished": true
},
"user": {
"id": "user-guid",
"tenantId": "tenant-guid"
},
"trigger": {
"id": "trigger-guid",
"schemaName": "trigger-schema"
},
"conversationId": "conv-id",
"planId": "plan-guid",
"planStepId": "step-1"
}
}
Analyze-tool-execution 応答
200 OK
リクエストが有効な場合、リクエストで使用されたツールが評価され、定義された基準に基づいて許可またはブロックされます。 応答には、以下のフィールドが含まれる場合があります。
- blockAction (ブール値): そのアクションをブロックすべきかどうか
- reasonCode (整数、オプション): ブロック理由を示す数値によるコード
- 理由 (文字列、オプション): わかりやすい説明
- 診断 (オブジェクト、任意): トレースやデバッグのためのその他の詳細
許可応答例
{
"blockAction": false
}
ブロック応答例
{
"blockAction": true,
"reasonCode": 112,
"reason": "The action was blocked because there is a noncompliant email address in the BCC field.",
"diagnostics": "{\\flaggedField\\:\\bcc\\,\\flaggedValue\\:\\hacker@evil.com\\}"
}
エラー応答の例
リクエストが無効な場合、エラーコード、メッセージ、HTTP ステータス、およびオプションの診断情報を含むエラー応答が返されます。
{
"errorCode": 4001,
"message": "Missing required field: toolDefinition",
"httpStatus": 400,
"diagnostics": "{\\missingField\\:\\toolDefinition\\,\\traceId\\:\\abc-123\\}"
}
リクエストおよび応答ボディ構造に関するリファレンス
以下の表は、エンドポイントのリクエストおよび応答本文内で使用されるさまざまなオブジェクトの内容について説明したものです。
ValidationResponse
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| isSuccessful | ブール値 | 有 | 検証が合格したかどうかを示します。 |
| 状態 | string | 有 | 任意のステータスメッセージまたはパートナー固有の詳細 |
AnalyzeToolExecutionResponse
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| blockAction | ブール値 | 有 | アクションをブロックすべきかどうかを示します。 |
| reasonCode | integer | いいえ | パートナーによって決定される、任意の数値による理由コード。 |
| reason | string | いいえ | 任意の人間向け説明。 |
| 診断 | string | いいえ | デバッグやテレメトリ用の、任意のフリーフォーム形式の診断情報。 事前に初期化する必要があります。 |
ErrorResponse
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| errorCode | integer | 有 | エラーの数値識別子 (例: 1001 = 必須フィールドの未入力、2003 = 認証失敗)。 |
| メッセージ | string | 有 | エラーの人間が理解しやすい説明 |
| httpStatus | integer | 有 | パートナーから返された HTTP 状態コード |
| 診断 | string | いいえ | デバッグやテレメトリ用の、任意のフリーフォーム形式の診断情報。 事前に初期化する必要があります。 |
EvaluationRequest
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| plannerContext | PlannerContext | 有 | プランナー コンテキスト データ。 |
| toolDefinition | ToolDefinition | 有 | ツール定義の詳細。 |
| inputValues | JSON オブジェクト | 有 | ツールに提供されたキーと値のペアの辞書。 |
| conversationMetadata | ConversationMetadata | 有 | 会話の文脈、ユーザー、計画の追跡に関するメタデータ。 |
PlannerContext
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| userMessage | string | 有 | エージェントから送られた元のメッセージ。 |
| 思考 | string | いいえ | プランナーによる、このツールが選択された理由の説明 |
| chatHistory | ChatMessage[] | いいえ | ユーザーとの最近のチャットメッセージ一覧。 |
| previousToolsOutputs | ToolExecutionOutput[] | いいえ | 最近のツール出力の一覧。 |
ChatMessage
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| ID | string | 有 | この会話におけるこのメッセージの固有の識別子です。 |
| role | string | 有 | メッセージの送信元 (例:ユーザー、アシスタント)。 |
| コンテンツ | string | 有 | メッセージ テキスト。 |
| タイムスタンプ | 文字列 (日付- 時間) | いいえ | メッセージが送信された時刻を示す ISO 8601 形式のタイムスタンプ。 |
ToolExecutionOutputs
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| toolId | string | 有 | この会話におけるこのメッセージの固有の識別子です。 |
| toolName | string | 有 | ツールの名前。 |
| 出力 | ExecutionOutput[] | 有 | ツールの実行結果の一覧。 |
| タイムスタンプ | 文字列 (日付- 時間) | いいえ | ツールの実行が完了した時刻を示す ISO 8601 形式のタイムスタンプ。 |
ExecutionOutput
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| name | string | 有 | 出力パラメーターの名前。 |
| description | string | いいえ | 出力値の説明。 |
| タイプ | object | いいえ | 出力のデータ型。 |
| 値 | JSON データの値 | 有 | 出力の値です。 |
ToolDefinition
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| ID | string | 有 | ツールの一意識別子です。 |
| タイプ | string | 有 | プランナーで使用するツールの種類を指定します。 |
| name | string | 有 | 人が理解しやすいツール名。 |
| description | string | 有 | ツールの機能概要。 |
| inputParameters | ToolInput[] | いいえ | ツールの入力パラメーター。 |
| outputParameters | ToolOutput[] | いいえ | ツールの実行後に返される出力パラメーター。 |
ToolInput
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| name | string | 有 | 入力パラメーターの名前。 |
| description | string | いいえ | この入力パラメーターの期待される値の説明。 |
| タイプ | JSON オブジェクト | いいえ | 入力パラメーターのデータの種類です。 |
ToolOutput
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| name | string | 有 | 出力パラメーターの名前。 |
| description | string | いいえ | 出力値の説明。 |
| タイプ | JSON オブジェクト | いいえ | 出力値の型。 |
ConversationMetadata
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| エージェント | AgentContext | 有 | エージェントのコンテキスト情報。 |
| ユーザー | UserContext | いいえ | エージェントと対話するユーザーに関する情報。 |
| トリガー (trigger) | TriggerContext | いいえ | プランナー実行をトリガーした事象に関する情報。 |
| conversationId | string | 有 | 現在進行中の会話の ID。 |
| planId | string | いいえ | ユーザーのリクエストを処理するために使用されたプランの ID。 |
| planStepId | string | いいえ | このツール実行に対応するプラン内の手順。 |
| parentAgentComponentId | string | いいえ | 親エージェントコンポーネントの ID。 |
AgentContext
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| ID | string | 有 | エージェントの ID。 |
| tenantId | string | 有 | エージェントが所属するテナント。 |
| environmentId | string | 有 | エージェントが公開される環境。 |
| version | string | いいえ | エージェント バージョン (isPublished が false の場合は任意)。 |
| isPublished | ブール値 | 有 | この実行コンテキストが公開版かどうか。 |
UserContext
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| ID | string | いいえ | Microsoft Entra ユーザーのオブジェクト ID です。 |
| tenantId | string | いいえ | ユーザーのテナント ID。 |
TriggerContext
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
| ID | string | いいえ | プランナーを起動したトリガーの ID。 |
| schemaName | string | いいえ | プランナーを起動したトリガースキーマの名前。 |
認証
開発する統合機能では、Microsoft Entra ID による認証を使用する必要があります。 開発者が構築したアプリを統合するに記載の手順に従ってください。
実行手順は以下の通りです:
- テナント内のリソースのアプリ登録を作成します。
-
Web API のスコープを公開します。 スコープとして公開する URL は、顧客が呼び出すリソースのベース URL でなければなりません。 たとえば、API の URL が
https://security.contoso.com/api/threatdetectionの場合、公開されるスコープはhttps://security.contoso.comでなければなりません。 - サービスの実装方法によっては、認可ロジックを実装し、受信トークンを検証する必要があります。 顧客がどのようにアプリを認証する必要があるかを文書化する必要があります。 その方法にはいくつかあり、たとえば、アプリ ID の許可リストを使用する方法や、ロール ベースのアクセス制御 (RBAC) などがあります。
応答時間の要件
エージェントは、脅威検知システムから 1,000 ミリ秒以内に応答があることを期待しています。 エンドポイントがリクエストに指定された時間内に応答するようにしてください。 システムが時間内に応答しない場合、エージェントは、応答が「許可」であるかのように振る舞い、ツールを起動します。
API のバージョン管理
リクエストでは、API のバージョンは api-version というクエリ パラメーター (api-version=2025-05-01 など) で指定されます。 実装は他の予期しないフィールドにも対応できるようにし、将来新しい値が追加されてもリクエストが失敗しないようにしてください。 現時点ではすべてのバージョンが後方互換性を維持しているとみなされているため、パートナーは API のバージョンを確認する必要はありません。 パートナーは API のバージョンを追跡すべきですが、新しいバージョンが検出された場合でもリクエストを失敗させてはいけません。