Résumé

  • La révision 07 lie la clé cnf.jwk d’un Workload Identity Token à la méthode, au chemin, à la requête, à l’audience, aux en-têtes retenus, au condensat du contenu et aux paramètres de signature. Elle ne décide pas si l’opération est permise.
  • Une absence de nonce ne vaut que pour la mémoire consultée. Une réponse n’est protégée contre la suppression de sa signature que si le client l’a exigée dans sa propre requête signée. Il faut conserver séparément identité, signature, rejeu, autorisation, validation applicative et résultat.

Le même nonce, deux mémoires

Une requête arrive sur le premier nœud d’un service. Le WIT est valable, sa clé de confirmation correspond à la signature, le corps produit le bon Content-Digest et l’audience vise le destinataire prévu. Le nœud accepte puis inscrit le nonce dans son cache local.

La requête identique atteint ensuite un deuxième nœud avant l’expiration. La cryptographie n’a pas changé. Le deuxième cache, lui, est vide. Il peut donc répondre « signature valide » et « nonce inconnu » sans contredire le premier. Si l’application transforme ces deux réponses en droit d’exécuter, elle a confondu trois décisions : authenticité, nouveauté et autorisation.

draft-ietf-wimse-http-signature-07, déposé le 20 septembre 2026, expose directement cette limite. Son en-tête vise la filière Standards Track et fixe une expiration au 24 mars 2027. Il s’agit d’un Internet-Draft actif d’un groupe de travail. Il ne s’agit ni d’un RFC, ni d’une obligation déployée, ni d’une mesure d’adoption. L’annexe d’implémentation signale du code en cours, pas un recensement de production.

La représentation protégée

Le profil s’appuie sur RFC 9421. Toute requête couvre @method, @path et @query. Lorsque les champs existent, elle couvre aussi Content-Type, Content-Digest, Authorization, Txn-Token et Workload-Identity-Token. Un message avec corps doit posséder un Content-Digest couvert, puis le récepteur doit recalculer ce condensat sur les octets effectivement reçus.

La nuance est opérationnelle. Signer le texte d’un condensat sans vérifier le contenu ne rattacherait pas la preuve au corps. RFC 9530 donne sa sémantique au champ ; WIMSE exige la comparaison. Le reçu utile doit donc noter la base de signature reconstruite, les composants couverts et le résultat du nouveau calcul.

Les paramètres comprennent created, un expires court, un nonce aléatoire et l’étiquette wimse-workload-to-workload. La requête ajoute wimse-aud. Les paramètres ordinaires keyid et alg de la signature HTTP ne sont pas employés : clé et algorithme viennent du cnf.jwk du WIT. La politique locale conserve le dernier mot sur l’algorithme acceptable.

Deux signatures portant l’étiquette WIMSE ne forment pas une réserve de secours. Le récepteur doit rejeter l’ambiguïté. Sinon, chaque intermédiaire pourrait choisir la représentation qui l’arrange et prétendre que « la signature » a été validée.

L’audience remplace une autorité fragile

Le composant @authority n’est pas obligatoire. Les répartiteurs et mandataires qui terminent TLS peuvent le réécrire. Le rendre intangible casserait précisément les chemins que le profil veut traverser. WIMSE signe donc wimse-aud, qui désigne le destinataire logique de la charge de travail.

Cela oblige l’opérateur à documenter la construction de l’audience. Un nom d’hôte vérifié pendant TLS, une autorité HTTP vue par le proxy et une audience WIMSE ne sont pas le même fait. RFC 9525 aide à vérifier l’identité du service présenté sur le canal. La signature WIMSE protège une représentation HTTP et une intention de destinataire. Une passerelle peut réussir le premier contrôle et appliquer une comparaison d’audience trop large ; l’inverse est également possible.

Les reçus doivent survivre à cette séparation : identité TLS attendue et présentée, terminal du canal, audience demandée et reconnue, principal de signature, puis service réellement appelé. Un seul voyant vert efface le lieu où l’erreur a été introduite.

Posséder la clé n’accorde pas l’opération

Le récepteur valide d’abord le WIT, puis la signature avec la clé liée. Le résultat soutient une affirmation limitée : un détenteur de la clé privée correspondante a signé la représentation couverte pendant la fenêtre acceptée.

Il ne dit pas pourquoi la requête a été produite. Il ne garantit pas que cette clé n’existe que dans une seule instance. Il ne transforme pas l’identité de service en rôle métier. Surtout, il n’autorise pas l’action.

La révision 07 place explicitement tout le sous-système d’autorisation hors de son périmètre et le suppose fiable. La limite doit être concrète. L’authentification livre un principal et une requête. Le composant capable de produire l’effet doit encore résoudre l’action, la ressource, le contexte et la version de politique avant de répondre oui ou non.

Un journal d’autorisation doit conserver la règle appliquée, les obligations, l’exception éventuelle et l’instant de décision. Si une passerelle donne automatiquement un rôle étendu à tout WIT provenant d’un domaine de confiance, ce rôle vient de la configuration de la passerelle. La signature ne l’a jamais contenu.

Le rejeu dépend de la topologie

created et expires bornent une fenêtre ; ils n’empêchent pas une seconde présentation à l’intérieur de cette fenêtre. Le nonce permet une détection, mais seulement si un état se souvient de sa première apparition. Le projet autorise un cache et recommande de refuser une valeur déjà observée. Il n’impose pas que plusieurs validateurs partagent leurs caches et ne fait pas de la protection contre le rejeu un objectif absolu, précisément à cause du coût de synchronisation.

Une absence dans le cache signifie donc : « ce validateur ne conserve pas cette valeur dans ce périmètre, à cet instant ». Elle ne signifie pas qu’aucune région ne l’a acceptée, qu’un enregistrement plus ancien n’a pas expiré ou que l’application n’a pas déjà traité une opération équivalente.

Le choix local peut être raisonnable pour une lecture idempotente. Il devient plus risqué pour un débit, une émission de certificat ou une suppression. Une seconde barrière applicative—clé d’idempotence, verrou de transaction ou preuve de commit—peut alors être indispensable. Le contrôle ne doit pas être présenté comme « anti-rejeu activé » sans l’identité du validateur, l’étendue du cache, sa durée et la politique de bascule.

La réponse signée est un contrat demandé

Un serveur peut signer ses réponses, mais la garantie forte commence chez le client. Celui-ci place wimse-sign-response=true dans les paramètres signés de la requête. Le serveur ne peut alors substituer une réussite non signée s’il ne sait pas signer, et le client doit rejeter une réponse non signée.

Toute réponse signée porte wimse-req-nonce, égal au nonce de la requête. Le client vérifie ainsi non seulement un signataire, mais l’attachement de la réponse couverte à cette sollicitation.

Si le client n’a rien exigé, une politique interne du serveur ne suffit pas. Un intermédiaire peut retirer la signature ; le client doit accepter la réponse ordinaire. La résistance à la suppression n’existe donc que sur la branche où la demande était elle-même signée. « Le serveur signe habituellement » décrit une capacité. « Ce client a exigé puis vérifié une signature liée à son nonce » décrit une transaction.

Même cette dernière preuve ne garantit ni fin d’une tâche asynchrone, ni commit en aval, ni résultat métier. Elle authentifie les composants couverts de la réponse.

Les transformations doivent avoir un propriétaire

Les proxys terminent TLS, normalisent des champs, routent et parfois re-signent. Un champ couvert ne peut être modifié sans casser la signature ; un champ omis peut l’être. Une nouvelle signature de proxy crée un nouveau principal et une nouvelle représentation. Elle n’étend pas rétrospectivement la couverture du premier auteur.

Le danger apparaît lorsque l’application détermine l’effet avec un champ laissé hors signature. Une passerelle peut autoriser un POST sur un chemin tandis qu’un en-tête non couvert choisit le compte réellement modifié. Le bon emplacement de l’autorisation est le premier point qui connaît l’opération résolue et peut encore l’empêcher.

Une trace robuste associe contrôle entrant, politique de transformation, identité de re-signature, différence de composants et décision finale. Il ne s’agit pas de geler chaque octet, mais de rendre explicite qui peut changer les octets qui déterminent l’effet.

Six reçus, pas un statut

Une transaction exploitable après incident conserve : le WIT et son empreinte de clé ; la base de signature et le digest recalculé ; le nonce avec le validateur et le périmètre mémoire ; le principal, l’action, la ressource et la règle d’autorisation ; l’identifiant d’idempotence et le commit applicatif ; enfin l’observation indépendante du résultat.

Ces reçus peuvent diverger. Une identité valable peut porter une mauvaise signature. Une signature valable peut être rejouée. Une requête neuve peut être interdite. Une action permise peut échouer. Un commit peut être compensé plus tard. Conserver les divergences n’est pas un défaut de cohérence : c’est la condition de l’imputabilité.

L’annexe du projet mentionne des implémentations exploratoires. Pour évaluer un système réel, il faut demander une capture, la base reconstruite, la validation du WIT, la topologie des caches, le journal d’autorisation et la preuve de commit. Une matrice de conformité ne remplace aucun de ces éléments. L’adoption devient réelle lorsque du code déployé produit et vérifie ces preuves.

Sources