WIKI Retour au Portfolio

Dernière mise à jour : 25 juin 2026

2 — Application Access & Managed Identities (AZ-500)

Gouvernance des identités applicatives (workload identities) dans Microsoft Entra : enterprise apps, app registrations, consentement OAuth, service principals et managed identities — l'angle « réduire la surface d'attaque des identités non-humaines ».


A. Application object vs Service principal

Distinction structurante pour toute la suite : on enregistre un application object, on consomme N service principals.

Objet Où il vit Rôle Analogie
Application object Tenant home uniquement (App registrations) Blueprint global : redirect URIs, credentials, scopes/app roles exposés, branding Classe
Service principal (SP) Chaque tenant où l'app est utilisée (Enterprise applications) Instance locale : consentements, assignations users/groupes, app role assignments Instance
Managed identity SP « spécial », sans application object, credentials gérés par Azure Instance sans classe
  • App ID (client ID) = identique pour app object + tous ses SP. Object ID = différent par objet.
  • Enregistrer une app via le portail crée app object + SP automatiquement ; via Graph API, le SP est une étape séparée.
  • Multitenant : 1 app object (chez l'éditeur) → 1 SP par tenant consommateur (créé au premier consentement).

🚨 Piège : « supprimer l'app » côté Enterprise applications = supprimer le SP (l'instance), pas l'app object. L'app object survit dans App registrations et peut recréer un SP. 🚨 Piège : une managed identity n'a pas d'application object — donc pas de redirect URI, pas de secret, pas de FIC entrant classique côté app registration.

📎 Application and service principal objects


B. App registrations — credentials & redirect URIs

Trois familles de credentials, par ordre de sécurité croissante.

Credential Secret en clair ? Rotation Verdict sécurité
Client secret Oui (string) Manuelle, expire Le pire — fuite Git/CI, expiration silencieuse
Certificate Clé privée à protéger Manuelle Mieux, mais gestion du cert
Federated identity credential (FIC) Aucun Géré par l'IdP externe Cible Zero Trust — zéro secret stocké
  • Redirect URI : doit matcher exactement la valeur déclarée (anti-token-injection). Single-tenant vs multitenant se choisit ici.
  • FIC = config de confiance OIDC : issuer + subject + audience (api://AzureADTokenExchange). Max 20 FIC par app/UAMI.
  • Le couple issuer+subject doit être unique sur l'app ; whitespace en tête/queue de l'issuer → échange bloqué.

🚨 Piège : subject mal configuré (ex. mauvais repo:org/repo:ref GitHub) → l'échange de token échoue sans erreur explicite côté IdP. 🚨 Piège : Application.ReadWrite.All permet d'ajouter un FIC à n'importe quelle app — vecteur de backdoor d'identité discret (pas de secret visible dans les logs).

📎 Add and manage application credentials 📎 FIC considerations & restrictions


C. Permission scopes — Delegated vs Application

Le cœur du modèle d'autorisation Entra. À maîtriser absolument pour l'examen.

Delegated (scopes) Application (app roles)
Contexte Au nom d'un user signé App-only, sans user
Plafond d'accès ≤ droits du user Tout ce que la permission couvre (tenant-wide)
Qui consent User (sauf admin-restricted) ou admin Admin seulement
Consentement Statique (déclaré) ou dynamique (incrémental au sign-in) Statique uniquement
Résultat (Graph) oauth2PermissionGrant appRoleAssignment
Token / flow Auth code, scopes nommés Client credentials, scope .default
  • Exposer une API (App registration → Expose an API) : Application ID URI (api://{clientId}), puis scopes (delegated) et/ou app roles (application).
  • App roles ≠ consentables par un user → seul l'admin consent aux clients d'une app exposant des app roles.
  • Durcissement : Assignment required = Yes sur l'Enterprise App → Entra n'émet de token qu'aux clients ayant un app role assigné (erreur AADSTS501051 sinon).

🚨 Piège least-privilege : le réflexe « un seul scope access_as_user / user_impersonation » = full access. Découper read/write, Resource.Read vs Resource.ReadFull. 🚨 Piège : Files.Read.All en Application = lecture de tous les fichiers du tenant ; en Delegated = seulement ce que le user voit. Même chaîne, portée radicalement différente.

📎 Permissions and consent overview 📎 Expose scopes in a protected web API


D. Consentement — admin, user, et son durcissement

Le levier de gouvernance contre les apps tierces malveillantes.

  • User consent settings (Entra > Enterprise apps > Consent and permissions) : trois niveaux —
    • Allow user consent (toutes perms non-admin),
    • Allow for verified publishers / selected low-risk permissions (recommandé),
    • Do not allow (admin consent obligatoire systématique).
  • Admin consent (tenant-wide) : Grant admin consent for [tenant] — depuis API permissions (App registrations) ou Permissions (Enterprise apps). Utilise le scope .default (statique).
  • Admin consent workflow : si user consent restreint, le user soumet une demande → reviewers notifiés → approbation/refus tracé. Config via adminConsentRequestPolicy.
  • Rôles capables d'admin consent : Cloud Application Administrator, Application Administrator, Privileged Role Administrator (selon perms).

🚨 Piège : changer les user consent settings n'affecte que les futurs consentements — les grants existants restent. Révoquer manuellement (Remove-MgOauth2PermissionGrant). 🚨 Piège : admin consent ≠ accès pour tous. Si Assignment required = Yes, seuls les users assignés accèdent malgré le consent tenant-wide.

📎 Configure how users consent to applications 📎 Overview of user and admin consent


Sujet de sécurité offensive incontournable de cette compétence.

Chaîne d'attaque : attaquant enregistre une app Entra demandant Mail.Read/Files.Read → phishing ou injection web pousse le user à consentir → l'app obtient un accès account-level OAuth aux données, sans compte dans l'org.

  • Pourquoi MFA/reset password n'aide pas : l'app détient un token OAuth, externe à l'org — ces remédiations ne révoquent pas le grant.
  • Détection : Audit log (Purview/Defender) → activité « Consent to application » ; IsAdminConsent=True inattendu = signal fort. Script Get-AzureADPSPermissions.ps1 → CSV, chercher ConsentType = AllPrincipals + perms *.All / Write.
  • Inventaire : Entra admin center (par user → Applications), myapps.microsoft.com (self), ou PowerShell (rapide, tout le tenant).
  • Remédiation : désactiver l'app (pas supprimer — elle reviendrait via un nouveau consent), révoquer oauth2PermissionGrant / appRoleAssignment.

Prévention : restreindre user consent (verified publishers + low-risk), publisher verification, app governance (Defender for Cloud Apps), Consent Insights workbook, revue hebdo des grants.

🚨 Piège : supprimer l'app malveillante ne suffit pas — un autre user peut re-consentir et la ressusciter. Disable d'abord.

📎 Detect and remediate illicit consent grants 📎 Protect against consent phishing


F. Service principals & Managed identities

Hiérarchie de préférence : Managed identity > FIC > SP avec cert > SP avec secret.

Service principals (auth app-only)

  • Pour services hors Azure ou non-supportés par MI. Authent via client credentials (.default scope).
  • Certificat > secret (MCSB IM-3.2). Rotation impérative, stockage en Key Vault.
  • Least-privilege : RBAC ciblé, pas de standing privilege global.

Managed identities

System-assigned (SAMI) User-assigned (UAMI)
Cycle de vie Lié à la ressource (auto-supprimé) Indépendant, ressource Azure à part
Réutilisation 1 seule ressource N ressources
Cas d'usage Charge éphémère, 1:1 Flotte, pré-provisionnement RBAC, CI/CD
  • Token sans credential via IMDS (endpoint local des VMs ARM). Pas de secret accessible, même à vous.
  • Authz : control plane = Azure RBAC (ARM) ; data plane = mécanisme propre à la cible (ex. Storage supporte RBAC data-plane, Key Vault = RBAC ou access policies).
  • Rotation cert automatique (~90 j expiration / ~45 j rotation). Gratuit.
  • Limites : pas de cross-tenant ; UAMI régionale (mais SP global) ; déplacement de subscription → recréer MI + réassigner RBAC.

FIC / Workload identity federation (zéro secret)

  • Cible : CI/CD GitHub Actions / Azure DevOps et workloads hors Azure (Kubernetes, autre IdP OIDC).
  • Flux : IdP externe émet token OIDC → envoyé à Entra → Entra valide issuer/subject vs FIC → émet un access token Entra.
  • Deux supports : FIC sur app registration ou sur UAMI. Pour GitHub→Azure, l'UAMI est souvent plus simple (RBAC direct).
  • Entra ne stocke que les 100 premières clés de signature de l'IdP externe.

🚨 Piège SAMI : supprimer la ressource détruit l'identité → les role assignments deviennent orphelins (GUID fantôme dans IAM). UAMI évite ça. 🚨 Piège : MI ne marche que vers des ressources supportant l'auth Entra ID. Vérifier la liste des services supportés avant de designer.

📎 What are managed identities 📎 Securing managed identities 📎 Services supporting managed identities 📎 Workload identity federation


🏢 Scénarios d'entreprise (CAF/WAF)

Scénario 1 : FinTech — Pipeline CI/CD GitHub vers Azure sans secret

Contexte business Une FinTech déploie 40+ services via GitHub Actions. Les identifiants Azure stockés dans GitHub fuient régulièrement et ne sont jamais renouvelés. L'audit PCI-DSS l'interdit.

Choix architectural Remplacer les secrets par une fédération OIDC : GitHub échange un jeton court contre un accès Azure, via une identité managée (UAMI) par environnement.

Architecture / pattern

  • 1 UAMI par environnement (dev/staging/prod), droits limités au RG cible.
  • Configurer la confiance (FIC) : on déclare quel repo/environnement GitHub a le droit de se connecter.
  • Approbateurs requis sur prod → validation humaine avant déploiement.
  • azure/login@v2 avec id-token: write ; plus aucun secret stocké.

Trade-offs assumés

  • Gain : plus aucun secret à renouveler ; chaque déploiement est tracé ; couper l'accès = supprimer la confiance.
  • Perte : la config OIDC est pointilleuse (le subject doit matcher exactement) ; les échecs sont peu explicites ; max 20 fédérations par identité.

Pièges à éviter

  • subject qui ne correspond pas à l'environnement → échec sans message clair.
  • Réutiliser l'UAMI de prod pour dev → casse l'isolation entre environnements.
  • Oublier id-token: write → GitHub n'émet pas le jeton.

📐 Réf. CAF/WAF — Workload identity federation : remplacer les credentials par une fédération OIDC élimine la classe de risque « secret exposé en CI/CD ». MCSB IM-3 — Manage application identities securely


Scénario 2 : Retail — Plateforme SaaS multi-services accédant à Key Vault et Storage

Contexte business Un retailer migre son e-commerce : App Services, Functions et AKS doivent lire des secrets (Key Vault) et des données (Storage). L'ancien code contient des connection strings en clair.

Choix architectural Des identités managées partout : SAMI (1 par ressource) pour les charges simples, UAMI (partagée) pour AKS et les workloads pré-provisionnés.

Architecture / pattern

  • SAMI sur chaque App Service/Function → droits data-plane précis (Key Vault Secrets User, Storage Blob Data Reader), jamais Contributor.
  • UAMI partagée pour le pool AKS (réutilisable par plusieurs pods).
  • DefaultAzureCredential dans le code → aucun identifiant embarqué.
  • Key Vault en mode RBAC plutôt qu'access policies.

Trade-offs assumés

  • Gain : plus de secrets dans le code ; rotation gérée par Azure ; droits fins par ressource.
  • Perte : ne fonctionne que vers des cibles compatibles Entra ; une SAMI laisse des attributions orphelines si la ressource est recréée.

Pièges à éviter

  • Donner Contributor au lieu d'un rôle data-plane ciblé → sur-privilège.
  • SAMI sur une ressource souvent recréée (IaC) → orphelins RBAC ; préférer une UAMI.
  • Une identité managée ne marche pas vers un service tiers non-Entra.

📐 Réf. CAF/WAF — Managed identities first : privilégier les identités managées élimine l'exposition de credentials pour les identités non-humaines. MCSB IM-3.1 — Use managed identity in supported Azure resources


Contexte business Un hôpital (HIPAA) subit du consent phishing : via un lien piégé, une fausse app « productivité » a obtenu l'accès aux mails et fichiers de plusieurs médecins.

Choix architectural Verrouiller ce que les utilisateurs peuvent autoriser, et industrialiser la détection/nettoyage des autorisations abusives.

Architecture / pattern

  • Consentement utilisateur limité aux éditeurs vérifiés + permissions à faible risque (sans tout bloquer, pour ne pas freiner les usages légitimes).
  • Workflow d'admin consent activé : l'équipe sécurité valide les demandes, qui expirent.
  • Revue hebdomadaire des autorisations (Defender for Cloud Apps + workbook Consent Insights).
  • Procédure incident : désactiver l'app → révoquer ses autorisations → vérifier les logs.

Trade-offs assumés

  • Gain : surface de consent phishing fortement réduite ; remédiation rapide et tracée.
  • Perte : apps légitimes en attente de validation (friction) ; charge de revue pour la sécurité.

Pièges à éviter

  • Supprimer l'app au lieu de la désactiver → l'utilisateur peut re-consentir, l'app revient.
  • Ne pas avoir activé l'audit mailbox/admin avant l'incident → impossible d'analyser après coup.
  • Croire que MFA ou reset de mot de passe corrige une autorisation OAuth (inefficace).

📐 Réf. CAF/WAF — Restrict consent & verify publishers : la restriction du consentement et la vérification d'éditeur sont des contrôles de protection des identités applicatives. CAF Secure — Govern your cloud estate securely


DEMO — chemins portail

entra.microsoft.comEntra ID > Enterprise apps > Consent and permissions > User consent settings → choisir Allow user consent for apps from verified publishers, for selected permissionsSave. Puis Admin consent settings → activer le workflow, désigner des reviewers et l'expiration des demandes.

entra.microsoft.comEntra ID > Enterprise apps > All applications → sélectionner l'app → Security > Permissions → revoir les permissions → Grant admin consent for [tenant]. (Variante App registrations → API permissions > Grant admin consent.)

3. Exposer une API avec scope + app role

Entra ID > App registrations > [app] > Expose an API > Add (Application ID URI api://{clientId}) > Add a scope (access_as_user, Who can consent: Admins and users). Puis App roles > Create app role (Allowed member types: Applications, ex. ToDoList.Read.All). Durcir : Enterprise App > Properties > Assignment required = Yes.

4. Enrôler une System-assigned MI et lui donner accès Key Vault

Sur la ressource (ex. App Service) → Settings > Identity > System assignedOn > Save (crée le SP). Puis Key Vault > Access control (IAM) > Add role assignment > Key Vault Secrets User > Managed identity > sélectionner l'App Service.

CLI :

az webapp identity assign -g rg-app -n myapp
az role assignment create --assignee <principalId> \
  --role "Key Vault Secrets User" \
  --scope $(az keyvault show -n mykv --query id -o tsv)

5. Configurer un FIC GitHub Actions sur une UAMI (OIDC, zéro secret)

Entra ID > onglet via la ressource Managed Identity (UAMI) > Settings > Federated credentials > Add Credential > scénario GitHub Actions deploying Azure resources → Organization, Repository, Entity = Environment (prod) → Name.

CLI :

az identity federated-credential create \
  --name gh-prod --identity-name uami-prod -g rg-app \
  --issuer "https://token.actions.githubusercontent.com" \
  --subject "repo:org/repo:environment:prod" \
  --audiences "api://AzureADTokenExchange"