Lorsque j'accompagne des équipes ou que je mène des audits de sécurité cloud, une des zones qui revient systématiquement est la gestion des permissions IAM en cross-account sur AWS. Les mécanismes d'AssumeRole, les politiques de confiance et les politiques ressources (S3, KMS, SNS, SQS, Lambda) ouvrent des portes puissantes — et parfois dangereuses — entre comptes. Dans cet article je partage ma méthode pas-à-pas pour auditer ces permissions, des commandes prêtes à l'emploi et des pistes d'analyse pour détecter et corriger les configurations risquées.

Pourquoi l'audit des permissions cross-account est essentiel

Les permissions cross-account permettent des architectures propres : centralisation des logs, délégation d'accès à des prestataires, CI/CD multi-comptes, etc. Mais elles représentent aussi une surface d'attaque : un rôle trop permissif ou une politique de confiance mal configurée peut donner accès à des ressources sensibles depuis l'extérieur. Mon objectif ici est pragmatique : vous donner une checklist opérationnelle et des requêtes pour repérer rapidement les mauvaises pratiques.

Vue d'ensemble de la méthode

Je travaille généralement en quatre étapes :

  • Inventaire : recenser rôles, policies et ressources exposées entre comptes.
  • Analyse des policies : identifier les principes trop larges (wildcards, root, comptes inconnus).
  • Recherche d'utilisation : vérifier qui assume quoi (CloudTrail / Athena).
  • Remédiation : recommandations concrètes et contrôles automatiques (IAM Access Analyzer, Config).
  • Étape 1 — Inventaire rapide des rôles et des politiques de confiance

    Commencez par lister les rôles IAM et leurs trust policies. En local, j'utilise l'AWS CLI pour récupérer les rôles et inspecter les trust policies :

    aws iam list-roles --query 'Roles[].RoleName' --output text

    Puis, pour chaque rôle :

    aws iam get-role --role-name <ROLE_NAME> --query 'Role.AssumeRolePolicyDocument' --output json

    Recherchez dans la policy de confiance :

  • Des Principals de type "AWS" avec une wildcard (\"*\")
  • Des Principals pointant sur arn:aws:iam::123456789012:root (account root)
  • Des Principals avec Federated ou des identités externes non documentées
  • Pour automatiser la détection de trusts larges :

    aws iam get-role --role-name <ROLE_NAME> --query 'Role.AssumeRolePolicyDocument.Statement[?Effect==`Allow` && Principal.AWS==`*`]'

    Étape 2 — Inventaire des ressources avec resource-based policies

    Certaines ressources ont des politiques attachées qui peuvent autoriser l'accès cross-account : S3 bucket policies, KMS key policies, SQS, SNS, Lambda resource policies. Voici comment lister quelques-unes :

  • S3 — aws s3api get-bucket-policy --bucket <BUCKET>
  • KMS — aws kms get-key-policy --key-id <KEY_ID> --policy-name default
  • Lambda — aws lambda get-policy --function-name <FUNC>
  • SQS — aws sqs get-queue-attributes --queue-url <URL> --attribute-names Policy
  • Dans ces policies, repérez :

  • Principal:\"*\"
  • Principal indiquant un autre compte (arn:aws:iam::ACCOUNT:root) sans conditions
  • Actions sensibles (kms:Decrypt, s3:GetObject, sqs:SendMessage) autorisées larges
  • Étape 3 — Analyser l'utilisation réelle (CloudTrail + Athena)

    Un rôle mal configuré n'est pas toujours exploité. CloudTrail vous permet de mesurer l'usage. J'aime déployer une table Athena sur les logs CloudTrail (ou utiliser CloudTrail Lake). Voici une requête Athena type pour repérer les Assumerole effectués depuis des comptes externes :

    SELECT eventTime, userIdentity.arn, userIdentity.accountId, eventName, requestParameters.roleArn, sourceIPAddress FROM cloudtrail_logs WHERE eventName = 'AssumeRole' AND userIdentity.accountId != '' ORDER BY eventTime DESC LIMIT 100;

    Autre requête utile pour voir qui a accédé à des clés KMS :

    SELECT eventTime, userIdentity.arn, requestParameters.keyId, eventName FROM cloudtrail_logs WHERE eventSource = 'kms.amazonaws.com' AND eventName IN ('Decrypt','GenerateDataKey') ORDER BY eventTime DESC LIMIT 200;

    Ces requêtes donnent des preuves d'usage et aident à prioriser la remédiation.

    Étape 4 — Vérifier les politiques IAM attachées aux rôles

    Un rôle peut avoir des policies inline ou gérées. Récupérez-les :

    aws iam list-attached-role-policies --role-name <ROLE_NAME>

    aws iam list-role-policies --role-name <ROLE_NAME>

    Pour chaque policy gérée, récupérez la version :

    aws iam get-policy --policy-arn <ARN> --query 'Policy.DefaultVersionId'

    aws iam get-policy-version --policy-arn <ARN> --version-id <ID> --query 'PolicyVersion.Document'

    Cherchez dans les documents :

  • Action:\"*\" combinée à Resource:\"*\"
  • Actions sensibles non restreintes (ec2:CreateSnapshot, iam:PassRole, sts:AssumeRole) sans conditions
  • Contrôles et règles à mettre en place

    Voici des contrôles pratiques que j'implémente toujours :

  • Activer et configurer IAM Access Analyzer — il détecte les ressources partagées cross-account et fournit des findings exploitables.
  • Configurer AWS Config rules — par exemple managed rule iam-password-policy, but also custom rules pour trust policies.
  • Restreindre les Principals dans les trust policies : préférer une liste d'ARNs d'identités spécifiques plutôt que l'account root ou \"*\".
  • Ajouter des conditions sur sts:ExternalId, aws:PrincipalOrgID ou aws:SourceAccount pour lier le trust à des contextes précis.
  • Surveiller les usages avec CloudWatch Events / EventBridge et déclencher alerts pour AssumeRole depuis comptes inconnus.
  • Exemples de patterns risqués et de remédiation

    Pattern risqué : trust policy autorisant tout le compte externe sans condition

    “Principal”: { “AWS”: “arn:aws:iam::123456789012:root” }

    Remédiation : remplacer par un ARN de rôle précis ou ajouter une condition :

    Condition: { "StringEquals": { "aws:PrincipalOrgID": "o-xxxxxxxx" } }

    Pattern risqué : S3 bucket policy avec Principal:\"*\" et PutObject

    Remédiation : utiliser des conditions basées sur aws:SourceAccount ou sur VPC endpoints, ou limiter le Principal à des rôles/ARN identifiés.

    Pièges courants

    Quelques erreurs que je vois souvent :

  • Pensée que "compte X a accès" est acceptable — mais le root du compte X autorise potentiellement toutes les identités de ce compte.
  • Absence de conditions : ExternalId pour les prestataires non vérifiés, PrincipalOrgID pour les membres d'une organisation.
  • Ignorer les resource-based policies : on vérifie souvent les roles IAM mais pas les policies S3/KMS/Lambda.
  • Outils complémentaires

    En plus de l'AWS CLI et d'Athena, j'utilise :

  • IAM Access Analyzer (console & findings API)
  • AWS Config (rules et snapshots)
  • CloudTrail Lake pour requêtes ad hoc sur les événements
  • Outils tiers : Prowler, ScoutSuite, ou des scanners internes pour automatiser les checks réguliers
  • Enfin, lors d'un audit, documentez chaque risque avec preuve (extraits de policy, logs CloudTrail) et proposez une remédiation testable. Les bonnes pratiques se renforcent quand on peut démontrer l'impact et valider la correction par des tests d'usage contrôlé.

    Si vous le souhaitez, je peux vous fournir un script bash/CLI qui itère sur tous vos rôles, récupère les trust policies et génère un rapport CSV des trusts cross-account — dites-moi quel niveau d'automatisation vous voulez et je vous lève une version prête à exécuter.