Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les organisations peuvent ajouter une couche de sécurité à leurs assistants Copilot Studio en les connectant à un système de détection des menaces à l’exécution. Une fois connecté, l’assistant appelle ce système à l’exécution. L’assistant fournit au système des données afin que celui-ci puisse déterminer si un outil qu’il prévoit d’invoquer est légitime ou non. Le système répond alors à Copilot Studio avec une réponse de « approuver » ou « bloquer », ce qui amène l’assistant à invoquer ou à ignorer l’outil en conséquence. Pour plus d’informations sur la façon de connecter des assistants à un système externe de détection des menaces existant, voir Activer la détection et la protection contre les menaces pour les assistants personnalisés de Copilot Studio.
Cet article s’adresse aux développeurs et décrit comment intégrer vos propres capacités de détection de menaces en tant que fournisseur de sécurité pour les assistants Copilot Studio.
L’intégration repose sur une API composée de deux points de terminaison. Le principal point de terminaison que vous devez implémenter est le point de terminaison analyze-tool-execution. Vous devez exposer ce point de terminaison en tant qu’interface avec votre système de détection des menaces. Une fois que les clients configurent votre système comme leur système externe de détection de menaces, l’assistant appelle cette API à chaque fois qu’il souhaite invoquer un outil.
En plus du point de terminaison analyze-tool-execution, vous devez également exposer un deuxième point de terminaison, appelé validate. Le point de terminaison validate est utilisé pour vérifier la santé et la préparation du point de terminaison dans le cadre de la configuration du système.
Les sections suivantes présentent chaque point de terminaison de manière détaillée.
POST /valider
Objectif : Vérifie que le point de terminaison de détection de menace est accessible et fonctionnel. Utilisé pour la configuration initiale et les tests de configuration.
Valider la requête
Méthode : POST
URL :
https://{threat detection endpoint}/validate?api-version=2025-05-01Headers :
Autorisation : jeton du porteur pour l’authentification d’API
x-ms-correlation-id: GUID pour le traçage
Corps : Vide
Valider la réponse
Exemple de réponse OK 200
{
"isSuccessful": true,
"status": "OK"
}
Exemple de réponse d’erreur
Si une erreur survient (code HTTP infructueux), le point de terminaison renvoie un code d’erreur, un message et des diagnostics optionnels.
{
"errorCode": 5031,
"message": "Validation failed. Webhook service is temporarily unavailable.",
"httpStatus": 503,
"diagnostics": "{\\reason\\:\\Upstream dependency timeout\\}"
}
POST /analyze-tool-execution
Objectif : envoie le contexte d’exécution de l’outil pour l’évaluation des risques. Évalue la demande d’exécution de l’outil et répond s’il faut autoriser ou bloquer cette exécution.
Requête Analyze-tool-execution
Méthode : POST
URL :
https://{threat detection endpoint}/analyze-tool-execution?api-version=2025-05-01Headers :
- Autorisation : jeton du porteur pour l’authentification d’API
- Content-Type : application/json
Corps : objet JSON
Exemple de requête 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"
}
}
Réponse Analyze-tool-execution
200 OK
Lorsque la requête est valide, l’utilisation de l’outil spécifiée dans la requête est évaluée et soit autorisée , soit bloquée, selon les critères définis. La réponse peut inclure les champs suivants :
- blockAction (booléen) : Indique si l’action doit être bloquée
- reasonCode (entier, facultatif) : Code numérique expliquant la raison du blocage
- raison (chaîne, facultative) : explication compréhensible par un humain
- diagnostics (objet, facultatif) : autres détails pour le traçage ou le débogage
Exemple de réponse d’autorisation
{
"blockAction": false
}
Exemple de réponse de blocage
{
"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\\}"
}
Exemple de réponse d’erreur
Si la requête n’est pas valide, une réponse d’erreur est renvoyée avec un code d’erreur, un message, un statut HTTP et des diagnostics optionnels.
{
"errorCode": 4001,
"message": "Missing required field: toolDefinition",
"httpStatus": 400,
"diagnostics": "{\\missingField\\:\\toolDefinition\\,\\traceId\\:\\abc-123\\}"
}
Référence des structures des corps de requête et de réponse
Les tableaux suivants décrivent les contenus des différents objets utilisés dans les corps de requête et de réponse des points de terminaison.
ValidationResponse
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| isSuccessful | Booléen | Oui | Indique si la validation a été réussie. |
| status | chaine | Oui | Message de statut optionnel ou détail spécifique à un partenaire. |
AnalyzeToolExecutionResponse
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| blockAction | Booléen | Oui | Indique si l’action doit être bloquée. |
| reasonCode | entier | Non | Code de motif numérique optionnel, déterminé par le partenaire. |
| reason | string | Non | Explication optionnelle lisible par un humain. |
| diagnostics | chaine | Non | Informations de diagnostic facultatives en texte libre pour le débogage ou la télémétrie. Doit être présérialisé. |
ErrorResponse
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| errorCode | entier | Oui | Identifiant numérique pour l’erreur (p. ex., 1001 = champ manquant, 2003 = échec d’authentification). |
| message | string | Oui | Explication compréhensible de l’erreur. |
| httpStatus | entier | Oui | Code d’état HTTP renvoyé par le partenaire. |
| diagnostics | chaine | Non | Informations de diagnostic facultatives en texte libre pour le débogage ou la télémétrie. Doit être présérialisé. |
EvaluationRequest
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| plannerContext | PlannerContext | Oui | Données contextuelles du Planner. |
| toolDefinition | ToolDefinition | Oui | Détails de la définition de l’outil. |
| inputValues | Objet JSON | Oui | Dictionnaire de paires clé-valeur fourni à l’outil. |
| conversationMetadata | ConversationMetadata | Oui | Métadonnées sur le contexte de la conversation, l’utilisateur et le suivi du plan. |
PlannerContext
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| userMessage | chaine | Oui | Le message original envoyé par l’assistant. |
| pensée | chaine | Non | Explication du planificateur sur la raison de la sélection de cet outil |
| chatHistory | ChatMessage[] | Non | Liste des messages de discussion récents échangés avec l’utilisateur. |
| previousToolsOutputs | ToolExecutionOutput[] | Non | Liste des résultats récents des outils. |
ChatMessage
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| ID | string | Oui | Identifiant unique de ce message dans la conversation. |
| role | chaine | Oui | Source du message (p. ex., utilisateur, assistant). |
| contenu | chaine | Oui | Texte du message. |
| horodateur | chaîne (date-heure) | Non | Horodatage ISO 8601 indiquant quand le message a été envoyé. |
ToolExecutionOutputs
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| toolId | chaine | Oui | Identifiant unique de ce message dans la conversation. |
| toolName | chaine | Oui | Nom de l’outil. |
| sorties | ExecutionOutput[] | Oui | Liste des sorties d’exécution de l’outil. |
| horodateur | chaîne (date-heure) | Non | Horodatage ISO 8601 indiquant le moment où l’exécution de l’outil s’est terminée. |
ExecutionOutput
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| nom | string | Oui | Nom du paramètre de sortie. |
| description | string | Non | Explication de la valeur de sortie. |
| type | object | Non | Type de données de la sortie. |
| value | Valeur de données JSON | Oui | Valeur de sortie. |
ToolDefinition
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| ID | string | Oui | Identificateur unique de l’outil. |
| type | chaine | Oui | Indique le type d’outil utilisé dans le planificateur. |
| nom | string | Oui | Nom lisible par un humain de l’outil. |
| description | string | Oui | Résumé de ce que fait l’outil. |
| inputParameters | ToolInput[] | Non | Paramètres d’entrée de l’outil. |
| outputParameters | ToolOutput[] | Non | Paramètres de sortie que l’outil renvoie après exécution. |
ToolInput
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| nom | string | Oui | Nom du paramètre d’entrée. |
| description | string | Non | Explication de la valeur attendue pour ce paramètre d’entrée. |
| type | Objet JSON | Non | Type de données pour le paramètre d’entrée. |
ToolOutput
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| nom | string | Oui | Nom du paramètre de sortie. |
| description | string | Non | Explication de la valeur de sortie. |
| type | Objet JSON | Non | Type de la valeur de sortie. |
ConversationMetadata
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| agent | AgentContext | Oui | Informations contextuelles de l’assistant. |
| Utilisateur de | UserContext | Non | Information sur l’utilisateur qui interagit avec l’assistant. |
| trigger | TriggerContext | Non | Informations sur ce qui a déclenché l’exécution du planificateur. |
| conversationId | chaine | Oui | ID de la conversation en cours. |
| planId | chaine | Non | ID du plan utilisé pour satisfaire la demande de l’utilisateur. |
| planStepId | chaine | Non | Étape du plan correspondant à cette exécution d’outil. |
| parentAgentComponentId | chaine | Non | ID du composant de l’élément parent assistant. |
AgentContext
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| ID | string | Oui | ID de l’assistant. |
| tenantId | chaine | Oui | Locataire où réside l’assistant. |
| environmentId | chaine | Oui | Environnement dans lequel l’assistant est publié. |
| version | chaine | Non | Version de l’assistant (optionnelle si isPublished est faux). |
| isPublished | Booléen | Oui | Indique si ce contexte d’exécution est une version publiée. |
UserContext
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| ID | string | Non | ID d’objet utilisateur Microsoft Entra. |
| tenantId | chaine | Non | ID client de l’utilisateur. |
TriggerContext
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
| ID | string | Non | L’identifiant du déclencheur ayant déclenché le planificateur. |
| schemaName | chaine | Non | Le nom du schéma déclencheur ayant déclenché le planificateur. |
Authentification
L’intégration que vous développez doit utiliser l’authentification Microsoft Entra ID. Suivez les instructions sur Intégrer les applications que vos développeurs créent.
Pour ce faire, procédez comme suit :
- Créez une inscription d’application pour votre ressource dans votre locataire.
-
Exposez une étendue pour votre API web. L’étendue exposée doit être l’URL de base de la ressource appelée par les clients. Par exemple, si l’URL de l’API est
https://security.contoso.com/api/threatdetection, alors l’étendue exposée doit êtrehttps://security.contoso.com. - Selon la façon dont vous implémentez votre service, vous devez implémenter une logique d’autorisation et valider les jetons entrants. Vous devez documenter comment le client doit autoriser ses applications. Il existe plusieurs façons de procéder, p. ex. en utilisant une liste d’autorisation d’ID d’application ou un contrôle d’accès basé sur les rôles (RBAC).
Exigences en matière de temps de réponse
L’assistant attend une réponse du système de détection de menaces en moins de 1 000 ms. Vous devez vous assurer que votre point de terminaison répond à l’appel dans ce délai. Si votre système ne répond pas à temps, l’assistant agit comme si votre réponse était "allow" et invoque l’outil.
Contrôle de version de l’API
Dans les requêtes, la version de l’API est spécifiée via un paramètre de requête api-version (p. ex., api-version=2025-05-01). Votre implémentation doit tolérer d’autres champs inattendus et ne pas échouer si de nouvelles valeurs sont ajoutées à l’avenir. Les partenaires ne doivent pas vérifier la version de l’API, car toutes les versions sont actuellement considérées comme compatibles. Les partenaires doivent suivre les versions de l’API, mais ne doivent pas rejeter la requête lorsqu’une nouvelle version est détectée.