AI

AgentOps : contenir des données sensibles dans les traces avant de couper l'observabilité

Un runbook de production pour borner une fuite dans les traces d'un agent, identifier le champ fautif, canaryer la redaction et restaurer une observabilité exploitable.

04 oct. 2026 aiagentopsagentsmicrosoft-foundryopentelemetryobservabilitysecurityprivacyredactionkqlguardrailsrunbookrollbackproduction

Après une release d’un agent d’exploitation, une équipe découvre qu’un span contient le corps complet d’un ticket : nom, adresse électronique, extrait de journal et jeton temporaire collé par erreur. Couper toutes les traces limite peut-être une nouvelle exposition, mais supprime aussi les preuves nécessaires pour savoir quelles sessions, quels outils et quels exports sont touchés.

Le cas fil rouge est un agent Microsoft Foundry qui consulte des runbooks, lit des tickets et prépare des actions bornées. Une modification de l’instrumentation a ajouté les entrées et sorties d’outils aux attributs de trace. Ce runbook vise quatre décisions : isoler le flux fautif, traiter les données déjà exportées, remettre une télémétrie minimale saine, puis restaurer les champs utiles ou rollbacker l’instrumentation.

Figer l’incident sans recopier la donnée

Commencez par l’identifiant de trace, la release, l’heure UTC, le type de span, l’outil, l’exporter et la destination. Ne collez pas la valeur sensible dans le ticket d’incident. Conservez un hash, une classe de donnée et un pointeur vers une preuve à accès restreint.

yaml incident-trace-sensible.yml
incident:
first_seen_utc: 2026-10-04T15:42:18Z
agent_release: ops-agent-2026-10-04.3
trace_id: <trace-id>
span_name: tool.ticket.read
tool: ticket.read
exporter_route: agent-traces-prod
destinations: [primary_observability, security_archive]

suspected_field:
attribute: tool.result.body
data_class: personal_and_secret
fingerprint_sha256: <restricted-fingerprint>
raw_evidence: <restricted-vault-reference>

containment_owner: platform-security
decision_deadline_utc: 2026-10-04T17:00:00Z

Le fingerprint sert à retrouver la même exposition sans redistribuer son contenu. Si la valeur est un secret, considérez-la compromise dès qu’elle a atteint une destination consultable et lancez sa révocation en parallèle de l’enquête.

Réduire le flux au plus petit périmètre

Identifiez l’endroit où la valeur devient télémétrie. Elle peut entrer par le message utilisateur, un document de retrieval, le résultat d’un outil, une exception, un attribut ajouté par le SDK ou un processor d’enrichissement. Elle peut ensuite être copiée vers plusieurs destinations.

text chemin-donnee-trace.txt
Entrées possibles
message utilisateur | document retrieval | résultat outil | exception

Points de copie
wrapper outil -> instrumentation agent -> collector -> exporter -> destination

Décision par point
Conserver: IDs, versions, statut, latence, taille, politique appliquée
Transformer: identifiants métier en hash stable si corrélation requise
Supprimer: prompt brut, corps outil, headers, tokens, secrets, pièces jointes
Restreindre: preuve brute exceptionnelle, accès et rétention bornés

Le bon confinement ne coupe pas l’agent entier si un seul wrapper d’outil est fautif. Désactivez l’enrichissement concerné, retirez temporairement l’outil du catalogue ou passez-le en lecture seule, et conservez des événements minimaux : trace ID, outil, identité technique, décision de policy, statut et code d’erreur.

Suspendre seulement l’exporter final ne suffit pas si une file, un collector, un stockage secondaire ou un debug log conserve déjà la charge. Cartographiez chaque copie avant de déclarer le flux contenu.

Mesurer l’exposition par métadonnées

Interrogez d’abord les noms d’attributs, versions et routes d’export, pas la valeur sensible en clair. Le schéma ci-dessous suppose une table normalisée AgentTraceEvents ; adaptez les colonnes au pipeline réel.

kusto 01-borner-exposition-traces.kql
let Start = datetime(2026-10-04T14:00:00Z);
let End = datetime(2026-10-04T16:30:00Z);
let SuspectRelease = "ops-agent-2026-10-04.3";
AgentTraceEvents
| where TimeGenerated between (Start .. End)
| where AgentRelease == SuspectRelease
| where AttributeNames has_any ("tool.result.body", "prompt.content", "http.request.header.authorization")
| summarize
  Events = count(),
  FirstSeen = min(TimeGenerated),
  LastSeen = max(TimeGenerated),
  Traces = dcount(TraceId),
  Conversations = dcount(ConversationId)
by SpanName, ToolName, ExporterRoute, Destination
| order by Events desc

Puis cherchez le fingerprint uniquement dans une fonction ou un environnement autorisé, en retournant des identifiants et non des payloads. Le volume d’événements n’est pas le nombre de personnes affectées : une même valeur peut être répétée dans plusieurs spans et destinations.

Définir un contrat de télémétrie positif

Une liste de motifs interdits ne couvre jamais toutes les données sensibles. Définissez plutôt les champs permis par type d’événement. Tout attribut non déclaré doit être supprimé, tronqué ou dirigé vers une route restreinte selon une règle explicite.

yaml contrat-telemetrie-agent.yml
event: agent.tool.completed
allowed:
- trace_id
- conversation_id_hash
- agent_release
- tool_name
- tool_contract_version
- policy_decision
- status_code
- duration_ms
- input_bytes
- output_bytes
forbidden:
- raw_prompt
- tool_arguments_raw
- tool_result_body
- authorization_header
- retrieved_document_content
limits:
string_length: 256
attribute_count: 32
restricted_debug:
enabled: false
approval_required: security_incident_owner
max_retention_hours: 4

Appliquez ce contrat au point le plus proche de la source, puis une seconde fois avant export. La première barrière évite de propager la donnée dans le pipeline ; la seconde protège contre une instrumentation ou un service qui contournerait le wrapper attendu.

Canaryer la redaction avec des marqueurs synthétiques

Ne validez pas la correction avec une vraie adresse, un vrai token ou un extrait client. Injectez des marqueurs uniques, non secrets et classés comme s’ils étaient sensibles. Faites-les passer séparément par le message, le retrieval, les arguments d’outil, le résultat et l’exception.

yaml canaris-redaction.yml
canaries:
- id: user_input_marker
  path: user.message
  value: NAXAYA_CANARY_USER_20261004
- id: retrieval_marker
  path: retrieval.document.content
  value: NAXAYA_CANARY_RETRIEVAL_20261004
- id: tool_result_marker
  path: tool.result.body
  value: NAXAYA_CANARY_TOOL_20261004
- id: exception_marker
  path: exception.message
  value: NAXAYA_CANARY_ERROR_20261004

expected:
allowed_destinations: []
metadata_preserved: [trace_id, tool_name, status_code, policy_decision]
terminal_action: read_only

Le test réussit seulement si aucun marqueur brut n’arrive dans les destinations ordinaires, si les métadonnées attendues restent corrélables et si les erreurs continuent à être diagnostiquables. Une redaction qui transforme toutes les valeurs en chaîne vide peut rendre le pipeline conforme mais inutilisable.

Traiter les copies déjà exportées

La correction du pipeline n’efface pas l’historique. Pour chaque destination, identifiez l’owner, les droits de lecture, les exports secondaires, les sauvegardes, la rétention et les capacités de suppression ou de restriction. Conservez la chronologie et les IDs de preuve même si le payload doit être supprimé.

Révoquez un secret exposé ; ne comptez pas sur la seule suppression des logs. Pour les données personnelles ou métier, suivez la procédure interne de sécurité et de confidentialité. Le runbook technique doit produire la liste des traces, des destinations et des accès possibles, pas décider seul des obligations de notification.

Restaurer progressivement et garder un rollback

Déployez la policy de télémétrie sur une cohorte canari. Réactivez d’abord les diagnostics en lecture seule, puis les outils qui ne retournent pas de contenu libre. Les outils d’écriture reviennent seulement après validation de leurs arguments, résultats, refus et erreurs.

text decision-restauration-traces.txt
Promouvoir
Aucun marqueur brut dans les destinations ordinaires
Champs autorisés présents et corrélables de bout en bout
Erreurs et refus restent exploitables
Révocation et traitement historique terminés ou suivis

Maintenir le confinement
Une route secondaire ou un cache n'est pas qualifié
Le contrat ne couvre pas un type de span
Les droits ou la rétention d'une destination restent inconnus

Rollbacker l'instrumentation
La redaction casse la corrélation ou masque les erreurs critiques
Restaurer le bundle précédent connu
Garder le wrapper fautif et les outils sensibles désactivés
Rejouer tous les canaris avant une nouvelle promotion

Un rollback ne doit jamais remettre en production le champ brut qui a causé l’incident. Il restaure la dernière instrumentation sûre, avec le chemin fautif toujours isolé. Fermez l’incident lorsque le flux courant est propre, l’historique est traité, les secrets exposés sont révoqués et les canaris prouvent à la fois confidentialité et exploitabilité.

Conclusion

Une donnée sensible dans une trace d’agent est un incident de pipeline, pas une raison suffisante pour devenir aveugle. La réponse utile relie release, span, champ, route et destination ; elle conserve les métadonnées nécessaires tout en isolant le contenu brut.

La décision finale est explicite : promouvoir une redaction canaryée, maintenir le confinement tant qu’une copie reste inconnue, ou restaurer un bundle d’instrumentation sûr. L’objectif n’est pas d’avoir moins de traces. C’est de garder des traces qui expliquent les actions sans devenir elles-mêmes une fuite.