Le badge ouvre le port, pas tous les quais

Un badge portuaire dit qui vous êtes et que la capitainerie vous a enregistré. Il ne dit rien de plus. Quels quais vous pouvez franchir, à quelles heures, avec quel véhicule, tout cela relève d'autres règles, imprimées ailleurs.

La zone sous douane, elle, ne s'ouvre jamais avec un badge ordinaire. Il y faut une habilitation nominative, demandée pour une opération précise, validée par un responsable, et qui expire toute seule au bout de deux heures.

Le billet précédent a posé l'annuaire et l'identité hybride. Il répond à une question et une seule : qui est ce demandeur. Celui-ci traite les trois questions suivantes, celles qui décident de ce que le demandeur peut réellement faire.

RBAC répond « quoi, et sur quelle portée ». L'accès conditionnel répond « dans quelles conditions ». Privileged Identity Management, ou PIM, répond « pendant combien de temps ». Les trois s'empilent, on les confond en permanence, et aucun ne rattrape l'absence des deux autres.

Authentifier n'est pas autoriser. Un annuaire impeccable, avec des attributions Propriétaire distribuées au fil des demandes, produit exactement la même catastrophe qu'un annuaire médiocre.

L'ordre d'évaluation explique la plupart des surprises, autant le poser une fois pour toutes. L'authentification vient en premier. L'accès conditionnel décide ensuite si un jeton est émis, et sous quelles conditions supplémentaires. Le jeton en poche, l'appel part vers Azure Resource Manager, qui se pose une question unique au moment de l'appel : ce principal dispose-t-il, à cet instant, d'une attribution couvrant cette action sur cette portée.

PIM agit en amont de cette dernière vérification. Il ne change pas le rôle, il change son état : éligible, donc inerte, ou actif, donc opposable.

flowchart TD dem["Demande d'accès
personne ou application"] auth["L'annuaire authentifie
qui est le demandeur"] ca{"Accès conditionnel
signaux conformes ?"} ref["Refus, ou contrôle
supplémentaire exigé"] jet["Jeton émis
durée de vie limitée"] pim{"Le rôle est-il actif
ou seulement éligible ?"} act["Activation PIM
justification, approbation, durée"] arm["Azure Resource Manager
évalue l'appel"] deny{"Refus d'attribution
ou verrou de ressource ?"} rbac{"Une attribution couvre-t-elle
cette action sur cette portée ?"} ok["Action autorisée"] ko["Action refusée"] dem --> auth --> ca ca -->|non| ref ca -->|oui| jet jet --> pim pim -->|éligible| act --> arm pim -->|actif| arm arm --> deny deny -->|oui| ko deny -->|non| rbac rbac -->|oui| ok rbac -->|non| ko classDef entree fill:#f5f2ec,stroke:#8a4d16,color:#1a1a1a classDef ctrl fill:#ede9e1,stroke:#b5651d,color:#1a1a1a classDef final fill:#b5651d,stroke:#5f5e5a,color:#f5f2ec classDef refus fill:#a0413e,stroke:#5f5e5a,color:#f5f2ec class dem,auth,jet entree class ca,pim,act,arm,deny,rbac ctrl class ok final class ko,ref refus

RBAC : quoi, et sur quelle portée

Sur le badge d'un docker, il y a une photo et une liste de zones. La photo relève de la capitainerie, la liste de zones relève de l'exploitant du terminal. Deux registres différents, deux gestes différents, et c'est déjà la moitié des malentendus.

Trois pièces, jamais deux

Une attribution de rôle Azure est un triplet. Un principal de sécurité : une personne, un groupe, un principal de service ou une identité managée. Une définition de rôle : la liste des opérations permises. Une portée : l'endroit de la hiérarchie où cette liste s'applique.

Retirez une des trois pièces, il ne se passe rien. Un rôle sans portée n'existe pas, une portée sans rôle non plus.

La première règle d'hygiène est courte : on attribue à des groupes, pas à des personnes. Le nombre d'attributions par abonnement est plafonné, et surtout, une attribution nominative survit toujours à la personne qui a changé d'équipe.

La portée et l'héritage

La hiérarchie a quatre étages, posés au billet sur la gouvernance : groupe d'administration, abonnement, groupe de ressources, ressource. Une attribution descend, jamais l'inverse.

Le modèle est additif. Les attributions s'accumulent, et l'effet obtenu est l'union de tout ce qui a été accordé aux différentes portées. Il n'existe pas de « rôle plus restrictif » qui viendrait annuler un rôle plus large accordé plus haut.

Portée Ce qu'elle couvre Quand elle est le bon niveau Ce qu'elle coûte si on se trompe
Groupe d'administration tous les abonnements en dessous, présents et à venir lecture globale, rôles de sécurité transverses un droit d'écriture y devient un droit sur tout le patrimoine
Abonnement toutes les ressources de l'abonnement équipe qui exploite un environnement entier l'accès survit largement au projet qui l'a justifié
Groupe de ressources les ressources d'une application, cycle de vie commun le cas par défaut pour une équipe applicative risque contenu, c'est le compromis raisonnable
Ressource un compte de stockage, un coffre, une machine accès aux données, exception ponctuelle une multiplication d'attributions que plus personne ne relit

Le réflexe utile consiste à attribuer au plus bas niveau qui rend le travail possible, puis à remonter seulement si la douleur devient réelle. L'inverse ne se corrige jamais, parce que personne ne retire un droit qui fonctionne.

Les rôles à connaître avant d'en inventer

Une définition de rôle sépare deux plans. Les Actions portent sur le plan de contrôle : créer, configurer, supprimer une ressource. Les DataActions portent sur le plan de données : lire le contenu d'un blob, lire un secret. Cette séparation explique un comportement qui déroute tout le monde.

Rôle Ce qu'il permet Le piège
Propriétaire tout, y compris accorder des droits à quiconque il n'a aucun plafond : celui qui l'a peut se cloner autant de fois qu'il veut
Contributeur tout sauf attribuer des rôles il administre un compte de stockage, donc il en lit les clés, donc il atteint la donnée
Lecteur lecture du plan de contrôle il ne lit pas le contenu d'un blob : la donnée exige un rôle de données
Administrateur de l'accès utilisateur gérer les attributions, et rien d'autre bon complément de Contributeur, à condition de le soumettre à activation temporaire
Rôles de données, par exemple Key Vault Secrets User lire ou écrire la donnée elle-même on les oublie, et on rouvre les clés partagées « pour que ça marche »

Reste un rôle plus discret, l'administrateur du contrôle d'accès en fonction du rôle, qui permet de gérer les attributions sans emporter le reste des permissions de Propriétaire. C'est souvent la bonne réponse à la demande « il me faut Propriétaire pour donner un accès ».

Quand écrire un rôle personnalisé

Le rôle personnalisé se justifie quand aucun rôle intégré ne colle et que l'écart se paie cher. Le cas typique : une équipe d'astreinte qui doit redémarrer des machines sans pouvoir les redimensionner ni les supprimer.

{
  "Name": "Redémarrage de machines virtuelles",
  "IsCustom": true,
  "Description": "Démarrer, arrêter et redémarrer une machine, sans la modifier ni la supprimer.",
  "Actions": [
    "Microsoft.Compute/virtualMachines/read",
    "Microsoft.Compute/virtualMachines/start/action",
    "Microsoft.Compute/virtualMachines/restart/action",
    "Microsoft.Compute/virtualMachines/deallocate/action"
  ],
  "NotActions": [],
  "AssignableScopes": [
    "/subscriptions/<id-abonnement>/resourceGroups/rg-production"
  ]
}

Le champ AssignableScopes décide de la portée où ce rôle pourra être attribué. Le déclarer à partir d'un groupe d'administration évite d'avoir à recréer le même rôle dans chaque abonnement, ce qui est le premier travers du rôle personnalisé.

Le second travers est la prolifération. Un catalogue de quarante rôles maison que personne ne sait relire vaut moins qu'une dizaine de rôles intégrés bien placés.

Ce qui passe avant les attributions

Deux mécanismes s'appliquent en amont du modèle additif. Le refus d'attribution bloque une opération quelles que soient les attributions accordées : il ne se crée pas à la main, la plateforme le pose pour protéger ce qu'elle gère, notamment avec les applications managées et les piles de déploiement.

Le verrou de ressource, lui, se pose volontairement, en lecture seule ou en interdiction de suppression. Il vaut pour tout le monde, y compris pour le Propriétaire, et il s'hérite vers les ressources filles.

Un détail qui fait perdre une demi-journée à qui l'ignore : un verrou en lecture seule bloque aussi des opérations qui ressemblent à de la lecture mais qui n'en sont pas, comme la récupération des clés d'un compte de stockage. Le portail affiche alors une erreur sans rapport apparent avec le verrou.

Rôles Azure et rôles d'annuaire

Ce sont deux systèmes distincts, stockés à deux endroits, et les confondre mène à des demandes absurdes du type « donne-moi Administrateur général pour créer une machine virtuelle ».

Rôles Azure Rôles d'annuaire
Portent sur les ressources Azure les objets de l'annuaire : comptes, groupes, applications
Portées possibles groupe d'administration, abonnement, groupe de ressources, ressource le locataire entier, ou une unité administrative
Exemples Contributeur, Lecteur, Contributeur de machines virtuelles Administrateur général, Administrateur d'utilisateurs, Lecteur de sécurité
Évalués par Azure Resource Manager l'annuaire, au moment d'agir sur ses objets

Il existe une passerelle entre les deux : un Administrateur général peut activer une élévation qui lui donne le rôle d'administrateur de l'accès utilisateur à la racine de la hiérarchie. Autrement dit, le sommet de l'annuaire peut s'ouvrir la porte du sommet des ressources.

Le rôle Propriétaire distribué largement est la faille de conception la plus fréquente et la plus banale. Il n'a pas de plafond : qui le détient peut l'accorder à d'autres, y compris à lui-même sous un autre nom.

Les identités qui ne sont pas des personnes

Sur un terminal moderne, les engins de levage travaillent seuls la moitié du temps. Eux aussi franchissent des portails, eux aussi ont besoin d'un badge, sauf qu'on ne peut pas leur demander de retenir un code ni de le changer tous les trimestres.

Le principal de service est l'ancienne réponse. Une application est déclarée dans l'annuaire, on lui crée un secret ou un certificat, et ce secret finit quelque part : dans un fichier de configuration, dans une variable d'environnement, parfois dans un dépôt de code. Il expire, la production tombe un dimanche, quelqu'un le régénère avec une échéance plus lointaine.

L'identité managée supprime le problème à la racine. La plateforme crée le principal, détient le matériel cryptographique et le renouvelle, et l'application demande un jeton à un point de terminaison local. Aucun secret n'est écrit nulle part.

Mécanisme Où vit le secret Cycle de vie Bon usage
Principal de service avec secret ou certificat dans votre configuration, votre coffre, parfois votre dépôt expire, donc se renouvelle à la main dernier recours, quand rien d'autre n'est possible
Identité managée affectée par le système nulle part, la plateforme s'en charge créée et détruite avec la ressource une application, un accès, aucun partage
Identité managée affectée par l'utilisateur nulle part ressource autonome, survit à ce qui l'utilise flotte de machines identiques, droits accordés avant le déploiement
Identité de charge de travail fédérée nulle part, le jeton s'échange à la volée dépend de la confiance déclarée avec l'émetteur externe chaîne de livraison ou charge exécutée hors d'Azure

Le geste complet tient en deux commandes : donner une identité à l'application, puis attribuer à cette identité un rôle de données sur la seule ressource concernée.

# 1. L'application reçoit une identité gérée par la plateforme
az webapp identity assign \
  --name app-facturation \
  --resource-group rg-facturation

# 2. Cette identité reçoit un rôle de données, sur le seul coffre concerné
az role assignment create \
  --assignee-object-id "$PRINCIPAL_ID" \
  --assignee-principal-type ServicePrincipal \
  --role "Key Vault Secrets User" \
  --scope "/subscriptions/$SUB/resourceGroups/rg-facturation/providers/Microsoft.KeyVault/vaults/kv-facturation"

Côté application, la bibliothèque d'identité se charge de la négociation. Le code ne connaît ni mot de passe ni chaîne de connexion.

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

client = SecretClient(
    vault_url="https://kv-facturation.vault.azure.net",
    credential=DefaultAzureCredential(),
)

chaine_sql = client.get_secret("sql-facturation").value

Une nuance à garder en tête : le jeton d'une identité managée s'obtient depuis l'intérieur de la ressource. Quiconque parvient à exécuter du code sur cette machine, ou à lui faire émettre une requête vers son point de terminaison local, obtient le même jeton. L'identité managée supprime le secret, elle ne supprime pas le besoin de dimensionner ses droits au plus juste.

Une identité managée ne se contente pas de simplifier l'exploitation. Elle retire du système un objet qui pouvait être volé, recopié, oublié dans un journal ou versionné par erreur.

L'accès conditionnel : dans quelles conditions

Le badge s'arrête au sas. Le sas, lui, regarde autre chose : d'où vous arrivez, à quelle heure, avec quel véhicule, et si votre visite du jour ressemble à vos visites habituelles.

L'accès conditionnel fonctionne exactement comme ce sas. Ce n'est ni un pare-feu ni un antivirus, c'est un moteur de règles évalué au moment où l'annuaire s'apprête à délivrer un jeton. Il rassemble des signaux, prend une décision, et impose éventuellement un contrôle supplémentaire avant de laisser passer.

Signal évalué Exemple concret Contrôle qu'on lui associe
Utilisateur ou groupe le groupe des administrateurs de plateforme authentification forte systématique, sans exception
Ressource ciblée le portail d'administration du cloud appareil géré par l'entreprise exigé
Réseau plage d'adresses du siège, ou pays inhabituel blocage, ou reconnexion plus fréquente
Appareil poste conforme aux règles de l'entreprise contre machine personnelle session limitée dans le navigateur, sans téléchargement
Application cliente client moderne contre protocole d'authentification hérité blocage des protocoles hérités
Risque de connexion deux connexions depuis deux pays en dix minutes authentification forte exigée avant d'aller plus loin

Le signal de risque suppose la détection de risques de l'annuaire ; les autres reposent sur ce que l'annuaire observe déjà. L'accès conditionnel et PIM relèvent des niveaux payants de l'annuaire, sujet traité au billet précédent.

Trois règles de conception valent plus que la liste des options disponibles.

D'abord, peu de stratégies, et lisibles. Une organisation qui en compte quarante ne sait plus laquelle bloque quoi, et le jour où un utilisateur se retrouve dehors, personne ne trouve la bonne. Une convention de nommage qui dit à qui, sur quoi et pourquoi vaut toutes les documentations.

Ensuite, les comptes de secours. Deux comptes au minimum, créés uniquement dans le cloud, exclus de toutes les stratégies, avec des identifiants conservés hors ligne et une alerte sur chaque utilisation. Sans eux, une stratégie mal écrite verrouille l'organisation à l'extérieur de son propre locataire, et il n'y a personne pour ouvrir de l'intérieur.

Enfin, le mode rapport seul. Une stratégie y est évaluée et journalisée sans être appliquée, ce qui permet de mesurer précisément qui elle aurait bloqué avant de la mettre en vigueur. La simulation intégrée complète l'exercice pour un cas particulier.

Une limite structurelle mérite d'être dite. L'accès conditionnel protège les accès qui passent par l'annuaire. Une clé de compte de stockage ou une signature d'accès partagé ne passe pas par l'annuaire : elle contourne l'ensemble du dispositif. C'est un argument de plus pour supprimer ces clés au profit des rôles de données.

Reste la question de la durée. Un jeton d'accès vit de l'ordre de l'heure, donc une décision prise au moment de la connexion vaut jusqu'à sa péremption. L'évaluation continue de l'accès corrige ce délai pour les services qui la prennent en charge : un compte désactivé, un mot de passe réinitialisé ou un changement de réseau peut invalider la session sans attendre l'expiration.

Une stratégie d'accès conditionnel sans compte de secours exclu et sans passage préalable en mode rapport seul n'est pas une mesure de sécurité, c'est un pari sur la précision de sa propre syntaxe.

PIM : pendant combien de temps

L'habilitation de la zone sous douane ne se demande pas au moment de l'embauche. Elle se demande le jour où l'on doit y entrer, pour une opération identifiée, elle est validée par quelqu'un, et elle tombe d'elle-même à la fin du créneau.

PIM introduit cette distinction dans l'annuaire, en séparant deux états d'une même attribution.

Attribution active Attribution éligible
État par défaut le droit s'applique en permanence le droit existe mais ne produit aucun effet
Pour l'utiliser rien à faire activer, avec les conditions exigées
Traçabilité l'action est journalisée, pas la décision de l'exercer la demande, le motif et l'approbation sont journalisés
Exposition permanente, y compris pour un compte compromis limitée à la durée d'activation

L'activation se paramètre rôle par rôle. On peut exiger une authentification forte au moment de la demande, un motif écrit, une référence de ticket, l'approbation d'un ou plusieurs validateurs, et une durée maximale au-delà de laquelle le droit retombe tout seul.

Une attribution active peut elle-même être bornée dans le temps, avec une date de début et une date de fin. C'est la réponse propre au prestataire présent trois mois, à la place de l'accès accordé « le temps de la mission » et jamais retiré.

PIM couvre trois familles d'objets : les rôles d'annuaire, les rôles Azure sur n'importe quelle portée de la hiérarchie, et l'appartenance à des groupes. Cette dernière est la plus sous-estimée : dès qu'un accès dépend d'un groupe, y compris hors d'Azure, il devient activable à la demande sans rien changer à l'application concernée.

Le service émet aussi des alertes de configuration, du type nombre excessif de comptes disposant du rôle le plus élevé, ou attribution créée en dehors du dispositif. Elles constituent une revue permanente, à faible coût.

Les revues d'accès complètent le tableau sur l'autre échelle de temps. À intervalle défini, les détenteurs d'un rôle ou les membres d'un groupe sont soumis à validation, par leur responsable, par un relecteur désigné ou par eux-mêmes, et le résultat peut être appliqué automatiquement. Sans ce mécanisme, le stock de droits ne fait que croître.

Une mesure simple sert de baromètre : le nombre de personnes disposant en permanence d'un rôle à haut privilège. S'il ne baisse pas après la mise en place de PIM, l'outil est installé mais pas utilisé.

PIM ne réduit pas le privilège, il réduit sa durée. Un compte compromis pendant une fenêtre où aucun rôle n'est actif ne donne à l'attaquant que ce qu'un compte ordinaire donne.

La question posée, le mécanisme qui répond

Le poste de garde relit tout à la fin : le badge, la zone, l'habilitation, et l'heure. Voici la même relecture, côté Azure.

La question posée Le mécanisme qui répond L'erreur classique
Qui est ce demandeur ? l'annuaire et l'authentification croire que l'authentification décide de l'autorisation
Quoi, et sur quelle portée ? RBAC Azure Propriétaire sur l'abonnement, « en attendant »
Et sur les objets de l'annuaire ? rôles d'annuaire confondre Administrateur général et Propriétaire
Dans quelles conditions ? accès conditionnel une stratégie sans compte de secours exclu
Pendant combien de temps ? PIM activer le lundi matin pour toute la semaine
Comment une application prouve-t-elle son identité ? identité managée un secret déposé en variable d'environnement
Est-ce encore justifié aujourd'hui ? revues d'accès l'accès d'un projet terminé il y a deux ans

La colonne du milieu se lit dans les deux sens. Un problème d'accès mal posé se reconnaît à ce qu'on cherche à le résoudre avec le mauvais mécanisme : élargir un rôle parce qu'un contrôle conditionnel gêne, ou ajouter une stratégie parce qu'un rôle est trop large.

Le moindre privilège se mesure sur trois axes en même temps : l'étendue des droits, les conditions dans lesquelles ils s'exercent, et la durée pendant laquelle ils existent. Serrer un seul des trois ne produit presque rien.

Scénario B : Twitter, 15 juillet 2020

Le 15 juillet 2020, plusieurs comptes parmi les plus suivis de la plateforme publient simultanément le même message, une escroquerie promettant de doubler tout envoi en bitcoin. Le rapport d'enquête publié le 14 octobre 2020 par le New York State Department of Financial Services, le régulateur financier de l'État de New York, en donne le déroulé.

L'entrée ne s'est pas faite par une faille technique. Les attaquants ont téléphoné à des employés en se faisant passer pour le support informatique interne, dans un contexte de travail à distance où les problèmes de connexion au réseau privé de l'entreprise étaient devenus banals. Ils ont orienté leurs interlocuteurs vers un site imitant le portail d'authentification interne, ont récupéré leurs identifiants, et se sont fait dicter en direct les codes du second facteur, qu'ils rejouaient immédiatement sur le vrai portail.

Munis de ces accès, ils ont atteint les outils d'administration internes de la plateforme, ceux qui permettent aux équipes de support d'agir sur les comptes des utilisateurs : changer l'adresse de messagerie associée, désactiver la double authentification, déclencher une réinitialisation de mot de passe.

Les chiffres publiés donnent la mesure de ce que ces outils permettaient. Environ 130 comptes ont été visés, 45 ont fait l'objet d'une réinitialisation de mot de passe suivie de publications, 36 boîtes de messages privés ont été consultées, et les données de 7 comptes ont été téléchargées. L'escroquerie a rapporté plus de 118 000 dollars en bitcoin.

Le rapport souligne deux points qui dépassent largement le cas d'espèce. D'abord que les auteurs n'étaient pas des attaquants sophistiqués : plusieurs étaient très jeunes, et leur mode opératoire tenait entièrement dans un appel téléphonique bien préparé. Ensuite que l'entreprise était alors sans responsable de la sécurité des systèmes d'information depuis plusieurs mois.

La transposition est directe. Trois points du billet s'y retrouvent.

Le privilège, d'abord. Un outil d'administration qui permet d'agir sur n'importe quel compte est un rôle à très large portée. Attribué de façon permanente à une population nombreuse, il transforme la compromission d'un seul employé de support en compromission de la plateforme entière. Une élévation temporaire, motivée et approuvée, n'aurait pas empêché l'hameçonnage, mais elle aurait réduit le nombre de comptes capables d'agir à un instant donné.

Le second facteur, ensuite. Un code à usage unique se dicte au téléphone et se rejoue en quelques secondes. Un contrôle qui exige un appareil géré par l'entreprise ou une méthode d'authentification résistante à l'hameçonnage ne se transmet pas de vive voix.

La journalisation, enfin. La question qui compte après coup n'est pas seulement qui a fait quoi, mais qui avait la possibilité de le faire. Sur un parc où les rôles sensibles s'activent à la demande avec un motif, cette réponse s'obtient en une requête.

L'incident ne raconte pas une prouesse technique. Il raconte un privilège permanent, très large, accordé à beaucoup de monde, et le peu qu'il faut pour s'en emparer.

Points clés

  • Une attribution RBAC est un triplet inséparable : un principal, un rôle, une portée. On attribue à des groupes, au plus bas niveau qui rend le travail possible.
  • Le rôle Propriétaire n'a pas de plafond, puisqu'il permet de distribuer des droits. Contributeur associé à un rôle d'administration des accès sous activation temporaire couvre presque tous les besoins réels.
  • Plan de contrôle et plan de données sont deux mondes : Lecteur ne lit pas un blob, et Contributeur atteint la donnée par les clés du compte de stockage.
  • L'accès conditionnel s'écrit en peu de stratégies lisibles, avec des comptes de secours exclus et un passage préalable en mode rapport seul. Les clés partagées le contournent entièrement.
  • Avec PIM, un droit sensible n'existe que pendant sa fenêtre d'activation. Le baromètre utile est le nombre de rôles à haut privilège actifs en permanence.

Dans la série

Palier 1 : Ouvrir le port. Domaine : Identité.


Pour aller plus loin