# Priorité des en-têtes HTTP : mettez fin aux conflits d'identité des API

Une requête qui contient deux identifiants n'est pas une requête avec une authentification de secours. C'est une instruction ambiguë remise à une chaîne de logiciels qui peut l'interpréter différemment à chaque étape. J'ai vu des équipes passer des heures à accuser une API alors qu'un proxy avait discrètement choisi une valeur Authorization et que l'application en avait choisi une autre. Le symptôme semble aléatoire jusqu'à ce que quelqu'un affiche les en-têtes bruts à chaque frontière.

La priorité des en-têtes HTTP doit suivre une règle que vous pouvez énoncer en une phrase, tester sur le réseau et appliquer avant l'authentification : une requête qui fournit plusieurs valeurs pour un même champ d'identifiant sensible doit échouer. Ne choisissez ni la première ni la dernière. Ne regroupez pas les valeurs avec une virgule. Ces choix transforment un comportement d'implémentation accidentel en politique d'authentification.

Cela concerne bien plus que `Authorization`. De nombreuses API acceptent `X-API-Key`, un en-tête personnalisé de tenant, un horodatage de requête signée ou un champ d'identité transmis. Dès que les identifiants traversent des clients, des répartiteurs de charge, des traducteurs de protocole et des middlewares applicatifs, la gestion des doublons fait partie de la frontière de sécurité.

## HTTP ne désigne pas de valeur gagnante générale

HTTP définit la syntaxe des champs et fournit des règles spéciales de combinaison pour certains champs répétés, mais il ne dit pas que le premier champ `Authorization` gagne partout, ni que le dernier gagne partout. Le destinataire doit interpréter la section de champs reçue selon la sémantique du champ et sa propre implémentation.

La RFC 9110 indique qu'un destinataire peut combiner plusieurs lignes de champ portant le même nom en une seule valeur séparée par des virgules lorsque la définition du champ autorise une liste séparée par des virgules. Elle précise aussi qu'un destinataire ne doit pas combiner les lignes lorsque la définition du champ ne l'autorise pas. Cette distinction est souvent oubliée. « Les en-têtes peuvent être fusionnés » n'est pas une règle applicable à tous les en-têtes. C'est une règle pour les champs conçus comme des listes.

`Accept` offre un bon contraste. Un client peut envoyer plusieurs lignes `Accept`, et un destinataire peut généralement les traiter comme une seule liste de types de contenu acceptables. `Authorization` transporte les identifiants d'une requête. Ce n'est pas une liste générique d'identifiants interchangeables. Une virgule peut aussi avoir une signification dans la syntaxe d'un mécanisme d'authentification. Regrouper deux valeurs peut créer une chaîne qu'aucun client n'avait prévue et que différents analyseurs liront différemment.

Les noms des champs d'en-tête ne sont pas sensibles à la casse. Voici des doublons :

```http
Authorization: Bearer token-a
authorization: Bearer token-b
```

Un détecteur qui compare la graphie d'origine ne verra pas le problème. Normalisez le nom avant de compter les valeurs.

Ne confondez pas les lignes de champ dupliquées avec plusieurs défis d'authentification dans `WWW-Authenticate`. Un serveur peut annoncer plusieurs mécanismes acceptables dans une réponse. Il propose alors des options. Une requête contenant deux valeurs `Authorization` présente des identifiants concurrents côté client. Ce sont deux problèmes différents qui demandent deux traitements différents.

Le même avertissement vaut lorsqu'une API prend en charge un champ d'identification standard et un champ personnalisé. Elle peut accepter volontairement `Authorization: Bearer ...` ou `X-API-Key: ...`. À moins que la documentation de l'API n'explique comment résoudre la présence des deux, leur envoi crée un conflit d'identité. Rejetez la requête. Un mécanisme de secours qui n'existe que dans le middleware de quelqu'un ne constitue pas un contrat.

## Les clients rendent les doublons plus faciles à créer qu'on ne le pense

La possibilité pour un client d'émettre plusieurs fois un en-tête dépend du modèle de requête de sa bibliothèque. Les bibliothèques qui exposent les en-têtes sous forme de dictionnaire écrasent souvent une valeur lorsque le code attribue deux fois le même nom. Celles qui exposent un tableau ou une collection multivaleur peuvent envoyer les deux. Aucun de ces comportements ne prouve ce que recevra l'étape suivante.

Avec curl, répétez `-H` pour demander deux champs :

```bash
curl --http1.1 -v https://api.example.test/orders \
  -H 'Authorization: Bearer first' \
  -H 'Authorization: Bearer second'
```

La trace détaillée doit afficher deux lignes sortantes semblables à celles-ci :

```text
> Authorization: Bearer first
> Authorization: Bearer second
```

Cela prouve seulement que curl a envoyé une requête HTTP/1.1 avec ces deux lignes sur cette connexion. Cela ne prouve pas que la périphérie, le répartiteur de charge ou l'application a reçu les deux valeurs. Testez un point de terminaison contrôlé que vous exploitez avant d'utiliser ce modèle contre une API de production. Les jetons des exemples doivent être jetables, et de vrais jetons Bearer ne doivent jamais apparaître dans un enregistrement de terminal ou un ticket d'assistance.

En JavaScript, l'objet `Headers` courant a une sémantique qui surprend souvent. `set()` remplace la valeur actuelle. `append()` ajoute théoriquement une autre valeur, mais la sérialisation et la sémantique de l'en-tête restent importantes. Un développeur peut croire avoir envoyé deux en-têtes alors que la bibliothèque a construit une valeur séparée par des virgules. C'est précisément pourquoi les tests d'authentification doivent inspecter l'entrée brute, et pas seulement un objet conservé en mémoire.

Le code serveur Node.js présente son propre piège. `req.headers` expose généralement des noms normalisés et peut ne présenter qu'une vue regroupée. `req.rawHeaders` conserve une liste alternée des noms et valeurs reçus pour les requêtes HTTP/1.1. Un diagnostic sûr doit compter les noms normalisés à partir de la représentation brute, puis éviter d'afficher les valeurs secrètes :

```js
function duplicateNames(rawHeaders) {
  const counts = new Map();
  for (let i = 0; i < rawHeaders.length; i += 2) {
    const name = rawHeaders[i].toLowerCase();
    counts.set(name, (counts.get(name) || 0) + 1);
  }
  return [...counts.entries()].filter(([, count]) => count > 1);
}

console.log(duplicateNames(req.rawHeaders));
// Example output: [ [ 'authorization', 2 ] ]
```

Utilisez cela comme aide au diagnostic, pas comme permission de réanalyser manuellement chaque en-tête dans l'application. Votre framework ou votre passerelle doit effectuer le rejet réel au point de confiance le plus précoce. L'objectif est de révéler ce que l'objet d'en-têtes pratique avait masqué.

Les en-têtes personnalisés méritent la même prudence. Un client peut ajouter accidentellement `X-API-Key` deux fois, une fois dans une couche d'en-têtes par défaut et une fois au niveau de la requête. Il peut aussi envoyer une valeur `Authorization` héritée d'un wrapper client d'entreprise alors que le code ajoute explicitement une clé API. L'API peut sembler fonctionner lors des tests locaux parce que le chemin local n'utilise pas ce wrapper. En production, elle reçoit alors les deux identifiants et se comporte différemment.

## Les proxys peuvent modifier la requête et les éléments de preuve

Un proxy inverse est un destinataire HTTP et un nouvel émetteur HTTP. Il ne transporte pas simplement des octets du client vers l'application. Il analyse la requête entrante, applique sa configuration, peut traduire les protocoles et écrit une nouvelle requête vers l'amont. Il peut donc conserver les doublons, les supprimer, les regrouper ou créer un nouvel en-tête d'identification.

Le cas dangereux est celui d'une interprétation différente. Imaginez qu'un client envoie :

```http
Authorization: Bearer attacker-token
Authorization: Bearer service-token
```

Un composant périphérique conserve la première valeur pour son contrôle d'accès. La bibliothèque en amont présente la dernière valeur à l'application. La périphérie autorise une identité et l'application exécute l'opération au nom d'une autre. Même si aucun des deux composants ne contient de bug d'analyse, la chaîne ne donne pas une signification unique à la requête.

Un problème plus ordinaire, moins spectaculaire et plus fréquent, survient lorsqu'une configuration de proxy ajoute un champ `Authorization` avec un identifiant de service, mais oublie de supprimer celui qui arrive du client. Le service cible choisit alors une valeur selon un comportement que personne n'a documenté. Une mise à niveau du proxy, une migration de route ou le passage de HTTP/1.1 à HTTP/2 peut modifier la valeur conservée. L'équipe parle d'une panne d'authentification intermittente parce qu'elle n'a jamais enregistré le doublon.

Les champs transmis créent un problème d'identité similaire. `X-Forwarded-User`, `X-Forwarded-Client-Cert` et les en-têtes d'identité personnalisés vont souvent d'une périphérie de confiance vers une application. La périphérie exposée au public doit supprimer les copies fournies par le client avant d'ajouter les siennes. Si elle transmet des copies non fiables, une application qui fait confiance à la mauvaise position dans la liste peut accepter une identité falsifiée.

La règle varie légèrement selon la frontière de confiance :

- À l'entrée publique, rejetez les champs d'authentification dupliqués et supprimez les en-têtes d'identité internes fournis par le client.
- Dans une passerelle de confiance, injectez l'unique identifiant ou en-tête d'identité requis en amont après avoir supprimé les données protégées fournies par l'appelant.
- Dans l'application, rejetez à nouveau les doublons. La protection à l'entrée est nécessaire, mais des changements de route peuvent contourner certaines hypothèses.
- Dans les journaux, consignez le nom de l'en-tête, le nombre d'occurrences, la route et l'identifiant de requête. Ne consignez le mécanisme d'identification que si cela ne présente aucun risque.

Ne vous fiez pas au comportement par défaut d'un proxy sans le tester. Les valeurs par défaut diffèrent selon le produit, le module, le protocole et la configuration. Un réglage qui traite les en-têtes de réponse dupliqués ne vous apprend rien sur les identifiants de requête dupliqués. Lisez la documentation de la directive ou du middleware exact, puis envoyez une requête réellement dupliquée à travers le chemin déployé.

## HTTP/2 et HTTP/3 suppriment l'ancienne syntaxe, pas l'ambiguïté

HTTP/2 et HTTP/3 n'envoient pas de lignes d'en-tête textuelles sur le réseau, mais ils transportent toujours une séquence de champs d'en-tête. Les règles du protocole interdisent les champs pseudo-en-tête dupliqués, comme `:method`, et imposent qu'ils précèdent les champs ordinaires. Ces règles favorisent la correction du protocole. Elles ne donnent pas pour autant une règle universelle de priorité à `Authorization`.

Un point de terminaison HTTP/2 peut recevoir plusieurs champs d'en-tête ordinaires. Une bibliothèque peut les exposer comme des valeurs séparées, une valeur regroupée ou une erreur selon le champ et son interface. HTTP/3 présente la même difficulté au niveau applicatif. Vous devez tester les versions du protocole acceptées par votre périphérie.

La traduction de protocole est l'endroit où les hypothèses se dégradent. Un client parle HTTP/2 à un CDN ou à un répartiteur de charge. Le CDN parle HTTP/1.1 à une passerelle. La passerelle parle HTTP/2 à un service. Chaque étape doit traduire une représentation d'en-tête. Si la première regroupe un champ et la deuxième le conserve, l'application finale ne peut pas reconstituer la requête originale. C'est une raison supplémentaire de faire rejeter l'ambiguïté par le premier destinataire de confiance, plutôt que de tenter une récupération complexe plus tard.

HTTP/2 traite aussi différemment les en-têtes propres à la connexion. Des champs comme `Connection` sont interdits parce qu'ils décrivent le comportement de connexion de HTTP/1.1. Cela n'a aucun rapport avec la priorité des identifiants. Ne recopiez pas une règle propre au protocole en supposant qu'elle sécurise un en-tête d'authentification personnalisé.

Certaines équipes tentent de résoudre le problème avec la casse minuscule, car HTTP/2 exige des noms de champs en minuscules sur le réseau. Cela ne corrige qu'un détail. Les noms HTTP/1.1 ne sont pas sensibles à la casse non plus, et une passerelle peut recevoir HTTP/1.1 avant HTTP/2. Normalisez les noms partout.

Construisez votre matrice de tests autour des chemins, pas seulement des protocoles. Testez une requête directe vers l'application dans un environnement de test, la route publique et chaque route interne utilisée par les workers ou les outils de déploiement. Pour chaque route, envoyez un `Authorization` dupliqué, des en-têtes d'identification personnalisés dupliqués et deux canaux d'identification concurrents. Le résultat attendu doit être la même erreur client explicite dans tous les cas.

## Les règles « première valeur » et « dernière valeur » créent toutes deux une surface d'attaque

« Utiliser le premier en-tête » semble prudent parce que cela ressemble à un analyseur qui lit de gauche à droite. « Utiliser le dernier » semble pratique parce qu'une configuration ultérieure devrait remplacer les valeurs par défaut. Les deux règles échouent, car l'émetteur et chaque intermédiaire peuvent influencer l'ordre différemment.

La règle de la première valeur est vulnérable lorsqu'un attaquant peut placer un identifiant avant qu'un composant de confiance n'ajoute le sien. Celle de la dernière valeur est vulnérable lorsqu'il peut ajouter un identifiant après qu'un composant de confiance a vérifié le premier. L'exploitation exacte dépend du routage et de la confiance, mais l'erreur de conception reste la même : un composant choisit un identifiant tandis qu'un autre voit une requête différente.

Le regroupement avec une virgule est encore pire lorsqu'il produit une chaîne qui semble valide. Imaginez un en-tête de clé API personnalisé que l'application découpe sur les virgules alors que la passerelle compare la chaîne complète. Ou imaginez un analyseur Bearer qui accepte le texte après le premier espace sans refuser les virgules. Vous avez créé deux langages d'analyse pour un champ contenant un secret.

Le conseil populaire consistant à « laisser l'API décider » est mauvais lorsqu'une passerelle effectue déjà une authentification, une limitation de débit, un routage par tenant ou une étiquette d'audit avant que la requête n'atteigne l'API. La passerelle a déjà pris une décision de sécurité. Elle doit utiliser la même identité non ambiguë que le service ou arrêter la requête.

Un contrat prévisible ressemble à ceci :

1. Normaliser chaque nom d'en-tête entrant.
2. Compter toutes les occurrences des champs protégés avant de choisir les identifiants.
3. Rejeter les doublons de chaque champ protégé avec une erreur client générique.
4. Rejeter les canaux d'identification incompatibles lorsque la route n'accepte qu'une seule source d'identité.
5. Supprimer les champs protégés entrants avant qu'un composant de confiance n'injecte ses propres identifiants en amont.

Faites cela avant l'analyse du jeton. Si l'analyse s'exécute d'abord, un analyseur peut consommer une valeur que le composant suivant aurait rejetée. Gardez la réponse d'erreur sobre. Indiquez que la requête contient des en-têtes d'authentification contradictoires, sans renvoyer leurs valeurs.

Il existe de rares API qui définissent volontairement plusieurs valeurs pour un champ. Si vous possédez une telle API, documentez la grammaire, l'ordre, le comportement en cas de doublon et les exigences des proxys dans le contrat d'authentification. « Le framework s'en charge » n'est pas une documentation. Si vous ne possédez pas l'API, n'inventez pas de règle de priorité autour d'elle.

## Les en-têtes personnalisés ont besoin d'un contrat d'identification, pas d'une simple convention de nommage

Les équipes considèrent souvent `Authorization` comme sensible et les en-têtes personnalisés comme de simples éléments techniques. C'est l'inverse. Un en-tête personnalisé qui sélectionne une clé API ou un tenant est un élément d'authentification, que son nom commence ou non par `X-`.

Écrivez quels canaux d'identification chaque route accepte. Une route peut accepter un jeton Bearer dans `Authorization`. Une autre peut accepter une signature de webhook dans un en-tête dédié avec un horodatage. Une route interne peut recevoir un en-tête d'identité uniquement depuis une passerelle. Ce sont des contrats distincts. Évitez un middleware général qui accepte le premier identifiant qu'il trouve.

Un contrat d'identification doit répondre aux questions suivantes :

- Ce champ peut-il apparaître plusieurs fois ?
- Peut-il apparaître avec un autre champ d'identification ?
- Quel composant de confiance peut l'ajouter ?
- Un proxy le supprime-t-il avant de le transmettre ?
- Quelle erreur l'API renvoie-t-elle en cas de conflit ?

Pour les clés API, utilisez l'un de deux modèles simples. Le premier accepte exactement un mécanisme `Authorization`. Le second accepte exactement un en-tête de clé API nommé. Ne prenez pas en charge les deux sur la même route, sauf en cas de migration nécessaire et avec une règle de conflit documentée. Pendant une migration, rejetez les requêtes qui contiennent les deux et fournissez aux clients un message indiquant clairement le remplacement accepté. Un fallback silencieux conservé indéfiniment crée un problème de diagnostic permanent.

Les webhooks signés demandent davantage de prudence. Les en-têtes de signature peuvent légitimement contenir des paramètres structurés, et un horodatage peut accompagner la signature. Cela ne rend pas les champs de signature dupliqués sûrs. Consultez la documentation de vérification du fournisseur et préservez le traitement attendu du corps brut. S'il ne définit pas les signatures répétées, rejetez-les avant la vérification. Ne les concaténez jamais en espérant que la bibliothèque de vérification fera le bon choix.

Les en-têtes d'identité internes sont les plus faciles à mal sécuriser parce qu'ils sont pratiques. Si une application accepte `X-User-Id` depuis le réseau public en supposant qu'un proxy l'a inséré, un appelant peut revendiquer n'importe quelle identité. Limitez ces en-têtes à un chemin réseau privé ou à une connexion de proxy authentifiée, supprimez-les à chaque périphérie publique et vérifiez que seule votre passerelle de confiance peut atteindre le port de l'application. La priorité des en-têtes ne peut pas réparer une frontière réseau mal conçue.

## Testez toute la route avec des conflits délibérés

Les tests unitaires d'un analyseur de jetons ne testent pas la priorité des en-têtes. Il faut un test d'intégration qui traverse les mêmes composants que ceux traversés en production. Le résultat recherché est simple et stable : toute requête ambiguë est rejetée avant toute action en amont.

Commencez par un point de terminaison sans danger que vous contrôlez. Donnez-lui un identifiant de requête et faites-lui renvoyer uniquement des observations sûres : noms d'en-têtes normalisés, nombres d'occurrences, version du protocole et composant qui a reçu la requête. Ne renvoyez pas les valeurs. Placez-le ensuite derrière la même périphérie, la même passerelle et le même routage de service que l'API cible.

Exécutez un petit ensemble de conflits :

```text
Authorization deux fois, avec la même valeur
Authorization deux fois, avec des valeurs différentes
Authorization avec X-API-Key
X-API-Key deux fois, avec la même valeur
Un en-tête d'identité interne fourni par l'appelant avec l'identité de la passerelle
```

Le cas où les valeurs sont identiques est important. Certains développeurs ne rejettent que les valeurs différentes, car ils jugent les valeurs identiques inoffensives. Cela crée une distinction exploitable entre analyseurs et laisse invisible un bug accidentel de duplication. Rejetez tout champ protégé dupliqué. Un appelant qui réessaie avec un seul champ peut toujours s'authentifier.

Vérifiez deux résultats pour chaque cas. Premièrement, le client reçoit une réponse 4xx explicite de la frontière qui possède la règle. Deuxièmement, le système en amont n'enregistre aucune action sous l'une ou l'autre identité. Une réponse 401 ou 403 ne prouve pas à elle seule que la route est sûre : le système en amont peut avoir traité une partie de la requête avant le rejet.

Répétez ensuite le test avec chaque protocole et chaque chemin pris en charge. Incluez les bibliothèques clientes utilisées par l'automatisation, et pas seulement curl. Un client en ligne de commande, un wrapper fetch de navigateur, une bibliothèque HTTP de CI et un environnement d'agent peuvent construire les collections d'en-têtes différemment. Gardez le test dans votre suite de déploiement afin qu'une mise à niveau du proxy ou du framework ne remplace pas silencieusement le rejet par une règle de sélection.

Lorsqu'un incident survient, recueillez des éléments sûrs dans l'ordre. Enregistrez la construction de la requête côté client, la décision d'accès de la périphérie, les en-têtes sortants de la passerelle sous forme de noms et de nombres, puis l'observation à l'entrée de l'application. Reliez-les avec un même identifiant de requête. Ne résolvez pas un incident d'en-têtes dupliqués en activant la journalisation complète des en-têtes en production. C'est ainsi qu'un bug d'authentification devient une fuite d'identifiants.

## Les passerelles doivent gérer l'injection des identifiants sortants

Une passerelle d'action doit éloigner l'agent des identifiants bruts et confier la requête sortante finale à un seul composant. Transmettre un jeton Bearer à l'agent et lui demander d'assembler les en-têtes lui donne à la fois l'autorité et trop de possibilités de créer une requête mal formée. Les journaux d'audit deviennent aussi plus difficiles à interpréter lorsque les valeurs par défaut et les en-têtes personnalisés se contredisent.

Sallyport exécute les appels HTTP avec des identifiants injectés depuis son coffre chiffré, au lieu d'exposer le secret à l'agent. Cette frontière n'est utile que si le générateur de requêtes sortantes traite les en-têtes d'identification comme des champs protégés, et non comme de simples suggestions que les en-têtes fournis par l'agent pourraient remplacer.

Pour un en-tête sortant protégé, la passerelle doit sélectionner la configuration d'identification enregistrée, supprimer toute occurrence de ce champ fournie par l'appelant sans tenir compte de la casse, puis ajouter exactement une valeur finale. Elle doit appliquer la même règle aux en-têtes d'identification personnalisés. Si la requête cible a besoin d'un en-tête contrôlé par l'agent portant le même nom, la configuration est incorrecte ou l'API cible a besoin d'une route distincte. Ne créez pas d'exception par requête qui modifie silencieusement l'identité.

Il y a une distinction importante. Supprimer un en-tête `Authorization` fourni par l'agent avant d'ajouter celui qui est configuré est approprié à la frontière sortante de confiance. Accepter deux en-têtes en espérant que la cible les départagera ne l'est pas. La première action établit une source unique d'identifiants. La seconde exporte l'ambiguïté.

Une passerelle doit aussi se protéger contre les canaux concurrents. Supposons qu'une connexion enregistrée injecte `Authorization: Bearer ...` tandis que la requête de l'agent contient `X-API-Key`. La cible peut accepter l'un ou l'autre. Le choix par défaut le plus sûr consiste à rejeter la requête pour conflit d'identifiants, sauf si la définition de la connexion autorise explicitement cette combinaison et en explique la raison. Une liste générique d'en-têtes autorisés ne peut pas répondre à cette question, car son sens dépend de l'API cible.

Les journaux d'audit doivent indiquer à l'opérateur que la passerelle a utilisé une connexion ou un identifiant nommé, quel hôte a reçu la requête, la méthode, le chemin et si une approbation humaine a eu lieu. Ils ne doivent pas conserver la valeur Authorization ni l'en-tête secret personnalisé. Le journal Activity de Sallyport est conçu autour d'appels individuels, mais un journal ne répare pas après coup une requête ambiguë. Le générateur de requêtes doit supprimer l'ambiguïté avant son départ de la machine.

## Les journaux révèlent les erreurs de priorité sans divulguer les jetons

Les bugs d'en-têtes dupliqués persistent parce que les équipes journalisent soit trop peu d'informations pour voir le changement de route, soit trop d'informations et créent un second incident. Vous pouvez enregistrer suffisamment de données pour diagnostiquer le problème sans conserver les identifiants.

Pour chaque conflit rejeté, consignez une liste normalisée des noms de champs protégés et leur nombre d'occurrences. Ajoutez le nom de la route, le protocole, le composant destinataire, l'identifiant de requête et un code de motif comme `duplicate_authorization` ou `conflicting_credential_channels`. Si vos procédures l'autorisent, enregistrez un identifiant de configuration d'identifiant qui ne permet pas de récupérer le secret.

Ne journalisez jamais les jetons Bearer bruts, les clés API, les valeurs d'authentification Basic, les charges utiles de webhooks signés, les cookies ou les lignes Authorization complètes. Une suppression après formatage de la chaîne n'est pas fiable. Une bibliothèque peut lancer une exception contenant la requête originale, ou un journal de débogage peut s'exécuter avant votre filtre. Construisez les enregistrements à partir de champs sûrs au lieu de prendre une capture de la requête et d'essayer de la nettoyer ensuite.

Hacher un jeton n'est pas automatiquement sûr. Un hachage stable peut permettre à toute personne ayant accès aux journaux de relier l'utilisation d'un même identifiant et peut être deviné lorsque le secret a peu d'entropie. Utilisez un identifiant non secret provenant de votre coffre ou de votre configuration si vous avez besoin d'une corrélation. Sinon, indiquez qu'un canal d'identification sans nom était présent et corrigez le modèle de configuration.

Traitez l'absence d'éléments de preuve comme un échec de déploiement. Si une périphérie rejette un doublon mais que la piste d'audit ne permet pas de voir quelle périphérie a pris la décision, les personnes chargées de la réponse perdront du temps à comparer des journaux applicatifs qui n'ont jamais vu la requête. À l'inverse, si l'application la rejette mais que la périphérie l'a laissée passer, vous avez trouvé un endroit où renforcer l'application de la règle.

La première correction pratique est limitée : énumérez les en-têtes porteurs d'identifiants sur une route publique, rejetez les répétitions et les conflits à l'entrée, puis prouvez par un test d'intégration qu'aucun appel en amont n'a lieu. Appliquez ensuite le même contrat à chaque chemin de proxy et à chaque client sortant. L'ordre des en-têtes ne doit jamais décider de l'identité que l'API attribue à l'appelant.
