# Le secours d'un fournisseur d'IA préserve-t-il les identifiants et les audits ?

Un pipeline d'IA ne conserve pas automatiquement son niveau de sécurité parce qu'il réessaie la même invite ailleurs. Un secours peut modifier l'identifiant qui autorise l'appel, le compte qui reçoit la facture, la région qui traite les données et les éléments que vous pourrez examiner plus tard. Si ces changements se produisent dans une boucle de nouvelles tentatives du SDK, le chemin d'échec dispose de plus d'autorité que ce qui a été prévu lors de la revue de conception.

J'ai vu des équipes traiter un endpoint de modèle de secours comme une simple tuyauterie sans risque. Tout commence généralement par un objectif raisonnable : maintenir un agent de programmation ou un flux documentaire en fonctionnement lorsqu'un fournisseur dépasse le délai d'attente. Puis une variable d'environnement, un profil par défaut ou un paramètre global de nouvelles tentatives transforme une route approuvée avec précision en route non déclarée. La requête aboutit, et personne ne remarque rien jusqu'à ce que la finance pose des questions sur un compte inconnu ou qu'une revue d'incident ne puisse pas établir où les données sont parties.

La solution n'est pas une politique de nouvelles tentatives plus sophistiquée. Prenez la décision d'autorité avant l'appel, rendez chaque destination possible explicite et créez une seule piste de preuves qui survive à une défaillance partielle. La disponibilité compte, mais elle ne justifie pas l'ambiguïté sur l'identité de l'acteur qui a agi en dehors de votre périmètre.

## Une route de secours est une deuxième voie d'autorité

Une route de secours a besoin de sa propre autorisation, car elle peut utiliser des identifiants et des autorisations contractuelles dont la route principale ne disposait pas. L'appeler une nouvelle tentative ne change rien à ce fait.

Une route ne se résume pas à un nom d'hôte et au nom d'un modèle. Elle comprend le fournisseur, le compte ou projet du fournisseur, la référence de l'identifiant, la région autorisée, la classification des données, le paramètre de conservation accepté et l'état de l'autorisation. Si l'un de ces champs diffère, l'appel alternatif produit un effet externe différent.

Les équipes confondent souvent continuité du transport et continuité de l'autorité. La continuité du transport signifie que l'appelant a reçu une réponse après la défaillance d'un endpoint. La continuité de l'autorité signifie que le travail a été effectué par la même organisation, dans la même région approuvée et avec le même périmètre d'identifiants. La première peut exister sans la seconde. Cette distinction détermine si un secours est sûr.

Prenons le cas d'un agent de programmation chargé de résumer un export du support client. La route principale envoie un texte expurgé à un compte approuvé dans une région définie. Un délai d'attente déclenche un client alternatif, qui lit un identifiant générique dans l'environnement du processus et envoie le même texte à un compte sandbox personnel dans une autre région. La tâche semble s'être déroulée normalement. La frontière de sécurité, elle, ne tient plus.

Ne résolvez pas ce problème en interdisant tous les secours. Certains travaux ont plusieurs destinations réellement interchangeables. Définissez cette équivalence sous forme d'un enregistrement de propriétés concrètes, puis faites-la respecter par le routeur. Une destination de secours dépourvue de compte, de région et de référence d'identifiant déclarés est incomplète, même si elle répond parfaitement à l'invite.

## Trois identités peuvent changer indépendamment

Le nom du fournisseur, l'identité de facturation et l'identité de l'identifiant sont trois champs distincts, et une route doit les transporter tous les trois. Supposer que l'un implique les autres crée l'angle mort le plus fréquent dans les environnements multi-fournisseurs.

Le fournisseur est l'entreprise ou le service qui reçoit la requête. L'identité de facturation est le compte, le projet, l'organisation, l'accord avec un revendeur ou l'abonnement cloud facturé. L'identité de l'identifiant est le secret précis ou le jeton délégué qui autorise l'action. Un même fournisseur peut proposer de nombreuses identités de facturation et de nombreux identifiants ayant des autorisations différentes.

C'est important pendant les pannes, car le code de secours cherche souvent ce qui fonctionne. Une bibliothèque cliente peut sélectionner son projet par défaut. Un conteneur peut hériter de l'identifiant d'un développeur. Une identité de charge de travail peut créer un jeton pour un autre locataire après une modification de configuration. Aucun de ces comportements ne paraît spectaculaire dans un journal applicatif. Il s'agit pourtant d'actions externes effectuées sous une autorité différente.

Décrivez la route comme un objet complet avant d'ouvrir une connexion réseau. Cette pseudoconfiguration montre la structure minimale :

```json
{
  "operation_class": "customer-text-summary",
  "primary": {
    "provider": "provider-a",
    "account": "production-eu",
    "credential_ref": "vault:provider-a-prod-eu",
    "region": "eu",
    "data_class": "redacted-customer-text"
  },
  "fallbacks": [
    {
      "provider": "provider-b",
      "account": "production-backup-eu",
      "credential_ref": "vault:provider-b-backup-eu",
      "region": "eu",
      "data_class": "redacted-customer-text",
      "approval": "destination-specific"
    }
  ],
  "deny_when": ["account_missing", "region_mismatch", "credential_ref_missing"]
}
```

Cette structure est volontairement peu spectaculaire. Elle sert à empêcher un SDK de remplir les champs du compte ou de l'identifiant après la décision de routage. Gardez les secrets hors de cet enregistrement. Une référence d'identifiant indique quelle autorité peut être utilisée ; elle ne doit jamais contenir l'identifiant lui-même.

Classez l'appelant séparément de la destination. Un processus agent peut être suffisamment fiable pour demander une tâche sans avoir l'autorisation d'envoyer cette tâche à tous les comptes fournisseurs détenus par votre entreprise. L'appelant fait une demande. Le résolveur de routes décide si une destination approuvée existe.

## Les identifiants par défaut créent des changements de compte silencieux

Les identifiants ambiants sont pratiques pour le développement local et dangereux dans une route de secours, car ils transforment l'état du processus en politique d'autorisation. Le code qui gère une panne ne devrait jamais découvrir un compte en demandant à l'environnement d'exécution quels identifiants sont disponibles.

Une séquence d'échec classique ressemble à ceci :

1. Un worker envoie une requête via le fournisseur A avec une référence d'identifiant de production explicite.
2. Le fournisseur A renvoie un délai d'attente après que la requête a atteint un état incertain.
3. Le wrapper de nouvelles tentatives sélectionne le fournisseur B et construit son client avec la découverte d'identifiants par défaut.
4. Le fournisseur B accepte un identifiant présent dans l'environnement du worker, peut-être un rôle cloud partagé ou un jeton créé par un développeur.
5. Le worker écrit uniquement `fallback succeeded` et renvoie le résultat.

Chaque ligne peut passer une revue de code si les évaluateurs se concentrent sur le traitement de la réponse. Le problème se trouve dans les champs omis. Quel compte a accepté la requête ? Quelle région l'a traitée ? L'invite pouvait-elle être envoyée à cette destination ? Le délai d'attente signifie-t-il que le fournisseur A a également terminé la première requête, laissant deux copies des données en dehors du chemin prévu ?

Exigez que le constructeur de secours reçoive une référence d'identifiant et une assertion de compte. L'assertion est l'identifiant que vous vous attendez à voir renvoyé par le service distant pour l'appelant authentifié. Si le service ne peut pas l'exposer par programmation, enregistrez le compte choisi par votre courtier d'identifiants et limitez l'identifiant afin qu'il ne puisse pas atteindre un compte imprévu.

Ne placez pas un jeton de secours à longue durée dans une variable d'environnement en appelant cela de la résilience. Il devient l'identifiant le plus facile à utiliser pour chaque processus de cette machine, y compris un nouvel outil qui n'a jamais fait partie de la conception du routage. Utilisez un coffre-fort ou un courtier qui ne libère un identifiant qu'après la sélection de la destination, et enregistrez cette libération comme un événement.

Un secours doit également avoir un budget. Ce budget ne se résume pas à une limite de dépenses. Limitez les tentatives par opération, destination et fenêtre temporelle afin qu'une panne généralisée d'un fournisseur ne fasse pas se disperser une file d'attente et exécuter la même tâche sensible sur plusieurs comptes. Si vous ne pouvez pas savoir si la tentative principale a atteint le fournisseur, marquez le résultat comme incertain et traitez explicitement cet état. Réessayer à l'aveugle est la façon dont les actions externes en double deviennent normales.

## Une trace continue a besoin de plus qu'un identifiant de requête

Un seul identifiant d'opération peut relier les événements de secours, mais une piste d'audit reste incomplète si chaque tentative n'indique pas l'autorité utilisée. La corrélation répond à la question de savoir quels événements vont ensemble ; les champs de route expliquent ce qui s'est réellement passé.

Créez un identifiant d'opération avant de sélectionner la route principale. Conservez-le pour la requête utilisateur, l'exécution de l'agent ou la tâche en file d'attente. Créez ensuite un numéro de tentative pour chaque appel fournisseur, y compris les appels bloqués avant le réseau. Un enregistrement utile ressemble à ceci :

```json
{
  "operation_id": "op_7c1d",
  "attempt": 2,
  "parent_attempt": 1,
  "reason": "primary_timeout",
  "provider": "provider-b",
  "account": "production-backup-eu",
  "credential_ref": "vault:provider-b-backup-eu",
  "region": "eu",
  "data_class": "redacted-customer-text",
  "approval_id": "apr_391",
  "result": "sent"
}
```

Écrivez un événement de résultat ultérieur avec le même identifiant d'opération et le même numéro de tentative. Ajoutez les identifiants de requête distants si le fournisseur les renvoie, mais n'en faites pas votre champ de corrélation principal. Ils n'existent pas pour les appels bloqués, et deux fournisseurs n'utiliseront pas forcément le même format.

La W3C Trace Context Recommendation définit un identifiant de trace qui se propage entre les frontières de service, et OpenTelemetry utilise ce contexte pour relier les spans. Utilisez-le pour le traçage opérationnel lorsque vos services le prennent en charge. Il ne remplace pas les champs d'autorité ci-dessus. Une trace peut montrer avec précision qu'une requête a traversé cinq services sans répondre à la question de savoir quel identifiant a franchi la dernière frontière.

Séparez une action tentée d'une action terminée. Si le routeur a choisi le fournisseur B mais que l'autorisation a été refusée, enregistrez une tentative bloquée. Si la requête a quitté votre réseau mais que la connexion a été interrompue, enregistrez une tentative incertaine. Si le fournisseur B a renvoyé une réponse, enregistrez une exécution terminée. Les personnes chargées de l'incident ont besoin de ces distinctions, et l'agent doit recevoir un résultat qui les préserve plutôt qu'une vague erreur de nouvelle tentative.

Utilisez un journal chaîné par hachage ou une autre conception en ajout uniquement pour l'enregistrement d'audit. Une base de données applicative modifiable peut servir aux rapports, mais elle permet à un administrateur ou à un processus compromis de réécrire précisément la séquence dont vous aurez besoin pendant une enquête. Reliez les traces opérationnelles, les journaux applicatifs et les preuves de sécurité par des identifiants, sans prétendre qu'ils offrent les mêmes garanties d'intégrité.

## La résidence des données nécessite un refus explicite

Une contrainte de résidence doit rejeter toute route alternative qui ne la respecte pas, même pendant une panne du fournisseur. Le secours sûr est parfois un échec contrôlé.

Ne réduisez pas la résidence à une étiquette de région dans un tableau de bord. Définissez ce que votre organisation entend par là pour la classe de données concernée : lieu de traitement, lieu de stockage, accès du support, conservation et éventuels sous-traitants approuvés. Le résolveur de routes doit partir de cette décision et non la deviner à partir de l'endpoint le plus proche du fournisseur.

Une erreur fréquente consiste à déclarer une région principale, puis à configurer une sauvegarde globale qui hérite de la géographie par défaut du fournisseur. La route principale semble conforme en fonctionnement normal. La sauvegarde n'apparaît dans les journaux que lorsque le service est dégradé, c'est-à-dire précisément au moment où les détails sont le moins consultés. C'est pourquoi les règles de secours doivent comporter des assertions de région explicites et une voie de refus pour toute destination qui ne peut pas garantir la propriété requise.

Conservez la minimisation des données dans la couche de routage. Si une tâche peut s'exécuter sur un texte expurgé, l'expurgation doit avoir lieu avant la sélection du fournisseur afin que chaque route autorisée reçoive la même charge utile réduite. Ne comptez pas sur une intégration du fournisseur principal pour supprimer des champs tandis qu'une intégration de secours envoie l'objet original. Le contrat de route doit indiquer la classe de données autorisée, et le générateur de charge utile doit refuser une classe plus large.

Il existe des cas légitimes où un opérateur peut approuver une exception temporaire. Traitez-la comme une exception avec une expiration visible, un approbateur nommé et un nouvel événement d'audit. Ne la transformez pas silencieusement en règle de routage permanente après l'incident. Une panne pousse à élargir les frontières ; elle n'efface pas la raison pour laquelle ces frontières existaient.

## Placez le routeur avant les identifiants

Un résolveur de routes unique doit sélectionner la destination avant qu'un client fournisseur reçoive un identifiant. Cela supprime le second moteur de politique caché qui apparaît lorsque chaque SDK possède ses propres nouvelles tentatives, valeurs par défaut et mécanismes de basculement.

Le résolveur a besoin d'entrées liées au travail et non à la bibliothèque cliente : classe d'opération, classe de données, identité de l'appelant, destinations approuvées, exigence de résidence, autorité de dépense et nécessité éventuelle d'une validation humaine. Il renvoie soit une route complète, soit un refus. Il ne doit pas renvoyer une liste de possibilités vagues que le code en aval devra interpréter.

Gardez l'adaptateur fournisseur étroit. Il reçoit une route, obtient l'identifiant référencé via la frontière de secrets approuvée, envoie la requête et signale le résultat. Il ne doit pas sélectionner un autre fournisseur après une erreur. S'il doit réessayer une défaillance de transport transitoire vers la même destination entièrement spécifiée, consignez-la comme une nouvelle tentative. S'il veut changer de destination, il doit rendre le contrôle au résolveur.

Cette séparation permet aussi de répondre à une question difficile : qui a autorisé le secours ? La réponse doit être une décision de route liée à un appelant, une opération et un enregistrement d'autorisation, et non une ligne cachée dans les paramètres de nouvelles tentatives d'une dépendance.

Pour les équipes macOS, Sallyport conserve les identifiants des agents dans un coffre-fort chiffré et enregistre les sessions des agents ainsi que les actions HTTP ou SSH individuelles, mais le routeur doit toujours spécifier chaque destination prévue avant de demander à Sallyport d'effectuer l'appel.

Ne confondez pas une passerelle d'identifiants avec un langage de politique généraliste. Vous n'avez pas besoin d'un vaste système de règles pour faire les choses correctement. Un ensemble fixe de champs de route et quelques conditions de refus claires sont plus faciles à examiner, tester et expliquer sous pression.

## L'autorisation doit couvrir la destination

Une autorisation n'a de sens que si elle indique à la personne quelle action externe aura lieu, y compris la destination modifiée par un secours. Autoriser uniquement un processus agent ne prouve pas que tous les comptes auxquels ce processus pourrait accéder plus tard ont été approuvés.

Utilisez deux points de décision lorsque le travail le justifie. D'abord, autorisez l'exécution de l'agent ou la charge de travail à demander des actions. Ensuite, exigez une autorisation propre à la destination lorsque la route franchit un seuil de sensibilité, change de fournisseur, utilise un autre compte de facturation ou traite une classe de données restreinte. La seconde décision peut être automatique pour des équivalents préapprouvés, mais elle doit découler des propriétés déclarées de la route.

La fiche ou l'enregistrement d'autorisation doit indiquer l'autorité de l'agent, le but de l'opération, le fournisseur, le compte, la région, la classe de données et l'expiration. Il n'est pas nécessaire d'afficher un secret, l'invite complète ou un mur d'identifiants internes. Il faut toutefois suffisamment d'informations pour qu'une personne voie qu'un compte de production européen est devenu un compte de test personnel ou qu'une route régionale a changé.

Évitez la lassitude liée aux autorisations en réservant la confirmation par appel aux actions qui en ont réellement besoin. Des demandes répétées pour des appels courants et préapprouvés apprennent aux utilisateurs à cliquer machinalement. La solution n'est pas un secours silencieux. C'est un petit ensemble de classes de routes avec des valeurs par défaut honnêtes, complété par une autorisation distincte lorsque la destination sort de cette classe.

La révocation compte autant que l'autorisation. Si vous découvrez qu'une exécution d'agent se comporte mal, terminez sa session et empêchez les nouveaux appels d'utiliser cette autorité. Si un identifiant ou un compte fournisseur semble compromis, désactivez la route et faites en sorte que le résolveur la refuse. Un enregistrement d'audit capable d'indiquer l'heure de l'arrêt est bien plus utile qu'une note générique signalant qu'une configuration a été modifiée.

## Testez la dégradation comme une panne de production

Une conception de secours n'est pas éprouvée tant que des échecs provoqués n'ont pas montré la route exacte, la référence d'identifiant et la séquence d'audit produites sous pression. Les tests d'intégration du chemin nominal n'exercent pas la branche où l'autorité change.

Créez un adaptateur de fournisseur de test capable de renvoyer un délai d'attente après avoir accepté une requête, une limitation de débit avant de l'accepter, une erreur d'authentification, une réponse malformée et une non-concordance d'assertion de région. Ces échecs ont des significations différentes. Un délai d'attente après soumission crée une incertitude sur l'exécution ; une erreur d'authentification ne doit pas pousser le routeur à chercher un autre identifiant dans l'environnement local.

Pour chaque cas d'échec, vérifiez cinq résultats :

- Le résolveur a choisi une route alternative entièrement spécifiée ou un refus.
- Le courtier d'identifiants a reçu exactement la référence d'identifiant de cette route.
- Le journal d'audit contient un enregistrement de tentative avant l'appel externe et un enregistrement de résultat après celui-ci.
- L'identifiant d'opération relie les tentatives principale et alternative sans fusionner des tâches distinctes.
- L'état renvoyé distingue le travail bloqué, échoué et incertain.

Exécutez les tests avec les identifiants principal et de secours délibérément associés à des comptes différents. Si les deux pointent vers le même compte dans un environnement de test, une assertion de compte manquante peut passer inaperçue. Exécutez-les aussi sans aucun identifiant ambiant disponible. Une conception qui ne fonctionne que parce que la découverte par défaut la sauve n'a pas démontré l'existence d'une frontière.

Testez le comportement des files d'attente. Un worker peut tomber en panne après avoir envoyé une requête, puis un nouveau worker peut reprendre la tâche avec une nouvelle identité de processus. Vérifiez qu'il lit l'état antérieur de l'opération, conserve l'identifiant d'opération et ne répète pas une requête incertaine simplement parce que sa mémoire locale est vide. Si l'action métier ne peut pas être répétée sans risque, exigez un jeton d'idempotence distant lorsque le fournisseur le prend en charge, puis stockez ce jeton dans l'enregistrement de tentative.

Enfin, testez l'expérience de l'opérateur. Demandez à quelqu'un qui n'a pas écrit le code de routage d'expliquer un événement de secours à partir du journal. Cette personne doit pouvoir identifier l'appelant, la destination initiale, la raison du changement, le compte et la région alternatifs, la décision d'autorisation et le résultat final. Si elle a besoin d'une requête de base de données et de trois journaux applicatifs pour répondre, la conception d'audit reste trop fragmentée.

## Préservez les preuves après l'incident

La piste d'audit doit rester consultable lorsque le fournisseur, le worker ou le compte administrateur impliqué dans l'incident n'est plus digne de confiance. Stockez localement suffisamment de métadonnées de route pour reconstruire la décision sans dépendre d'une console fournisseur qui a pu changer ou devenir indisponible.

Gardez les valeurs secrètes brutes hors du journal. Enregistrez des références d'identifiants stables, des identifiants de compte et, lorsque c'est pertinent, des empreintes cryptographiques. Un évaluateur doit pouvoir prouver quelle autorité a été sélectionnée, sans obtenir une nouvelle façon de l'utiliser.

Vérifiez régulièrement le journal et pendant la réponse à un incident. La commande `sp audit verify` de Sallyport vérifie hors ligne son journal d'audit chiffré et chaîné par hachage sans exiger de clé de coffre-fort, ce qui correspond au type de contrôle utile lorsque vous voulez préserver les preuves sans ouvrir les secrets qui ont permis les actions.

Lorsque vous découvrez un secours non déclaré, corrigez le contrat de route avant de mettre le rapport en ordre. Conservez la configuration défaillante, révoquez l'autorité concernée, identifiez les identifiants d'opération qui l'ont utilisée et ajoutez un test qui fait échouer clairement la même substitution. La prochaine panne retrouvera la même faiblesse si le système n'a pas de raison concrète de la refuser.
