조직은 Copilot Studio 에이전트를 런타임 위협 탐지 시스템에 연결하여 보안 계층을 추가할 수 있습니다. 연결되면 에이전트는 런타임에 이 시스템을 호출합니다. 에이전트는 시스템에서 에이전트가 호출하려는 도구가 합법적인지 여부를 확인할 수 있도록 시스템에 데이터를 제공합니다. 그런 다음 시스템은 "승인" 또는 "차단"의 응답을 Copilot Studio에 전달하고, 이 응답에 따라 에이전트가 도구를 호출하거나 건너뛰게 합니다. 기존 외부 위협 탐지 시스템에 에이전트를 연결하는 방법에 대한 자세한 내용은 Copilot Studio 사용자 지정 에이전트에 대한 지원 가능한 외부 위협 탐지 및 보호 참조하세요.
이 문서는 개발자를 대상으로 하며 고유한 위협 탐지 기능을 Copilot Studio 에이전트용 보안 공급자로 통합하는 방법을 설명합니다.
통합은 두 개의 엔드포인트로 구성된 API를 기반으로 합니다. 구현해야 하는 주요 엔드포인트는 analyze-tool-execution 엔드포인트입니다. 이 엔드포인트를 위협 탐지 시스템에 대한 인터페이스로 노출해야 합니다. 고객이 시스템을 외부 위협 탐지 시스템으로 구성하면 에이전트는 도구를 호출할 때마다 이 API를 호출합니다.
analyze-tool-execution 엔드포인트 외에도 validate라는 두 번째 엔드포인트를 노출해야 합니다.
validate 엔드포인트는 시스템 설정의 일부로 엔드포인트의 상태 및 준비 상태를 확인하는 데 사용됩니다.
다음 섹션에서는 각 엔드포인트에 대해 자세히 설명합니다.
게시 /검증
목적: 위협 탐지 엔드포인트에 연결할 수 있고 작동하는지 확인합니다. 초기 설정 및 구성 테스트에 사용됩니다.
요청 유효성 검사
메서드: 올리기
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
목적: 위험 평가를 위해 도구 실행 컨텍스트를 제출합니다. 도구 실행 요청을 평가하고 도구 실행을 허용하거나 차단할지 여부를 응답합니다.
분석 도구 실행 요청
메서드: 올리기
URL:
https://{threat detection endpoint}/analyze-tool-execution?api-version=2025-05-01헤더:
- 권한 부여: API 인증을 위한 전달자 토큰
- Content-Type: application/json
몸: JSON 개체
분석 도구 실행 요청 예제
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"
}
}
분석 도구 실행 응답
200 확인
요청이 유효하면 정의된 조건에 따라 요청에 지정된 도구 사용이 평가되고 허용 되거나 차단됩니다. 응답에는 다음 필드가 포함될 수 있습니다.
- blockAction (부울): 작업을 차단해야 하는지 여부
- reasonCode (정수, 선택 사항): 블록의 이유를 설명하는 숫자 코드
- reason (문자열, 선택 사항): 사람이 읽을 수 있는 설명
- 진단 (개체, 선택 사항): 추적 또는 디버깅에 대한 기타 세부 정보
응답 허용 예제
{
"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\\}"
}
요청 및 응답 본문 구조 참조
다음 표에서는 엔드포인트에 대한 요청 및 응답 본문 내에서 사용되는 다양한 개체의 내용을 설명합니다.
유효성 확인 응답
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| isSuccessful | 불리언 (Boolean) | Yes | 유효성 검사가 통과되었는지 여부를 나타냅니다. |
| status | 문자열 | Yes | 선택적 상태 메시지 또는 파트너별 세부 정보입니다. |
AnalyzeToolExecutionResponse
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| blockAction | 불리언 (Boolean) | Yes | 작업을 차단해야 하는지 여부를 나타냅니다. |
| 사유 코드 | integer | 아니오 | 파트너에 의해 결정되는 선택적 숫자 이유 코드입니다. |
| 이유 | 문자열 | 아니오 | 선택적 사람이 읽을 수 있는 설명입니다. |
| diagnostics | 문자열 | 아니오 | 디버깅 또는 원격 분석을 위한 선택적 자유형 진단 정보입니다. 미리 직렬화해야 합니다. |
에러 응답
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 오류 코드 | integer | Yes | 오류에 대한 숫자 식별자입니다(예: 1001 = 누락된 필드, 2003 = 인증 실패). |
| message | 문자열 | Yes | 오류에 대한 사람이 읽을 수 있는 설명입니다. |
| http 상태 코드 | integer | Yes | 파트너가 반환한 HTTP 상태 코드입니다. |
| diagnostics | 문자열 | 아니오 | 디버깅 또는 원격 분석을 위한 선택적 자유형 진단 정보입니다. 미리 직렬화해야 합니다. |
평가 요청
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 계획자컨텍스트 | PlannerContext | Yes | Planner 컨텍스트 데이터입니다. |
| 도구 정의 | ToolDefinition | Yes | 도구 정의 세부 정보입니다. |
| 입력값들 | JSON 개체 | Yes | 도구에 제공된 키-값 쌍의 사전입니다. |
| 대화 메타데이터 | ConversationMetadata | Yes | 대화 컨텍스트, 사용자 및 계획 추적에 대한 메타데이터입니다. |
PlannerContext
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 사용자 메시지 | 문자열 | Yes | 에이전트에서 보낸 원본 메시지입니다. |
| 생각 | 문자열 | 아니오 | 이 도구를 선택한 이유에 대한 Planner 설명입니다. |
| 채팅 기록 | ChatMessage[] | 아니오 | 사용자와 교환된 최근 채팅 메시지 목록입니다. |
| 이전 도구 출력 | 도구 실행 출력[] | 아니오 | 최근 도구 출력 목록입니다. |
채팅 메시지
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 아이디 | 문자열 | Yes | 대화에서 이 메시지의 고유 식별자입니다. |
| 역할 | 문자열 | Yes | 메시지의 원본(예: 사용자, 도우미)입니다. |
| 내용 | 문자열 | Yes | 메시지 텍스트입니다. |
| 시간표시 | string(date-time) | 아니오 | 메시지를 보낸 시간을 나타내는 ISO 8601 타임스탬프를 표시합니다. |
도구 실행 결과
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 도구 ID | 문자열 | Yes | 대화에서 이 메시지의 고유 식별자입니다. |
| toolName | 문자열 | Yes | 도구의 이름입니다. |
| 출력 | ExecutionOutput[] | Yes | 도구 실행 출력 목록입니다. |
| 시간표시 | string(date-time) | 아니오 | 도구 실행이 완료된 시기를 나타내는 ISO 8601 타임스탬프를 나타냅니다. |
실행 출력
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 이름 | 문자열 | Yes | 출력 매개 변수의 이름입니다. |
| description | 문자열 | 아니오 | 출력 값에 대한 설명입니다. |
| type | 객체 | 아니오 | 출력의 데이터 형식입니다. |
| value | JSON 데이터 값 | Yes | 출력 값입니다. |
도구 정의
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 아이디 | 문자열 | Yes | 도구의 고유 식별자입니다. |
| type | 문자열 | Yes | Planner에 사용되는 도구의 종류를 지정합니다. |
| 이름 | 문자열 | Yes | 사람이 읽을 수 있는 도구 이름입니다. |
| description | 문자열 | Yes | 도구가 수행하는 작업의 요약입니다. |
| 입력 매개변수 | ToolInput[] | 아니오 | 도구의 입력 매개 변수입니다. |
| outputParameters | ToolOutput[] | 아니오 | 실행 후 도구가 반환하는 출력 매개 변수입니다. |
도구 입력
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 이름 | 문자열 | Yes | 입력 매개 변수의 이름입니다. |
| description | 문자열 | 아니오 | 이 입력 매개 변수의 예상 값에 대한 설명입니다. |
| type | JSON 개체 | 아니오 | 입력 매개 변수의 데이터 형식입니다. |
도구출력
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 이름 | 문자열 | Yes | 출력 매개 변수의 이름입니다. |
| description | 문자열 | 아니오 | 출력 값에 대한 설명입니다. |
| type | JSON 개체 | 아니오 | 출력 값의 유형입니다. |
대화메타데이터
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 에이전트 | AgentContext | Yes | 에이전트 컨텍스트 정보입니다. |
| 사용자 | UserContext | 아니오 | 에이전트와 상호 작용하는 사용자에 대한 정보입니다. |
| trigger | TriggerContext | 아니오 | Planner 실행을 트리거한 내용에 대한 정보입니다. |
| conversationId | 문자열 | Yes | 진행 중인 대화의 ID입니다. |
| planId | 문자열 | 아니오 | 사용자 요청을 수행하는 데 사용되는 계획의 ID입니다. |
| planStepId | 문자열 | 아니오 | 이 도구 실행에 해당하는 계획 내에서 단계별로 실행합니다. |
| 상위에이전트구성요소ID | 문자열 | 아니오 | 부모 에이전트 구성 요소의 ID입니다. |
AgentContext
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 아이디 | 문자열 | Yes | 에이전트의 ID입니다. |
| tenantId | 문자열 | Yes | 에이전트가 있는 테넌트입니다. |
| environmentId | 문자열 | Yes | 에이전트가 게시되는 플랫폼 환경입니다. |
| version | 문자열 | 아니오 | 에이전트 버전(false인 경우 isPublished 선택 사항). |
| isPublished | 불리언 (Boolean) | Yes | 이 실행 컨텍스트가 게시된 버전인지 여부입니다. |
사용자 컨텍스트
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 아이디 | 문자열 | 아니오 | 사용자의 Microsoft Entra 개체 ID. |
| tenantId | 문자열 | 아니오 | 사용자의 테넌트 ID입니다. |
트리거 컨텍스트 (TriggerContext)
| Name | 유형 | 필수 | 설명 |
|---|---|---|---|
| 아이디 | 문자열 | 아니오 | 계획자를 발동시킨 트리거의 ID입니다. |
| schemaName | 문자열 | 아니오 | Planner를 트리거한 트리거 스키마의 이름입니다. |
Authentication
개발하는 통합은 Microsoft Entra ID 인증을 사용해야 합니다. 개발자가 빌드하는 앱 통합에 대한 지침을 따릅니다.
수행할 단계는 다음과 같습니다.
- 테넌트에서 리소스에 대한 앱 등록을 생성합니다.
-
웹 API에 대한 범위를 노출합니다. 노출된 범위는 고객이 호출하는 리소스의 기본 URL이어야 합니다. 예를 들어, API URL이
https://security.contoso.com/api/threatdetection인 경우, 공개된 범위는 반드시https://security.contoso.com이어야 합니다. - 서비스를 구현하는 방법에 따라 권한 부여 논리를 구현하고 들어오는 토큰의 유효성을 검사해야 합니다. 고객이 앱에 권한을 부여하는 방법을 문서화해야 합니다. 예를 들어, 앱 ID 허용 목록이나 역할 기반 접근 제어(RBAC) 등이 있습니다.
응답 시간 요구 사항
에이전트는 1,000ms 미만의 위협 탐지 시스템의 응답을 기대합니다. 엔드포인트가 이 시간 프레임 내에서 호출에 회신하는지 확인해야 합니다. 시스템이 시간에 응답하지 않으면 에이전트는 응답이 도구를 호출하는 "허용"인 것처럼 동작합니다.
API 버전 관리
요청에서 API 버전은 쿼리 매개 변수(예: api-version)를 통해 api-version=2025-05-01 지정됩니다. 구현은 다른 예기치 않은 필드에 관대해야 하며 나중에 새 값이 추가될 경우 실패하지 않아야 합니다. 현재 모든 버전은 호환성을 유지하는 것으로 간주되기 때문에 파트너는 API 버전을 확인할 필요가 없습니다. 파트너는 API 버전을 추적해야 하지만 새 버전이 표시되면 요청에 실패하지 않아야 합니다.