Be Software Architecture Wise
Be Wise Apps

Read in English · Leer en español · Auf Deutsch lesen

Section 8.3 sur 8.8 · Avancé · 26 min de lecture

Identité et accès : authentification, autorisation, OAuth 2.0 et OpenID Connect

Leçon vidéo

5 min · narré en anglais, avec sous-titres
Écouter seulement (audio)
Lire la transcription

Chaque requête soulève deux questions : qui appelle, et que peut-il faire ? Cette leçon montre comment les architectes répondent aux deux, pour les personnes comme pour les services.

Pensez à un grand immeuble de bureaux. À l’accueil, vous montrez une pièce d’identité avec photo et vous recevez un badge. C’est l’authentification : prouver qui vous êtes. Le badge ouvre ensuite certaines portes et pas d’autres. C’est l’autorisation : décider de ce que vous avez le droit de faire. Un coursier qui récupère un colis pour vous reçoit un laissez-passer limité au local du courrier, et seulement pour aujourd’hui. OAuth fonctionne ainsi, pour les applications. Et les machines de l’immeuble ont elles aussi besoin de badges, pour pouvoir se prouver les unes aux autres qu’elles sont authentiques.

L’authentification gagne à être centralisée dans un seul fournisseur d’identité auquel toutes les applications font confiance, pour que les règles de mot de passe, l’authentification multifacteur et la récupération de compte soient construites une seule fois. L’autorisation, elle, est distribuée. Seul le service des commandes sait à qui appartient une commande, si bien que la décision finale concernant une commande doit être prise là. La plupart des violations du contrôle d’accès viennent de la confusion entre les deux : un endpoint vérifie que le jeton est valide, puis renvoie n’importe quelle commande qu’on lui demande.

Les lignes directrices du NIST privilégient les mots de passe longs aux règles sur les chiffres et les symboles, et exigent une vérification par rapport aux mots de passe compromis. Elles interdisent d’imposer des changements à intervalles fixes. L’authentification multifacteur arrête la plupart des attaques qui utilisent des mots de passe divulgués. Mais aucun code à usage unique ne résiste à l’hameçonnage, car un faux site peut le relayer aussitôt. Une passkey, elle, résiste à l’hameçonnage. L’appareil signe un défi avec une clé privée liée au vrai site web, et le serveur ne détient que la clé publique. Et surveillez la récupération de compte. Si une passkey perdue peut être remplacée en cliquant sur un lien reçu par e-mail, tout le système n’est pas plus solide que ce compte e-mail.

Après la connexion, une session côté serveur conserve les détails sur le serveur et donne au navigateur un identifiant aléatoire dans un cookie. La révoquer prend effet immédiatement. Un jeton autonome, généralement un JSON Web Token, est signé par l’émetteur, si bien que n’importe quel service peut le vérifier sans rien consulter. Mais il ne peut pas être révoqué avant son expiration. Gardez donc ces jetons de courte durée, fixez l’algorithme de signature dans le code, et vérifiez l’émetteur, l’audience et l’expiration, pas seulement la signature. Et ne gardez pas les jetons dans le stockage du navigateur, où n’importe quel script de la page peut les lire.

OAuth 2.0 permet à une application d’agir pour un utilisateur sans connaître son mot de passe. Voici les quatre parties : le navigateur de l’utilisateur, l’app cliente, le serveur d’autorisation et le serveur de ressources qui détient les données. Les applications qui agissent pour un utilisateur doivent utiliser le flux de code d’autorisation avec Proof Key for Code Exchange, ou PKCE. D’abord, le client crée un secret aléatoire, le vérificateur, et calcule son hachage, le défi. Le client n’envoie que le défi au serveur d’autorisation. L’utilisateur se connecte, ici avec une passkey, et donne son consentement. Le navigateur est redirigé vers le client avec un code de courte durée. Le client échange ce code contre des jetons par une requête directe, en envoyant le vérificateur d’origine. Le serveur vérifie que son hachage correspond au défi. Le client reçoit un jeton d’accès et appelle l’API avec. Un attaquant qui intercepte le code ne peut pas l’échanger, car le vérificateur n’a jamais quitté le client.

Sans utilisateur impliqué, par exemple quand le système d’un partenaire appelle la plateforme, un service utilise l’octroi par identifiants client. OAuth seul n’indique pas au client qui est l’utilisateur. OpenID Connect y remédie, avec un jeton d’identité qui indique qui s’est connecté, pour quel client et quand. La règle empirique : le jeton d’identité est destiné au client, pour savoir qui s’est connecté. Le jeton d’accès est destiné à l’API, pour autoriser les appels. Et entre services, l’identité de charge de travail remplace les clés partagées de longue durée par des identités de courte durée émises par la plateforme.

Les restaurants vont du café unique aux grandes chaînes. Avec les seuls rôles, chaque vérification doit savoir de quel établissement il s’agit, et on finit avec des milliers de rôles. Le contrôle d’accès basé sur les relations stocke plutôt des relations : un gérant gère un établissement, un établissement appartient à un restaurant, une commande appartient à un établissement. Les règles suivent les relations. Le gérant d’un établissement peut modifier la carte de cet établissement, et le propriétaire du restaurant aussi. Un livreur ne peut voir l’adresse de retrait que tant que la livraison lui est affectée. Une fois la livraison terminée, le lien est supprimé, et l’accès avec. Et un plafond de remboursement de vingt livres dépend d’un attribut de la requête : il s’écrit donc sous forme de politique basée sur les attributs. Les systèmes réels combinent ainsi les modèles. Côté application des règles, l’API gateway rejette les requêtes sans jeton ou sans portée valide. Chaque service pose ensuite à un moteur de politiques la question au niveau de l’objet. C’est ce contrôle fin que les équipes oublient.

La section complète contient un guide pour choisir les flux OAuth et une comparaison des modèles d’autorisation. Ensuite, dans la section huit point quatre, nous verrons comment protéger les données. À très vite.

Ce qu’il faut savoir

Authentification et autorisation

Chaque requête adressée à la plateforme de livraison de repas soulève deux questions distinctes. L’authentification demande qui est-ce ? et y répond par des preuves : un mot de passe, une passkey, un certificat, un jeton signé. L’autorisation demande l’appelant peut-il faire ceci, sur cet objet, maintenant ? et y répond par une politique : ce client peut lire cette commande parce qu’il l’a passée ; ce livreur peut voir cette adresse de retrait parce que la livraison lui est affectée. HTTP les distingue lui aussi : 401 Unauthorized signifie que la requête ne comporte pas d’authentification valide, tandis que 403 Forbidden signifie que l’appelant est connu mais n’a pas le droit d’agir.

Cette distinction compte sur le plan architectural, car les deux problèmes se résolvent à des endroits différents. L’authentification gagne à être centralisée dans un seul fournisseur d’identité (IdP) auquel toutes les applications font confiance, de sorte que les règles de mot de passe, l’authentification multifacteur, la récupération de compte et le verrouillage soient mis en œuvre une seule fois. L’autorisation est par nature distribuée : seul le service des commandes sait à qui appartient une commande, si bien que la décision finale concernant une commande doit être prise là, même si des vérifications grossières ont lieu plus tôt, au niveau de l’API gateway (passerelle d’API). La plupart des violations du contrôle d’accès recensées dans l’OWASP Top 10 viennent de la confusion entre les deux : un endpoint qui vérifie que le jeton est valide, puis renvoie n’importe quel objet dont on lui donne l’identifiant.

Mots de passe, authentification multifacteur et passkeys

Les mots de passe restent l’authentificateur le plus courant, et les Digital Identity Guidelines du NIST sont les règles les plus largement suivies en la matière. La révision 4 de la SP 800-63B, publiée en juillet 2025, renverse plusieurs habitudes de longue date. La longueur compte davantage que la composition : un mot de passe utilisé comme seul facteur doit compter au moins 15 caractères (au moins 8 lorsqu’il n’est utilisé que dans le cadre d’une authentification multifacteur), et les vérificateurs devraient accepter au moins 64 caractères, espaces et caractères Unicode compris. Les vérificateurs ne doivent pas imposer de règles de composition, comme l’obligation d’inclure un chiffre et un symbole, qui rendent les mots de passe plus difficiles à retenir sans les rendre beaucoup plus difficiles à deviner. Ils doivent vérifier les nouveaux mots de passe par rapport à une liste de blocage de mots de passe courants, prévisibles et compromis. Ils ne doivent pas imposer de changements périodiques, seulement un changement en cas de preuve de compromission. Ils doivent autoriser les gestionnaires de mots de passe et devraient autoriser le collage, ne doivent pas proposer d’indices de mot de passe lisibles avant la connexion et ne doivent pas demander de réponses à des questions de sécurité. Les tentatives échouées doivent faire l’objet d’une limitation de débit (rate limiting).

L’authentification multifacteur (MFA) combine des facteurs de natures différentes : quelque chose que vous savez (un mot de passe), quelque chose que vous possédez (un téléphone ou une clé de sécurité) et quelque chose que vous êtes (une empreinte digitale, généralement utilisée seulement pour déverrouiller un appareil). Elle déjoue l’essentiel du bourrage d’identifiants (credential stuffing), où des attaquants essaient des couples nom d’utilisateur et mot de passe divulgués par d’autres sites. Tous les seconds facteurs ne se valent pas : les codes à usage unique envoyés par SMS peuvent être volés par échange de carte SIM (SIM swapping), et aucun code à usage unique, qu’il vienne d’un SMS ou d’une application d’authentification, ne résiste à l’hameçonnage, car l’utilisateur peut être amené par la ruse à le saisir sur un faux site qui le relaie immédiatement. Les lignes directrices du NIST exigent donc que les services au niveau d’assurance de l’authentification 2 proposent au moins une option résistante à l’hameçonnage, et que ceux du niveau 3 en utilisent une.

Une passkey (clé d’accès) est l’option résistante à l’hameçonnage que la plupart des utilisateurs peuvent réellement utiliser. Les passkeys sont des identifiants FIDO2, fondés sur la Web Authentication API du W3C (WebAuthn) et sur le Client to Authenticator Protocol (CTAP) de la FIDO Alliance. À l’enregistrement, l’appareil de l’utilisateur crée une nouvelle paire de clés pour ce site web ; le serveur ne stocke que la clé publique. À la connexion, le serveur envoie un défi aléatoire, et l’appareil le signe avec la clé privée une fois que l’utilisateur l’a déverrouillé par empreinte digitale, reconnaissance faciale ou code PIN. Comme le navigateur lie l’identifiant à l’origine du site web, un site d’hameçonnage qui imite le vrai ne peut pas obtenir de signature valide, et comme le serveur ne détient aucun secret partagé, une violation de sa base de données ne fournit rien qu’un attaquant puisse rejouer. Les passkeys peuvent être liées à un appareil (sur une clé de sécurité matérielle) ou synchronisées entre les appareils d’un utilisateur par une plateforme ou un gestionnaire de mots de passe ; les recommandations 2025 du NIST acceptent les passkeys synchronisées au niveau 2, tandis que le niveau 3 exige une clé non exportable.

Le point faible architectural de tout dispositif d’authentification est la récupération de compte. Si une passkey perdue peut être remplacée en cliquant sur un lien reçu par e-mail, la solidité de tout le système est celle du compte e-mail. Les parcours de récupération méritent leur propre modèle de menaces, des limites de débit, des notifications sur les autres appareils de l’utilisateur et, pour les comptes à forte valeur, des délais ou des vérifications humaines.

Sessions et jetons

Une fois l’utilisateur authentifié, le système doit reconnaître ses requêtes suivantes sans lui redemander qui il est. Il existe deux conceptions de base. Dans une session côté serveur, le serveur stocke la session (utilisateur, expiration, éventuellement rôles) et donne au navigateur un long identifiant de session aléatoire dans un cookie. Dans une conception à jeton autonome, l’émetteur signe un jeton qui porte les revendications (claims), généralement un JSON Web Token (JWT, RFC 7519), et tout service qui détient la clé publique de l’émetteur peut le valider sans rien consulter.

Sessions côté serveur et jetons autonomes comparés

AspectSession côté serveurJeton autonome (JWT)
Où se trouve l’étatDans un magasin de sessions sur le serveur ; le navigateur ne détient qu’un identifiant aléatoire.Dans le jeton signé ; le serveur ne conserve rien par utilisateur.
RévocationSupprimer la session : effet immédiat.Impossible avant l’expiration sans liste de refus ni consultation, si bien que les durées de vie doivent être courtes.
Passage à l’échelle entre servicesNécessite un magasin de sessions partagé ou un routage persistant (sticky).Tout service peut valider la signature localement.
Taille sur le réseauUn petit cookie.De quelques centaines d’octets à quelques kilo-octets à chaque requête.
Usage typiqueSessions de navigateur pour les applications web et les backends for frontends.Jetons d’accès pour les API, les applications mobiles et les appels entre services.
Principaux risquesFixation de session et falsification de requête intersites (atténuées en régénérant l’identifiant à la connexion et par les cookies SameSite).Vol par injection de script s’il est conservé dans le stockage du navigateur ; erreurs de validation ; revendications périmées.

Pour les applications de navigateur, une session côté serveur dans un cookie marqué HttpOnly (invisible pour JavaScript), Secure (HTTPS uniquement) et SameSite est difficile à battre. Les applications monopages utilisent de plus en plus un backend for frontend (BFF) : le navigateur ne détient qu’un cookie de session pour son propre petit backend, qui détient les jetons OAuth et appelle les API pour son compte, une approche que recommandent les lignes directrices du groupe de travail OAuth de l’IETF pour les applications fonctionnant dans le navigateur. Les JWT excellent entre services et dans les applications mobiles, où une vérification sans état à chaque saut évite un goulet d’étranglement central.

import jwt  # PyJWT
from jwt import PyJWKClient

ISSUER = "https://id.fooddelivery.example/"
jwks = PyJWKClient(ISSUER + ".well-known/jwks.json")  # issuer's public keys

def verify_access_token(token: str) -> dict:
    signing_key = jwks.get_signing_key_from_jwt(token)
    return jwt.decode(
        token,
        signing_key.key,
        algorithms=["RS256"],      # pinned: never read from the token header
        audience="orders-api",      # the token must be meant for this API
        issuer=ISSUER,
        options={"require": ["exp", "iat", "sub"]},
    )  # raises an exception on any failure: fail closed
Valider un jeton d’accès dans une API Python avec PyJWT : l’algorithme, l’audience et l’émetteur sont fixés par l’API, jamais tirés du jeton.

OAuth 2.0 : l’autorisation déléguée

OAuth 2.0 (RFC 6749, 2012) résout un problème précis : permettre à une application d’agir au nom d’un utilisateur sans connaître son mot de passe. Avant OAuth, un service qui voulait importer vos contacts vous demandait le mot de passe de votre messagerie électronique. OAuth définit quatre rôles : le propriétaire de la ressource (l’utilisateur), le client (l’application qui veut obtenir l’accès), le serveur d’autorisation (qui authentifie l’utilisateur, lui demande son consentement et émet les jetons) et le serveur de ressources (l’API qui détient les données). Le client reçoit un jeton d’accès limité par des portées (scopes, comme orders:read), une durée de vie et une audience, et souvent un jeton de rafraîchissement qui permet d’obtenir de nouveaux jetons d’accès sans redemander à l’utilisateur.

OAuth définit plusieurs manières d’obtenir un jeton, appelées octrois (grants). Pour toute application qui agit pour un utilisateur, qu’il s’agisse d’une application web côté serveur, d’une application monopage ou d’une application mobile, l’octroi recommandé est le flux de code d’autorisation avec PKCE (Proof Key for Code Exchange, RFC 7636, 2015). Le client crée d’abord un code_verifier (vérificateur) aléatoire et n’envoie que son hachage SHA-256, le code_challenge (défi), lorsqu’il redirige l’utilisateur vers le serveur d’autorisation. Une fois que l’utilisateur s’est connecté et a donné son consentement, le serveur d’autorisation le redirige vers le client avec un code d’autorisation de courte durée. Le client échange ensuite ce code contre des jetons par une requête directe sur le canal arrière (back channel), en envoyant le vérificateur d’origine ; le serveur vérifie que son hachage correspond au défi. Un attaquant qui intercepte le code, par exemple une application mobile malveillante enregistrée pour la même adresse de redirection, ne peut pas l’échanger sans le vérificateur, qui n’a jamais quitté le client.

Diagramme de séquence du flux de code d’autorisation OAuth 2.0 avec PKCE entre le navigateur de l’utilisateur, l’app cliente, le serveur d’autorisation et le serveur de ressourcesUsager(navig.)App clienteServeur d’auto-risationServ. ressourcescrée code_verifier ;défi = son SHA-2561 /authorize + code_challenge2 connexion passkey, consentement3 authentification4 redir. : code + state5 /token : code + code_verifierSHA-256(verifier)= défi ?6 jeton d’accès (+ ID, refresh)7 GET /orders + jeton Bearer8 ses commandes
Le flux de code d’autorisation avec PKCE : seul le hachage du vérificateur transite dans les redirections du navigateur (le canal frontal) ; le vérificateur lui-même est envoyé directement à l’endpoint de jeton.

L’octroi par identifiants client (client credentials grant) couvre le cas où il n’y a pas d’utilisateur : un service obtient un jeton en son propre nom, par exemple le service d’affectation qui appelle l’API d’un partenaire cartographique, ou le système d’un partenaire qui appelle l’API de statut des commandes de la plateforme. Le client devrait s’authentifier auprès de l’endpoint de jeton avec une clé privée (une assertion JWT signée) ou avec le TLS mutuel (RFC 8705) plutôt qu’avec un secret partagé. Deux octrois plus anciens sont désormais déconseillés : l’octroi implicite, qui renvoyait les jetons dans l’URL du navigateur, et l’octroi par mot de passe du propriétaire de la ressource, qui faisait collecter le mot de passe de l’utilisateur par le client et allait ainsi à l’encontre du but même d’OAuth. La RFC 9700, l’OAuth 2.0 Security Best Current Practice publiée en janvier 2025, consigne ces leçons, notamment la correspondance exacte des adresses de redirection et les jetons liés à l’expéditeur.

OAuth 2.1 regroupe OAuth 2.0 et ces bonnes pratiques en un seul document : PKCE est obligatoire pour le flux de code d’autorisation, les octrois implicite et par mot de passe sont supprimés, les adresses de redirection doivent correspondre exactement et les jetons porteurs (bearer tokens) ne peuvent plus être envoyés dans les chaînes de requête des URL. Au moment où ces lignes sont écrites (octobre 2026), c’est toujours un Internet-Draft de l’IETF (version 16, septembre 2026), et non une RFC, mais ses règles décrivent déjà ce que font les serveurs d’autorisation bien gérés.

Guide de décision

Guide de décision : quel flux OAuth 2.0 choisir ?

Pour chaque type d’appelant des API de livraison de repas.

  1. Une personne est-elle présente, et l’application agit-elle en son nom ?
    OuiUtilisez le flux de code d’autorisation avec PKCE, pour les applications web, monopages et mobiles sans distinction ; jamais les octrois implicite ou par mot de passe.
    NonPassez à la question suivante.
  2. L’appareil est-il incapable d’afficher un navigateur, ou peu pratique pour la saisie, comme l’écran de cuisine d’un restaurant ?
    OuiUtilisez l’octroi d’autorisation d’appareil (device authorization grant, RFC 8628) : l’appareil affiche un code court que l’utilisateur approuve sur son téléphone.
    NonPassez à la question suivante.
  3. S’agit-il d’un de vos propres services qui en appelle un autre au sein de votre plateforme ?
    OuiPréférez l’identité de charge de travail (TLS mutuel avec des identités émises par la plateforme) ; si l’API attend des jetons OAuth, utilisez les identifiants client avec une authentification du client par clé.
    NonPassez à la question suivante.
  4. S’agit-il du système d’un partenaire qui appelle votre API en son propre nom ?
    OuiUtilisez les identifiants client avec des jetons de courte durée et de portée étroite, un client par partenaire et des limites de débit propres à chaque partenaire.
    NonRéexaminez l’exigence : une conception dans laquelle votre client a besoin du mot de passe d’un utilisateur est un signal d’alarme.

OpenID Connect, authentification unique et SAML

OAuth émet des jetons d’accès pour les API ; il n’indique pas, à lui seul, au client qui est l’utilisateur. Utiliser un jeton d’accès comme preuve de connexion est une erreur bien connue, car un jeton émis pour une application peut être rejoué auprès d’une autre qui ne vérifie pas son audience. OpenID Connect (OIDC, Core 1.0, 2014) ajoute la couche d’identité manquante. Avec la portée openid, le serveur d’autorisation, qui joue alors le rôle de fournisseur OpenID, renvoie aussi un jeton d’identité (ID token) : un JWT signé destiné au client, qui indique l’émetteur, l’identifiant stable de l’utilisateur (sub), l’audience (l’identifiant du client), les dates d’émission et d’expiration, un nonce qui le rattache à cette connexion et, facultativement, comment et quand l’utilisateur s’est authentifié. OIDC normalise aussi un endpoint d’informations sur l’utilisateur et des documents de découverte qui publient les endpoints et les clés de signature du fournisseur. La règle empirique : le jeton d’identité est destiné au client, pour savoir qui s’est connecté ; le jeton d’accès est destiné à l’API, pour autoriser les appels.

L’authentification unique (SSO) en découle naturellement : dès qu’un utilisateur a une session auprès du fournisseur d’identité, chaque application qui lui fait confiance peut le connecter sans lui redemander de mot de passe, et la désactivation du compte en un seul endroit coupe l’accès partout. En entreprise, le SSO utilise encore souvent SAML 2.0 (une norme OASIS de 2005), qui échange des assertions XML signées par l’intermédiaire du navigateur. La plateforme de livraison de repas pourrait utiliser OIDC pour ses propres applications et accepter SAML de la part de grandes chaînes de restaurants qui veulent que leur personnel se connecte au portail des restaurants avec ses comptes d’entreprise. Le provisionnement et le déprovisionnement des comptes entre systèmes sont généralement automatisés avec SCIM (RFC 7643 et 7644).

Modèles d’autorisation : RBAC, ABAC et relations

L’authentification indique au système qui appelle ; un modèle d’autorisation décide de ce que l’appelant peut faire. Trois modèles dominent, et les systèmes réels les combinent généralement.

Trois modèles d’autorisation

ModèleComment il décidePoints fortsFaiblesses
Basé sur les rôles (RBAC)Les permissions sont accordées à des rôles ; des rôles sont attribués aux utilisateurs. Formalisé par David Ferraiolo et Richard Kuhn au NIST en 1992.Simple à comprendre et à auditer ; correspond à des fonctions comme celle d’agent du support.Ne peut pas exprimer « seulement les siens » sans règles supplémentaires ; le découpage par établissement ou par marché mène à une explosion des rôles.
Basé sur les attributs (ABAC)Une politique évalue des attributs du sujet, de la ressource, de l’action et de l’environnement ; décrit dans la NIST SP 800-162 (2014).Très expressif : marché, classification des données, heure, état de sécurité de l’appareil, montant.Plus difficile de répondre à « qui peut accéder à ceci ? » ; les politiques peuvent devenir opaques et lentes.
Basé sur les relations (ReBAC)L’accès suit des relations stockées sous forme de graphe : un utilisateur gère un établissement, un établissement appartient à un restaurant, une commande appartient à un établissement.Naturel pour le partage et les hiérarchies ; passe à l’échelle jusqu’à des permissions fines, objet par objet.Nécessite un magasin de relations dédié et cohérent, et une modélisation soignée.

Le contrôle d’accès basé sur les relations est surtout connu par l’article de Google de 2019 sur Zanzibar, le système d’autorisation mondial qui sous-tend Google Drive, Calendar, YouTube et bien d’autres produits. Zanzibar stocke des tuples de relation de la forme object#relation@user, évalue les permissions en les suivant, et utilise des jetons de cohérence pour qu’une vérification de permission ne soit jamais évaluée sur des données plus anciennes que le contenu qu’elle protège ; c’est ce qu’on appelle le problème du « nouvel ennemi » (new enemy problem) : retirer quelqu’un d’un document puis y ajouter un contenu sensible ne doit pas lui permettre de le voir. Parmi les systèmes open source qui s’en inspirent figurent SpiceDB, OpenFGA et Ory Keto.

Quel que soit le modèle, il est utile de séparer le point de décision de politique (PDP), qui évalue la politique et répond « autoriser » ou « refuser », du point d’application de politique (PEP), le code de la passerelle ou du service qui pose la question et applique la réponse. Les moteurs de politiques généralistes comme Open Policy Agent (OPA, projet diplômé de la Cloud Native Computing Foundation, dont les politiques s’écrivent dans son langage Rego) et Cedar (publié en open source par Amazon Web Services en 2023) permettent aux politiques de vivre dans des fichiers versionnés, d’être testées comme du code et d’être évaluées dans le processus ou dans un sidecar, au plus près du service. Sur la plateforme, un découpage en couches raisonnable est le suivant : l’API gateway rejette les requêtes sans jeton valide ou sans la bonne portée (contrôle grossier), et chaque service tranche les questions au niveau de l’objet avec des données que lui seul possède (contrôle fin). La faille Broken Object Level Authorization (autorisation défaillante au niveau de l’objet) est le premier risque de l’OWASP API Security Top 10 (édition 2023), précisément parce que le contrôle fin est celui que les équipes oublient.

Exemple commenté

Exemple commenté : qui peut modifier une carte, marquer une commande comme prête ou voir une adresse de retrait

Les restaurants de la plateforme vont du café unique à des chaînes de plusieurs dizaines d’établissements. Exigences : les propriétaires de chaîne gèrent tous les établissements ; les gérants d’établissement modifient la carte de leur propre établissement ; le personnel de cuisine marque comme prêtes les commandes de son établissement ; un livreur ne voit les informations de retrait que pour les commandes qui lui sont affectées ; les gérants peuvent accorder des remboursements commerciaux jusqu’à £20.

Première tentative : RBACRôles owner, manager, staff, courier. Chaque vérification a alors besoin de savoir « pour quel établissement ? » ou « quelle commande ? », ce qui mène à des rôles comme manager_branch_1742 : des milliers de rôles, un par établissement et par fonction.
Tuples ReBACrestaurant:bella#owner@user:ana; branch:bella-soho#parent@restaurant:bella; branch:bella-soho#manager@user:ben; branch:bella-soho#staff@user:kai; order:9812#branch@branch:bella-soho; order:9812#courier@user:cara
Règles du modèlebranch.edit_menu = gérant, ou propriétaire du restaurant parent. order.mark_ready = personnel ou gérant de l’établissement de la commande. order.view_pickup = le livreur affecté, ou le personnel de l’établissement de la commande.
Vérificationsben peut-il modifier la carte de bella-soho ? Oui (gérant). Et ana ? Oui (propriétaire du parent). cara peut-elle voir le retrait de la commande 9812 ? Oui, jusqu’à ce qu’Affectation supprime son tuple de livreur à la fin de la livraison ; ensuite, non.
ABAC pour le plafond de remboursementLa règle de remboursement dépend d’un attribut de la requête, et non d’une relation : le moteur de politiques autorise refund si l’utilisateur gère l’établissement de la commande et si le montant ne dépasse pas £20.
Lieu d’applicationLa passerelle vérifie la validité et la portée du jeton ; les services de la carte, des commandes et d’affectation demandent chacun au PDP la décision au niveau de l’objet avant d’agir.

Les relations répondent directement aux questions d’audit : lister toutes les personnes qui peuvent modifier la carte d’un établissement est une requête sur le graphe, et non une revue de code.

Les données de relation ont désormais elles aussi un responsable : Affectation écrit les tuples de livreur, le portail des restaurants écrit les tuples du personnel, et les tuples périmés sont un bug de sécurité.

Identité de charge de travail : quand l’appelant est un service

Les services s’authentifient les uns auprès des autres bien plus souvent que les personnes ne se connectent, et pourtant les identifiants des services sont souvent les plus faibles : une clé d’API de longue durée dans une variable d’environnement, partagée par plusieurs services et jamais renouvelée. Si cette clé fuit par un journal, un dépôt ou une image de conteneur, l’attaquant devient le service. L’identité de charge de travail (workload identity) remplace ces secrets par des identités que la plateforme émet pour la charge de travail en cours d’exécution, après avoir vérifié ce qu’est cette charge de travail.

Le standard ouvert est SPIFFE (Secure Production Identity Framework for Everyone), un projet diplômé de la Cloud Native Computing Foundation. Il nomme chaque charge de travail par une URI comme spiffe://fooddelivery.example/ns/prod/sa/orders et émet un document de courte durée, renouvelé automatiquement, qui prouve cette identité ; ce document, appelé SVID, est généralement un certificat X.509 (ou un JWT). Son implémentation de référence, SPIRE, atteste le nœud et la charge de travail (par exemple son espace de noms et son compte de service Kubernetes) avant d’émettre l’identité. Les services utilisent ensuite les certificats pour le TLS mutuel, si bien que le service des paiements sait que l’appelant est réellement le service des commandes, et peut autoriser en fonction de l’identité. Les plateformes cloud proposent des équivalents (rôles pour les charges de travail, identités managées, fédération d’identité de charge de travail), et les systèmes de CI comme GitHub Actions peuvent échanger un jeton OIDC signé contre des identifiants cloud de courte durée, si bien que les pipelines n’ont besoin d’aucune clé stockée. La façon dont ces identités servent à construire un réseau sans confiance implicite est le sujet du zero trust.

Vérifiez votre compréhension

Une API renvoie 403 à un appelant muni d’un jeton valide. Qu’est-ce que cela vous apprend ?

L’appelant a été authentifié mais n’est pas autorisé pour cette action ou cet objet ; 401 signifierait une authentification absente ou invalide.

Contre quoi PKCE protège-t-il dans le flux de code d’autorisation ?

Contre l’interception ou l’injection du code d’autorisation : sans le vérificateur de code, qui ne transite jamais dans les redirections du navigateur, un code volé ne peut pas être échangé contre des jetons.

Pourquoi un service ne devrait-il pas accepter un jeton d’identité OpenID Connect comme jeton d’accès à une API ?

Le jeton d’identité est adressé au client (son audience est l’identifiant du client) pour lui indiquer qui s’est connecté ; les API ne devraient accepter que des jetons d’accès émis pour elles, dont l’audience et la portée sont vérifiées.

Pourquoi un rôle comme manager_branch_1742 laisse-t-il penser que le modèle d’autorisation n’est pas le bon ?

Il encode une relation (gérant d’un établissement donné) sous forme de rôle, ce qui mène à une explosion des rôles ; des règles basées sur les relations ou sur les attributs l’expriment directement.

Suivant · 8.4Protéger les donnéesLe chiffrement en transit et au repos et ce que chaque couche protège réellement, la cryptographie symétrique et asymétrique, le hachage des mots de passe, le KMS et le chiffrement d’enveloppe, les secrets, la tokenisation pour PCI DSS et la classification des données.Continuer →

Sources et lectures complémentaires

Une question sur cette section ? ArchitectBot, l’assistant d’étude IA du cours, répond d’abord à partir du cours.

Demander : « Notre application monopage doit-elle conserver les jetons OAuth dans le navigateur, ou utiliser un backend for frontend, et qu’est-ce qui change dans l’architecture si nous basculons ? »