veilletech.fr
21 août Feed du jour
#03 OAUTH Faille

OAuth : refuser une permission sans tout bloquer

Un agent qui demande tout obtient surtout un refus.

Cloudflare remplace le consentement OAuth « tout ou rien » par un modèle où les développeurs distinguent portées obligatoires et optionnelles, ces dernières pouvant être refusées sans bloquer l'autorisation. L'annonce cite explicitement les serveurs MCP, qui demandent large parce qu'un agent pourrait tout utiliser.

3 min de lecturevidéo 1:21
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. Le problème résolu
  3. Comment ça marche
  4. Ce que ça change pour votre code
  5. À retenir

Ce qui se passe

Cloudflare introduit la personnalisation des portées OAuth. Le propriétaire d'un client peut désormais marquer certaines portées comme optionnelles, et l'utilisateur peut les décocher au moment d'autoriser l'application.

Le contexte donne la mesure du sujet : depuis juin, les développeurs ont créé des milliers d'applications OAuth tierces sur Cloudflare, pour plus d'un million d'autorisations.

Le problème résolu

Cloudflare permettait déjà à un client de demander un sous-ensemble de ses portées configurées. Mais une fois cette demande formulée, l'utilisateur ne pouvait plus la restreindre.

L'expérience restait donc binaire de son point de vue. Selon l'annonce, si une application demandait plus d'accès que ce que l'utilisateur était prêt à accorder, ses seules options étaient d'approuver la demande entière ou de refuser tout net.

Le cas des serveurs MCP est cité explicitement : un serveur MCP demande large, parce qu'en théorie un agent pourrait tout utiliser. La plupart des utilisateurs ne veulent pas accorder autant. Avant cette fonctionnalité, la seule parade consistait pour l'éditeur à construire son propre écran de sélection de portées avant d'envoyer l'utilisateur vers le flux de consentement.

Comment ça marche

Le mécanisme s'appuie sur une souplesse déjà présente dans la spécification OAuth : un serveur d'autorisation a toujours le droit d'accorder un jeu de portées plus étroit que celui demandé.

À la configuration du client, un champ optional_scopes vient s'ajouter à scopes :

JSON
"scopes": [
  "user-details.read",
  "workers-scripts.write",
  "workers-kv-storage.write",
  "zone.read"
],
"optional_scopes": [
  "workers-kv-storage.write",
  "zone.read"
]

Le détail qui fait la valeur du dispositif : obligatoires et optionnelles ne sont évaluées que sur les portées demandées dans ce flux précis, pas sur tout ce que le client a configuré.

Dans l'exemple ci-dessus, un flux qui demande les quatre portées laisse l'utilisateur décider pour workers-kv-storage.write et zone.read. Mais si le même client ne demande plus tard que workers-scripts.write et zone.read, seules ces deux-là sont considérées : les autres ne sont ni affichées ni appliquées.

L'écran de consentement parle donc de la tâche du moment, pas du catalogue complet des capacités du produit. Et les clients existants gardent leur comportement : sans portées optionnelles déclarées, rien ne change.

Ce que ça change pour votre code

Un point d'implémentation à ne pas manquer. Quand un utilisateur décoche une portée optionnelle, le jeton d'accès généré ne contient que ce qu'il a consenti.

Autrement dit : après l'échange du code d'autorisation, il faut vérifier le jeu de portées réellement accordé au lieu de supposer que la demande a été approuvée en totalité. Une application qui plante sur une permission absente est une application qu'on n'autorisera pas.

La limite du dispositif est là aussi : il ne vaut que pour les éditeurs qui jouent le jeu. Une application qui déclare tout obligatoire retrouve exactement le comportement d'avant.