Aller au contenu principal

ADR-028 : Validation de Liaison de Certificat RFC 8705

Statut​

Accepté

Date​

2026-02-01

Contexte​

STOA supporte mTLS pour l'authentification des clients API en utilisant les RFC 8705 Certificate-Bound Access Tokens. Les tokens JWT contiennent une claim cnf.x5t#S256 avec l'empreinte SHA-256 du certificat client. Le MCP Gateway doit valider que le certificat présenté par le client (via l'en-tête du proxy terminant TLS) correspond à l'empreinte liée au JWT.

Le défi : différents systèmes dans la chaîne utilisent différents formats d'empreinte.

SystèmeFormatExemple
JWT RFC 8705 (cnf.x5t#S256)base64urlhLmVMvjnmCm_I4d8_3nw5A
F5 / Nginx (par défaut)hex minuscule84b99532f8e79829bf23877cff79f0e4
Sortie CLI OpenSSLhex avec deux-points84:B9:95:32:F8:E7:98:29:BF:23:87:7C:FF:79:F0:E4

De plus, le nom de l'en-tête injecté par le proxy terminant TLS varie selon le déploiement (X-SSL-Client-Cert-SHA256, X-Client-Cert-Fingerprint, SSL_CLIENT_FINGERPRINT, etc.).

Décisions Associées​

  • ADR-027 : Authentification X509 par En-têtes HTTP — contrat d'en-têtes entre F5 et Keycloak
  • ADR-011 : Modes de Sécurité API — mTLS pour les APIs internes CORE
  • CAB-868 : Métriques de Liaison de Certificat
  • CAB-1024 : Politique de Liaison de Certificat Pilotée par UAC

Décision​

1. Normalisation en hex minuscule pour toutes les comparaisons​

Les trois formats d'empreinte sont normalisés en hex minuscule (sans séparateurs) avant comparaison. Cela évite les problèmes de sensibilité à la casse et l'ambiguïté de format.

base64url  →  décoder  →  hex minuscule
hex majuscule → minuscule → hex minuscule
hex:deux-points → supprimer → hex minuscule

2. Comparaison sécurisée en temps constant​

Toutes les comparaisons d'empreintes utilisent secrets.compare_digest() pour prévenir les attaques par canal auxiliaire basées sur le timing. Cela s'applique au middleware MCP Gateway et au module partagé fingerprint_utils.

3. Détection automatique du format lorsqu'il n'est pas spécifié​

detect_format(fingerprint) inspecte le motif de la chaîne :

  • Contient : → hex_colons
  • Correspond à ^[a-fA-F0-9]+$ → hex
  • Sinon → base64url (avec validation du jeu de caractères : ^[A-Za-z0-9\-_]+$)

4. Configuration pilotée par UAC​

Tous les paramètres de liaison de certificat sont configurables par tenant via le schéma UAC (Universal API Contract) :

Chemin UACTypeDéfautDescription
security.authentication.mtls.cert_binding.enabledbooleantrueActiver la validation de liaison de certificat
security.authentication.mtls.cert_binding.header_namestringX-SSL-Client-Cert-SHA256En-tête du proxy TLS
security.authentication.mtls.cert_binding.fingerprint_formatenumhexFormat : base64url, hex, hex_colons
security.authentication.mtls.cert_binding.jwt_claimstringcnf.x5t#S256Chemin de claim JWT
security.authentication.mtls.cert_binding.strict_modebooleantrueRejeter si cnf présent mais en-tête absent

5. Utilitaires centralisés​

Toute la logique de conversion de format réside dans control-plane-api/src/services/fingerprint_utils.py :

  • Énumération FingerprintFormat
  • detect_format(), normalize_to_hex(), hex_to_base64url()
  • fingerprints_match() — comparaison cross-format sécurisée en temps constant

Le MCP Gateway duplique la normalisation inline (ne peut pas importer depuis control-plane-api), mais suit le même algorithme.

6. Génération de politique webMethods​

La configuration UAC cert_binding génère une action de politique requestProcessing webMethods via mappers.py, en passant le nom d'en-tête, le format, la claim JWT et le mode strict comme paramètres de mapping d'entrée.

Conséquences​

Positives​

  • Fonctionne avec n'importe quelle configuration F5/LB — le nom d'en-tête et le format sont configurables, pas codés en dur
  • Aucun changement de code par déploiement — le schéma UAC pilote toute la configuration
  • Sécurisé contre les attaques de timing — secrets.compare_digest partout
  • Correspondance cross-format — la même empreinte en hex, base64url ou avec deux-points correspond correctement
  • Feature flag — cert_binding_enabled permet un déploiement progressif

Négatives​

  • Trois conversions de format — doit gérer correctement base64url, hex et hex_colons
  • Complexité du schéma UAC — ajoute un objet cert_binding imbriqué à security.authentication.mtls
  • Normalisation dupliquée — MCP Gateway et control-plane-api ont chacun leur propre implémentation (runtimes différents)

Risques​

  • Ambiguïté base64url — une chaîne hex comme abcdef1234 pourrait être détectée à tort comme hex alors qu'elle est en base64url. Atténuée par des indications explicites de format dans la configuration UAC.
  • Usurpation d'en-tête — si l'en-tête proxy n'est pas supprimé des requêtes externes, un attaquant pourrait injecter une fausse empreinte. Atténuée par la configuration F5/Nginx (proxy de confiance uniquement).