Gestion des identités et des accès (IAM)#

L’IAM (Identity and Access Management) répond à trois questions fondamentales : Qui est l’utilisateur ? (authentification), Que peut-il faire ? (autorisation), et Comment gérer le cycle de vie de son identité ? (provisioning). À l’échelle des systèmes distribués modernes, ces questions deviennent complexes : des milliers d’utilisateurs humains, des centaines de comptes de service, des applications déployées sur plusieurs clouds, des identités fédérées entre organisations.

Hide code cell source

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
import seaborn as sns
from matplotlib.patches import FancyBboxPatch

Authentification#

Les trois facteurs#

L’authentification repose sur un ou plusieurs des trois facteurs :

Facteur

Catégorie

Exemples

Faiblesses

Quelque chose que vous savez

Connaissance

Mot de passe, PIN, question secrète

Phishing, credential stuffing, keyloggers

Quelque chose que vous possédez

Possession

TOTP (Google Authenticator), clé matérielle (YubiKey), SMS OTP

SIM swapping (SMS), malware (TOTP logiciel)

Quelque chose que vous êtes

Inhérence

Empreinte digitale, reconnaissance faciale, iris

Faux positifs, problèmes de vie privée, non-révocable

Le MFA (Multi-Factor Authentication) combine au moins deux facteurs de catégories différentes. Deux mots de passe ne constituent pas un MFA.

WebAuthn / FIDO2 — les passkeys#

WebAuthn est un standard W3C qui permet une authentification forte sans mot de passe (passwordless) ou en complément d’un mot de passe. Il repose sur la cryptographie asymétrique :

  1. Enregistrement : l’authentificateur (appareil de l’utilisateur) génère une paire de clés Ed25519/P-256 liée au domaine (relying party). La clé publique est stockée sur le serveur.

  2. Authentification : le serveur envoie un challenge aléatoire ; l’authentificateur signe le challenge avec la clé privée (protégée par biométrie ou PIN local) ; le serveur vérifie la signature.

Avantages sur TOTP :

  • Résistant au phishing (la clé est liée au domaine exact)

  • Pas de secret partagé côté serveur (contrairement à TOTP où la graine est stockée)

  • Pas de transmission de secret sur le réseau

Les passkeys sont des identifiants WebAuthn synchronisés entre appareils via le cloud du fournisseur (Apple iCloud, Google Password Manager). Ils permettent une expérience passwordless complète.

TOTP vs WebAuthn

TOTP (RFC 6238) est vulnérable aux attaques de phishing en temps réel : un attaquant peut relayer le code TOTP dans les 30 secondes de validité. WebAuthn est immunisé car le challenge est lié à l’origine du serveur — un site de phishing ne peut pas usurper le domaine légitime dans la signature.

Autorisation#

RBAC — Role-Based Access Control#

RBAC organise les permissions autour de rôles plutôt que d’utilisateurs individuels. Les concepts fondamentaux :

  • Permission : droit d’effectuer une action sur une ressource (ex. orders:read, payments:write)

  • Rôle : ensemble nommé de permissions (ex. analyst, support, admin)

  • Hiérarchie de rôles : un rôle peut hériter des permissions d’un rôle inférieur

  • Séparation des tâches (Separation of Duties) : certaines combinaisons de rôles sont mutuellement exclusives (ex. payment_initiator et payment_approver ne peuvent pas être attribués au même utilisateur)

RBAC niveau 0 : pas de hiérarchie, pas de séparation des tâches. RBAC niveau 1 : hiérarchies de rôles. RBAC niveau 2 : contraintes de séparation des tâches. RBAC niveau 3 : hiérarchies + contraintes.

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.0)

# Simulation RBAC : matrice rôles × permissions

roles = ["viewer", "analyst", "support", "developer", "admin"]
permissions = [
    "orders:read", "orders:write", "orders:delete",
    "payments:read", "payments:write", "payments:approve",
    "users:read", "users:write", "users:delete",
    "config:read", "config:write",
    "audit:read",
]

# Matrice : 1 = permission accordée, 0 = refusée
matrix = np.array([
    # viewer, analyst, support, developer, admin
    [1, 1, 1, 1, 1],  # orders:read
    [0, 0, 0, 1, 1],  # orders:write
    [0, 0, 0, 0, 1],  # orders:delete
    [0, 1, 1, 0, 1],  # payments:read
    [0, 0, 0, 0, 1],  # payments:write
    [0, 0, 0, 0, 1],  # payments:approve
    [0, 0, 1, 1, 1],  # users:read
    [0, 0, 0, 0, 1],  # users:write
    [0, 0, 0, 0, 1],  # users:delete
    [1, 1, 0, 1, 1],  # config:read
    [0, 0, 0, 1, 1],  # config:write
    [0, 1, 0, 0, 1],  # audit:read
], dtype=float)

fig, ax = plt.subplots(figsize=(9, 7))
sns.heatmap(
    matrix,
    xticklabels=roles,
    yticklabels=permissions,
    annot=True, fmt=".0f",
    cmap="RdYlGn",
    linewidths=0.5,
    linecolor="#ecf0f1",
    vmin=0, vmax=1,
    cbar_kws={"label": "0 = refusé  /  1 = accordé"},
    ax=ax
)
ax.set_title("Matrice RBAC — Rôles × Permissions", fontsize=12, fontweight="bold")
ax.set_xlabel("Rôle", fontsize=10)
ax.set_ylabel("Permission", fontsize=10)
ax.tick_params(axis="x", rotation=0)
ax.tick_params(axis="y", rotation=0)
plt.savefig("rbac_matrix.png", dpi=120, bbox_inches="tight")
plt.show()

# Moteur d'évaluation RBAC
role_permissions: dict[str, set] = {}
for perm_idx, perm in enumerate(permissions):
    for role_idx, role in enumerate(roles):
        if matrix[perm_idx, role_idx] == 1:
            role_permissions.setdefault(role, set()).add(perm)

def check_rbac(user_roles: list[str], requested_permission: str) -> bool:
    for role in user_roles:
        if requested_permission in role_permissions.get(role, set()):
            return True
    return False

# Tests
print("check_rbac(['analyst'], 'payments:read')  →", check_rbac(["analyst"], "payments:read"))
print("check_rbac(['analyst'], 'payments:write') →", check_rbac(["analyst"], "payments:write"))
print("check_rbac(['support'], 'users:read')     →", check_rbac(["support"], "users:read"))
print("check_rbac(['viewer', 'developer'], 'config:write') →", check_rbac(["viewer", "developer"], "config:write"))
_images/70b4c00f7ae14db64a49d7ce01d8e67a9dfa540b1d01d439ff98fbf9cbca8c04.png
check_rbac(['analyst'], 'payments:read')  → True
check_rbac(['analyst'], 'payments:write') → False
check_rbac(['support'], 'users:read')     → True
check_rbac(['viewer', 'developer'], 'config:write') → True

ABAC — Attribute-Based Access Control#

ABAC évalue des politiques exprimées en termes d’attributs du sujet (utilisateur), de la ressource et de l’environnement. Plus expressif que RBAC mais plus complexe à administrer.

Exemple de politique ABAC :

ALLOW si :
  sujet.département == ressource.département
  ET sujet.clearance_level >= ressource.classification
  ET heure >= 08:00 ET heure <= 20:00
  ET sujet.pays == "FR"

Le standard XACML (eXtensible Access Control Markup Language) formalise ce type de politiques en XML, avec un modèle de décision PDP/PEP (Policy Decision Point / Policy Enforcement Point).

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.0)

# Mini-moteur ABAC : évaluation sur 10 requêtes simulées

from typing import Any

Policy = list[dict[str, Any]]

def evaluate_abac(subject: dict, resource: dict, environment: dict, policies: Policy) -> str:
    """Évalue les politiques ABAC. Retourne 'PERMIT' ou 'DENY'."""
    for policy in policies:
        if all(
            subject.get(k) == v for k, v in policy.get("subject", {}).items()
        ) and all(
            resource.get(k) == v for k, v in policy.get("resource", {}).items()
        ) and all(
            environment.get(k) == v for k, v in policy.get("environment", {}).items()
        ):
            return policy["effect"]
    return "DENY"  # deny-by-default

policies = [
    {
        "id": "P-01",
        "description": "Les managers RH peuvent lire les dossiers RH en heures ouvrées",
        "subject":     {"role": "manager", "département": "RH"},
        "resource":    {"type": "dossier_rh", "classification": "confidentiel"},
        "environment": {"heures_ouvrées": True},
        "effect":      "PERMIT",
    },
    {
        "id": "P-02",
        "description": "Les auditeurs peuvent lire tous les logs",
        "subject":     {"role": "auditeur"},
        "resource":    {"type": "log"},
        "environment": {},
        "effect":      "PERMIT",
    },
]

requests_sim = [
    ({"role": "manager", "département": "RH"}, {"type": "dossier_rh", "classification": "confidentiel"}, {"heures_ouvrées": True}),
    ({"role": "manager", "département": "RH"}, {"type": "dossier_rh", "classification": "confidentiel"}, {"heures_ouvrées": False}),
    ({"role": "auditeur"},                     {"type": "log"},                                           {}),
    ({"role": "developer"},                    {"type": "log"},                                           {}),
    ({"role": "manager", "département": "IT"}, {"type": "dossier_rh", "classification": "confidentiel"}, {"heures_ouvrées": True}),
    ({"role": "auditeur"},                     {"type": "dossier_rh", "classification": "confidentiel"}, {}),
    ({"role": "viewer"},                        {"type": "config"},                                        {}),
    ({"role": "manager", "département": "RH"}, {"type": "dossier_rh", "classification": "confidentiel"}, {"heures_ouvrées": True}),
    ({"role": "support"},                       {"type": "log"},                                           {}),
    ({"role": "developer"},                     {"type": "config"},                                        {}),
]

print(f"{'#':<3} {'Rôle sujet':<30} {'Type ressource':<20} {'Résultat'}")
print("-" * 65)
for i, (subj, res, env) in enumerate(requests_sim, 1):
    result = evaluate_abac(subj, res, env, policies)
    tag = "PERMIT" if result == "PERMIT" else "DENY  "
    print(f"{i:<3} {str(subj.get('role','?'))+'/'+str(subj.get('département','')):<30} {res.get('type','?'):<20} {tag}")
#   Rôle sujet                     Type ressource       Résultat
-----------------------------------------------------------------
1   manager/RH                     dossier_rh           PERMIT
2   manager/RH                     dossier_rh           DENY  
3   auditeur/                      log                  PERMIT
4   developer/                     log                  DENY  
5   manager/IT                     dossier_rh           DENY  
6   auditeur/                      dossier_rh           DENY  
7   viewer/                        config               DENY  
8   manager/RH                     dossier_rh           PERMIT
9   support/                       log                  DENY  
10  developer/                     config               DENY  

ReBAC — Relationship-Based Access Control#

ReBAC généralise ABAC en exprimant les permissions sous forme de relations dans un graphe. L’exemple canonique est Google Zanzibar (système d’autorisation de Google Drive, Docs, etc.).

Modèle Zanzibar :

  • Un tuple (namespace, object_id, relation, user) représente le fait que user a la relation sur object_id.

  • Les permissions sont évaluées par traversée du graphe de relations.

doc:readme#viewer@user:alice      → alice peut lire readme
folder:home#owner@user:alice      → alice possède le dossier home
doc:readme#parent@folder:home     → readme est dans home

Si folder:home#viewer est hérité par doc:readme, alors alice a implicitement viewer sur readme.

Cas d’usage : systèmes avec des structures d’objets arborescentes (documents, dossiers, projets, organisations), des équipes et des rôles dynamiques.

OpenFGA

OpenFGA (Open Fine-Grained Authorization, fondé par Auth0) est l’implémentation open-source du modèle Zanzibar. Il définit un langage de modélisation et expose une API gRPC/REST pour les vérifications d’autorisation.

IAM en pratique#

LDAP / Active Directory#

LDAP (Lightweight Directory Access Protocol) est le protocole standard de lecture/écriture dans un annuaire d’entreprise. Active Directory (Microsoft) et OpenLDAP en sont les deux implémentations majeures.

Structure LDAP (arbre DIT) :

dc=example,dc=com
├── ou=users
│   ├── cn=alice,ou=users,dc=example,dc=com
│   └── cn=bob,ou=users,dc=example,dc=com
└── ou=groups
    └── cn=devops,ou=groups,dc=example,dc=com

Les opérations clés : ldapsearch (recherche), ldapadd/ldapmodify (provisioning), ldapbind (authentification).

Keycloak#

Keycloak est un serveur IAM open-source (Red Hat) qui implémente OAuth 2.0, OIDC, SAML 2.0 et LDAP. Il propose :

  • Gestion des utilisateurs et des rôles

  • SSO entre applications

  • Fédération d’identité (LDAP, Active Directory, Google, GitHub)

  • Flows d’authentification personnalisables (MFA, passkeys, magic links)

Configuration d’un realm Keycloak (extrait JSON) :

{
  "realm": "production",
  "enabled": true,
  "sslRequired": "all",
  "registrationAllowed": false,
  "passwordPolicy": "length(14) and upperCase(1) and specialChars(1) and notRecentlyUsed(10)",
  "bruteForceProtected": true,
  "failureFactor": 5,
  "waitIncrementSeconds": 60,
  "clients": [
    {
      "clientId": "api-backend",
      "protocol": "openid-connect",
      "bearerOnly": true
    },
    {
      "clientId": "frontend-spa",
      "protocol": "openid-connect",
      "publicClient": true,
      "redirectUris": ["https://app.example.com/*"],
      "standardFlowEnabled": true,
      "pkceCodeChallengeMethod": "S256"
    }
  ]
}

OAuth 2.0 et OIDC#

OAuth 2.0 est un cadre d’autorisation (RFC 6749), non d’authentification. Il définit des flows pour obtenir des access tokens permettant d’accéder à des ressources protégées.

OpenID Connect (OIDC) étend OAuth 2.0 avec une couche d’identité : il ajoute un ID token (JWT signé) contenant des claims sur l’utilisateur (sub, email, name, etc.).

Flows principaux :

Flow

Usage

Particularités

Authorization Code + PKCE

SPA, applications mobiles

PKCE évite l’interception du code

Client Credentials

Machine-to-machine

Pas d’utilisateur impliqué

Device Authorization

TV, CLI

Affiche un code sur le device

~~Implicit~~

Déprécié

Token exposé dans l’URL

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.0)

# Diagramme de séquence Authorization Code + PKCE

fig, ax = plt.subplots(figsize=(11, 9))
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.axis("off")
ax.set_title("Flow OAuth 2.0 — Authorization Code + PKCE", fontsize=13, fontweight="bold", pad=14)

# Colonnes des acteurs
actors = {
    "Navigateur\n(SPA)":     1.5,
    "Authorization\nServer": 5.0,
    "Resource\nServer (API)":8.5,
}
colors_actors = ["#3498db", "#e67e22", "#2ecc71"]

for (name, x), color in zip(actors.items(), colors_actors):
    bbox = FancyBboxPatch((x - 0.9, 9.2), 1.8, 0.65,
                          boxstyle="round,pad=0.1", linewidth=1.5,
                          edgecolor="#2c3e50", facecolor=color, alpha=0.85)
    ax.add_patch(bbox)
    ax.text(x, 9.52, name, ha="center", va="center", fontsize=9, color="white", fontweight="bold")
    ax.axvline(x, color=color, linewidth=1, linestyle="--", alpha=0.4)

# Étapes du flow
steps = [
    (1.5, 5.0, 8.8, "1. generate code_verifier + code_challenge (S256)"),
    (1.5, 5.0, 7.9, "2. GET /authorize?client_id&code_challenge&redirect_uri"),
    (5.0, 1.5, 7.0, "3. Redirect → login page"),
    (1.5, 5.0, 6.1, "4. Authentification (login/password + MFA)"),
    (5.0, 1.5, 5.2, "5. Redirect → callback?code=AUTH_CODE"),
    (1.5, 5.0, 4.3, "6. POST /token (code + code_verifier)"),
    (5.0, 1.5, 3.4, "7. access_token + id_token (JWT)"),
    (1.5, 8.5, 2.5, "8. GET /api/resource (Authorization: Bearer <token>)"),
    (8.5, 1.5, 1.6, "9. 200 OK — données protégées"),
]

arrow_colors = ["#2c3e50"] * len(steps)
for (x1, x2, y, label), ac in zip(steps, arrow_colors):
    ax.annotate("",
                xy=(x2, y), xytext=(x1, y),
                arrowprops=dict(arrowstyle="-|>", color=ac, lw=1.4))
    mid = (x1 + x2) / 2
    va = "bottom" if x1 < x2 else "top"
    ax.text(mid, y + (0.07 if va == "bottom" else -0.07),
            label, ha="center", va=va, fontsize=7.5, color="#2c3e50")

plt.savefig("oauth_pkce_flow.png", dpi=120, bbox_inches="tight")
plt.show()
_images/1834e17ba15ed3310d4b01b80cac874786cc448edc67cf6538e4b1ae9b61565a.png

Fédération d’identités, SSO et SAML 2.0#

SSO — Single Sign-On#

Le SSO permet à un utilisateur de s’authentifier une seule fois et d’accéder à plusieurs applications sans se réauthentifier. Le protocole central est SAML 2.0 pour les applications d’entreprise, OIDC pour les applications web modernes.

SAML 2.0#

SAML (Security Assertion Markup Language) 2.0 est un standard XML de fédération d’identité entre un SP (Service Provider, l’application) et un IdP (Identity Provider, l’annuaire d’entreprise).

Flow SP-initiated :

  1. L’utilisateur accède à l’application (SP).

  2. Le SP redirige vers l’IdP avec une SAMLRequest (AuthnRequest encodée en base64).

  3. L’IdP authentifie l’utilisateur (LDAP, MFA…).

  4. L’IdP retourne une assertion SAML signée et chiffrée au SP via le navigateur (POST binding).

  5. Le SP valide la signature de l’assertion, extrait les attributs (NameID, email, groupes…) et crée une session locale.

Extrait d’assertion SAML :

<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                Version="2.0" ID="_abc123" IssueInstant="2026-03-26T10:00:00Z">
  <saml:Issuer>https://idp.example.com/saml</saml:Issuer>
  <saml:Subject>
    <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
      alice@example.com
    </saml:NameID>
    <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
      <saml:SubjectConfirmationData
        Recipient="https://app.example.com/saml/acs"
        NotOnOrAfter="2026-03-26T10:05:00Z"/>
    </saml:SubjectConfirmation>
  </saml:Subject>
  <saml:AttributeStatement>
    <saml:Attribute Name="groups">
      <saml:AttributeValue>devops</saml:AttributeValue>
      <saml:AttributeValue>audit</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>

Comptes de service et identités machines#

IRSA (AWS) et Workload Identity (GCP)#

Les comptes de service ne doivent jamais utiliser de clés statiques longue durée (fichiers JSON de clés). Les clouds modernes proposent des mécanismes d’identité éphémère basés sur OIDC :

IRSA (IAM Roles for Service Accounts) — AWS

  1. Le cluster EKS expose un OIDC endpoint.

  2. Un pod Kubernetes porte une annotation liée à un IAM Role.

  3. Le mutating webhook injecte un token OIDC dans le pod à chaque démarrage.

  4. Le SDK AWS échange ce token contre des credentials STS à durée limitée.

Workload Identity — GCP Modèle similaire : un service account Kubernetes est lié à un service account GCP via une annotation. Les tokens sont automatiquement émis et renouvelés.

Machine-to-machine OIDC Pour les services en dehors de Kubernetes (GitHub Actions, GitLab CI), un provider OIDC émet un token JWT signé décrivant le contexte d’exécution (répertoire, branche, commit). AWS, GCP et Vault peuvent valider ce token et accorder des credentials temporaires. Voir cicd/19_secrets_management.md pour les détails Vault.

PAM — Privileged Access Management#

La gestion des accès à privilèges vise à limiter et auditer les comptes administrateurs :

  • Just-in-Time Access : les droits elevés ne sont accordés que le temps d’une opération, puis révoqués automatiquement (ex. vault lease avec TTL de 1h).

  • Session recording : enregistrement des sessions SSH/RDP pour audit.

  • Break-glass accounts : comptes d’urgence sécurisés dans un coffre-fort, dont l’utilisation déclenche une alerte.

  • Least privilege : chaque compte n’a que les droits strictement nécessaires à sa fonction.

Provisioning et déprovisioning : SCIM#

SCIM (System for Cross-domain Identity Management, RFC 7643/7644) est un protocole REST standard pour automatiser le provisioning et le déprovisioning des identités entre un fournisseur d’identité (LDAP, Workday, Okta) et des applications cibles (Slack, GitHub, Google Workspace…).

Opérations principales : POST /Users (créer), PUT /Users/{id} (mettre à jour), DELETE /Users/{id} (désactiver).

Déprovisioning : l’oubli critique

Le déprovisioning — suppression ou désactivation des accès quand un employé quitte l’organisation — est aussi critique que le provisioning. Les comptes orphelins constituent une surface d’attaque majeure. SCIM automatise ce processus : lorsque l’entrée LDAP est désactivée, le système SCIM propage la désactivation à toutes les applications liées dans les minutes qui suivent.

Comparaison RBAC / ABAC / ReBAC#

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)

# Radar chart comparatif RBAC vs ABAC vs ReBAC

categories = ["Flexibilité", "Scalabilité", "Complexité\nadmin.", "Auditabilité", "Performance\néval.", "Maturité\néco."]
N = len(categories)
angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
angles += angles[:1]

models = {
    "RBAC":  [0.5, 0.8, 0.9, 0.9, 1.0, 1.0],
    "ABAC":  [1.0, 0.6, 0.3, 0.6, 0.5, 0.7],
    "ReBAC": [0.9, 0.9, 0.5, 0.7, 0.7, 0.4],
}
colors = ["#3498db", "#e67e22", "#2ecc71"]

fig, ax = plt.subplots(figsize=(7, 7), subplot_kw=dict(polar=True))
ax.set_theta_offset(np.pi / 2)
ax.set_theta_direction(-1)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(categories, fontsize=9)
ax.set_ylim(0, 1.2)
ax.set_yticks([0.25, 0.5, 0.75, 1.0])
ax.set_yticklabels(["0.25", "0.50", "0.75", "1.00"], fontsize=7)
ax.set_title("Comparaison RBAC / ABAC / ReBAC", fontsize=12, fontweight="bold", pad=20)

for (label, values), color in zip(models.items(), colors):
    vals = values + values[:1]
    ax.plot(angles, vals, color=color, linewidth=2.2, label=label)
    ax.fill(angles, vals, alpha=0.12, color=color)

ax.legend(loc="upper right", bbox_to_anchor=(1.35, 1.15), fontsize=10)
plt.savefig("iam_radar.png", dpi=120, bbox_inches="tight")
plt.show()
_images/692de8c538cad8ed5eedddfbd3dc3bd00876df4b4e6178415ce622bb5770f5d9.png

Choisir son modèle d’autorisation

  • RBAC convient à la majorité des applications B2B où les utilisateurs ont des rôles stables. Simple à auditer.

  • ABAC est pertinent quand les règles doivent tenir compte du contexte (heure, lieu, classification des données). Utilisé dans les environnements gouvernementaux et réglementés.

  • ReBAC excelle pour les systèmes avec des partages d’objets complexes (type Google Drive). OpenFGA simplifie son adoption.

  • En pratique, de nombreux systèmes combinent les trois : RBAC pour la structure de base, ABAC pour les contraintes contextuelles, ReBAC pour les permissions sur les objets partagés.

Résumé#

  1. L’authentification multi-facteurs combine des facteurs de catégories différentes (connaissance, possession, inhérence) ; WebAuthn/FIDO2 est résistant au phishing contrairement à TOTP.

  2. Les passkeys (WebAuthn synchronisé) représentent l’évolution vers une authentification sans mot de passe, reposant sur la cryptographie asymétrique et liée au domaine du service.

  3. RBAC est le modèle d’autorisation le plus répandu : permissions regroupées en rôles, hiérarchies, et contraintes de séparation des tâches. Facile à auditer.

  4. ABAC offre une expressivité maximale via des politiques sur les attributs (sujet, ressource, environnement) ; XACML formalise ce modèle en XML avec un modèle PDP/PEP.

  5. ReBAC (Google Zanzibar / OpenFGA) modélise les permissions comme des relations dans un graphe, idéal pour les systèmes de partage d’objets hiérarchiques.

  6. OAuth 2.0 + OIDC est le standard moderne pour l’autorisation et l’identité web ; le flow Authorization Code + PKCE est recommandé pour les SPA et applications mobiles.

  7. SAML 2.0 reste le standard de fédération dans les environnements d’entreprise ; les assertions signées et chiffrées permettent le SSO entre IdP et SP.

  8. IRSA et Workload Identity éliminent les clés statiques pour les charges de travail cloud : les tokens OIDC éphémères sont émis automatiquement et échangés contre des credentials temporaires.

  9. PAM et just-in-time access réduisent la surface d’exposition des comptes à privilèges : les droits élevés sont accordés pour une durée limitée et toutes les sessions sont enregistrées.

  10. SCIM automatise le provisioning et surtout le déprovisioning inter-systèmes, réduisant le risque des comptes orphelins après le départ d’un employé.