Cloud

Azure APIM : diagnostiquer les échecs mTLS avant de changer les policies

Un runbook de production pour qualifier des échecs mTLS Azure API Management avec chaîne de certificat client, hostname, policy, logs gateway, identité backend, validation et rollback avant de modifier les policies API.

20 juil. 2026 azureapi-managementapimmtlscertificat-clientsecurityidentityobservabilitykqlrunbookrollbackproduction

Un échec mTLS sur Azure API Management peut ressembler à une erreur de policy, un bug consumer, un certificat expiré, un problème gateway ou un refus backend. Sous pression, le réflexe courant consiste à assouplir une policy, contourner la validation de certificat pour un consumer, ou redéployer l’API. C’est exactement comme cela qu’une frontière de sécurité contrôlée devient une exception silencieuse.

Le cas d’usage est une API interne ou partenaire exposée via APIM. Les consumers présentent un certificat client, APIM valide les attributs ou le thumbprint en policy, puis transmet au backend qui peut exiger sa propre identité, son token ou son chemin réseau. L’objectif du runbook est de décider s’il faut corriger le certificat consumer, mettre à jour le matériau de confiance, corriger la policy APIM, suspendre le changement, ou rollbacker sans affaiblir toute l’API.

Figer le contrat mTLS

Commencez par écrire le contrat que la production doit faire respecter. mTLS n’est pas seulement un fichier certificat. Le contrat inclut hostname, handshake TLS, chaîne de certification, contrôles APIM, ownership consumer et authentification backend.

yaml apim-mtls-contract.yml
api:
hostname: api.partner.example.com
apim_service: apim-prod-core
api_id: orders-api
operation: POST /orders
product: partner-standard

consumer:
name: partner-orders-worker
certificate_subject: CN=partner-orders-prod
issuer: CN=partner-ca-prod
expected_thumbprint: 0123456789ABCDEF0123456789ABCDEF01234567
rotation_window: 2026-07-20T08:00:00Z/2026-07-20T10:00:00Z

decision_needed:
- accept_new_certificate
- restore_previous_certificate
- fix_consumer_chain
- correct_apim_policy
- block_until_evidence_exists

Si l’équipe ne sait pas nommer le subject attendu, l’issuer, le thumbprint ou le propriétaire, n’assouplissez pas la policy. Reconstruisez d’abord le contrat.

Séparer handshake, policy APIM et refus backend

Un incident mTLS peut échouer avant l’exécution de la policy APIM, dans la policy APIM, ou après transmission au backend. Ce ne sont pas les mêmes corrections.

text mtls-layered-reading.txt
Echec handshake TLS
Le certificat client est absent, expire, non approuve, envoye au mauvais hostname, ou rejete avant qu'APIM journalise l'appel API

Refus policy APIM
APIM recoit la requete mais la policy refuse subject, issuer, thumbprint, header, produit, subscription ou claim

Refus backend
APIM accepte le certificat client, puis le backend refuse l'identite APIM, le token, le chemin source ou l'autorisation applicative

Refus gateway ou WAF
Une couche frontale bloque avant APIM, souvent sans log APIM pour la meme correlation

Mauvais chemin de test
Un endpoint de sante reussit mais l'operation protegee echoue car elle n'utilise pas la meme branche de policy

Cette distinction évite un raccourci dangereux : modifier la policy APIM alors que le client n’a jamais terminé TLS, ou remplacer un certificat client alors que l’identité backend est en panne.

Capturer la preuve certificat

Demandez au consumer ou au runner de diagnostic d’afficher le certificat réellement présenté. La preuve doit inclure validité, subject, issuer, thumbprint et chaîne complète. Un certificat présent dans Key Vault ou sur un hôte ne prouve pas qu’il est envoyé sur le fil.

bash 01-client-certificate-evidence.sh
CERT_PATH="./partner-orders-prod.crt"

openssl x509 -in "$CERT_PATH" -noout -subject -issuer -serial -fingerprint -sha1 -dates

openssl verify -show_chain -CAfile ./partner-ca-chain.pem "$CERT_PATH"

Bloquez le changement si la chaîne ne peut pas être reproduite, si le certificat n’est pas encore valide, si le subject ne correspond plus au contrat de policy, ou si le thumbprint vu dans la requête diffère du certificat approuvé pour la production.

Prouver ce qu’APIM voit

Vérifiez ensuite les diagnostics APIM dans la même fenêtre que les appels en erreur. L’objectif est de savoir si APIM a reçu la requête, quelle API et quelle opération ont été sélectionnées, et quel statut ou message de policy a été produit.

kusto 02-apim-mtls-failures.kql
let Window = 2h;
let ApiPath = "/orders";
AzureDiagnostics
| where TimeGenerated > ago(Window)
| where ResourceProvider == "MICROSOFT.APIMANAGEMENT"
| where tostring(Url) has ApiPath or tostring(RequestUri) has ApiPath
| project TimeGenerated,
        ServiceName=tostring(Resource),
        ApiId=tostring(ApiId),
        OperationId=tostring(OperationId),
        ProductId=tostring(ProductId),
        SubscriptionId=tostring(SubscriptionId),
        CallerIp=tostring(CallerIPAddress),
        Status=toint(ResponseCode),
        Error=tostring(ErrorMessage),
        CorrelationId=tostring(CorrelationId),
        Url=tostring(Url)
| where Status in (400, 401, 403, 495, 496, 500)
| order by TimeGenerated desc

Si APIM ne contient aucun log pour la requête en échec, regardez hostname, gateway, WAF, handshake TLS, DNS et chemin client. Si APIM journalise un refus policy, inspectez les conditions. Si APIM retourne un succès alors que le consumer voit un refus, vérifiez la couche frontale ou le backend.

Inspecter la policy sans l’élargir

Les policies de certificat client dérivent facilement : une liste de thumbprints grossit, un contrôle issuer disparaît pendant une urgence, ou une comparaison de subject devient trop large. Relisez la policy comme une décision d’autorisation, pas comme du XML décoratif.

bash 03-apim-policy-export.sh
RG="rg-shared-api-prod"
APIM="apim-prod-core"
API_ID="orders-api"

az apim api policy show --resource-group "$RG" --service-name "$APIM" --api-id "$API_ID" --query "value" --output tsv > apim-api-policy.xml

grep -nE "certificate|thumbprint|Subject|Issuer|validate-client-certificate|choose|return-response" apim-api-policy.xml

La revue saine tient en quatre questions : quel attribut de certificat est trusted, quels consumers partagent cette règle, que se passe-t-il en cas de mismatch, et comment le rollback restaure le matériau accepté auparavant.

Rejouer la vraie opération

Utilisez une requête contrôlée via le vrai hostname, avec le certificat candidat et un identifiant de corrélation. Évitez les tests qui contournent APIM ou utilisent une route de santé non protégée.

bash 04-apim-mtls-controlled-replay.sh
HOST="api.partner.example.com"
PATH_TO_TEST="/orders"
CORRELATION_ID="mtls-$(date +%Y%m%d%H%M%S)"

curl -sS -D - "https://${HOST}${PATH_TO_TEST}" --cert ./partner-orders-prod.crt --key ./partner-orders-prod.key -H "x-correlation-id: ${CORRELATION_ID}" -H "content-type: application/json" -d '{"probe":"mtls-validation"}' -o /tmp/apim-mtls-response.json

echo "correlation_id=${CORRELATION_ID}"
cat /tmp/apim-mtls-response.json

Retrouvez ensuite la même corrélation dans les logs APIM et les logs backend. La validation est complète seulement si la même requête prouve le certificat, la branche de policy, l’opération API et le résultat backend.

Décider correction, attente ou rollback

La décision doit rester étroite et réversible. Ne remplacez pas le modèle de sécurité pendant l’incident.

text apim-mtls-decision.txt
Accepter le nouveau certificat
Chaine, subject, issuer et thumbprint correspondent au contrat approuve
La policy APIM accepte le certificat candidat sur la vraie operation
Le backend accepte la requete transmise
Le certificat precedent reste disponible pendant la fenetre d'observation

Corriger le consumer
Mauvais certificat presente
Chaine intermediaire absente
Certificat pas encore valide ou deja expire
Application encore connectee a une ancienne version de secret

Corriger la policy APIM
La policy ne fait confiance qu'a un ancien thumbprint
La regle issuer ou subject ne correspond plus au contrat documente
La branche de policy differe entre operation et route de sante
Les diagnostics prouvent le refus APIM

Suspendre le changement
Le certificat reellement presente est inconnu
Les logs ne distinguent pas handshake, policy APIM et backend
Plusieurs consumers partagent la meme exception
Le rollback imposerait de desactiver globalement la validation certificat

Rollbacker
Restaurer l'ancien thumbprint ou set de certificats trusted
Rebrancher le consumer sur l'ancienne version de secret
Garder la preuve du certificat en echec pour le follow-up
Supprimer les matches larges temporaires apres validation

Si le rollback est nécessaire, validez que l’ancien certificat fonctionne encore sur l’opération protégée. Un rollback qui restaure seulement un fichier ou une valeur de policy ne suffit pas.

Laisser un handover exploitable

Les incidents mTLS reviennent quand l’ownership est flou. Le handover doit dire quel certificat est accepté, qui possède la prochaine rotation, quels logs prouvent le succès et quelle exception temporaire doit disparaître.

yaml apim-mtls-handover.yml
apim_mtls_handover:
api: orders-api
consumer: partner-orders-worker
accepted_certificate:
  subject: CN=partner-orders-prod
  issuer: CN=partner-ca-prod
  thumbprint: 0123456789ABCDEF0123456789ABCDEF01234567
  valid_until: 2026-10-20
evidence:
  - controlled_replay_correlation_id
  - apim_log_policy_accept
  - backend_log_success
  - previous_certificate_status_checked
rollback:
  previous_secret_version: kv://kv-prod/partner/orders-client-cert/previous
  previous_thumbprint_kept_until: 2026-07-21T10:00:00Z
follow_up:
  - monitor 401 and 403 by API and consumer
  - remove emergency thumbprint matches
  - document next rotation owner and date

Conclusion

Un échec mTLS APIM est un incident de sécurité en production, mais la réponse la plus sûre n’est pas d’affaiblir la policy en premier. Le chemin utile consiste à prouver le certificat présenté par le consumer, prouver ce qu’APIM a vu, inspecter la branche de policy, rejouer la vraie opération et décider avec un rollback disponible.

Quand cette preuve existe, l’équipe peut accepter un nouveau certificat, corriger le consumer, ajuster APIM ou rollbacker sans transformer mTLS en exception large que personne ne pensera à retirer.