Si vous construisez des agents sur AWS dans un secteur régulé, votre équipe sécurité a probablement imposé une permissions boundary IAM sur chaque rôle que vous créez. La mienne s’appelle BoundaryForLPMA — la vôtre porte peut-être un autre nom. Le principe est le même : même avec des credentials admin, vous ne pouvez pas sortir de ce que la boundary autorise.
Bedrock AgentCore est un magnifique service dans un compte vierge. Dans un compte d’entreprise contraint par une boundary, c’est une suite de casse-têtes IAM que la documentation ne relie pas pour vous. Après avoir déployé AgentCore Runtime, Memory, Gateway, Evaluations, Registry et l’accès cross-account sous une boundary LPMA, voici les patterns que j’aurais aimé lire avant de commencer.
Pattern 1 — Le nommage des rôles est votre garde-barrière
La plupart des rôles contraints par une boundary ne délèguent la création de rôles à votre équipe que si le nom du rôle commence par un préfixe précis. Dans mon univers, c’est LPMA_*. Si vous essayez d’appeler iam:CreateRole pour un rôle nommé CrossAccount-BedrockAgent-FromProd, vous obtenez un AccessDenied qui ne mentionne pas la règle de nommage. La boundary sur votre rôle créateur d’IAM limite iam:CreateRole par Resource: arn:aws:iam::*:role/LPMA_*, et vous ne voyez pas la condition.
Convention que j’utilise désormais systématiquement :
- Rôle d’exécution du runtime :
LPMA_<App>_AgentCoreRuntime - Rôle de la Lambda dispatcher :
LPMA_<App>_AlertDispatcher - Rôle d’exécution des évaluations :
LPMA_<App>_EvaluationExecution - Invocateur cross-account (un nouveau rôle, pas un réutilisé) :
LPMA_<App>_CrossAccount<Purpose>
Choisissez un identifiant de projet (<App>) et tenez-vous-y sur tous les rôles, files, secrets, runtimes.
Pattern 2 — iam:PassRole vers le principal de service AgentCore est généralement bloqué
La politique de boundary sur un rôle d’entreprise typique n’autorise iam:PassRole que vers une liste triée sur le volet de principaux de service : ec2.amazonaws.com, lambda.amazonaws.com, ecs-tasks.amazonaws.com, etc. Le principal de service AgentCore bedrock-agentcore.amazonaws.com y figure rarement.
Conséquence pratique : un CD automatisé qui crée le runtime via votre CI ne peut pas passer le rôle d’exécution. Vous devez soit :
- Faire passer le rôle une seule fois par quelqu’un disposant de droits élevés, hors boundary ; ensuite le runtime existe et la CI se contente de lancer
UpdateAgentRuntimedessus (ce qui n’a pas besoin de PassRole). - Soit demander à la sécurité d’ajouter
bedrock-agentcore.amazonaws.comà la whitelist PassRole de la boundary.
J’ai choisi l’option 1. La CI ne crée jamais un runtime de zéro — elle fait toujours passer un runtime existant vers une nouvelle image. Le runtime lui-même est provisionné via un script à droits élevés, exécuté une seule fois.
Pattern 3 — Recréer un runtime, c’est une mise à jour à deux endroits
Si vous supprimez puis recréez un runtime (par ex. pour migrer de direct_code_deploy vers un artefact conteneur), l’ID du runtime change. Deux endroits doivent être mis à jour ensemble :
- La variable d’environnement de la Lambda (ou là où le code consommateur stocke l’ARN) — facile, facile à retenir.
- La politique IAM du rôle qui invoque le runtime, où l’ARN du runtime est restreint dans
Resource. Celle-là, on l’oublie facilement, et le symptôme est unAccessDeniedsur un runtime qui tourne parfaitement, des heures après avoir cru en avoir fini.
J’ai perdu une heure là-dessus. Maintenant, je traite la recréation d’un runtime comme une triple action : variables d’env + politique IAM + smoke test.
Pattern 4 — La policy de la clé KMS doit autoriser explicitement chaque service qui l’utilise
Les environnements de comptes régulés exigent souvent une CMK KMS dédiée au projet sur Secrets Manager, les topics SNS, les files SQS, les logs CloudWatch, les buckets S3. La policy de la clé CMK doit autoriser chaque principal de service à utiliser la clé, restreint à votre projet.
Un pattern qui marche bien pour une famille de ressources <app>-* :
{
"Sid": "AllowSNSUsage",
"Effect": "Allow",
"Principal": { "Service": "sns.amazonaws.com" },
"Action": ["kms:GenerateDataKey", "kms:Decrypt", "kms:DescribeKey"],
"Resource": "*",
"Condition": {
"StringEquals": { "aws:SourceAccount": "<your-account-id>" },
"ArnLike": { "aws:SourceArn": "arn:aws:sns:<region>:<acct>:<app>-*" }
}
}
Ajoutez un statement par service AWS pour lequel vous voulez que la CMK chiffre. Le scope aws:SourceArn est votre filet de sécurité contre le confused deputy. Sans ces statements, l’appel de création du topic SNS réussit, mais chaque Publish suivant échoue avec une erreur d’accès KMS.
Pattern 5 — La politique basée sur la ressource du runtime est le pattern cross-account le plus propre
Je ne vais pas répéter mon autre article, mais : quand l’appelant est dans un autre compte, la politique basée sur la ressource du runtime et de son endpoint vous évite de créer un rôle intermédiaire dans le compte propriétaire de la ressource. put-resource-policy est une action bedrock-agentcore-control, pas une action IAM — donc même sous une boundary qui bloque iam:CreateRole hors du namespace LPMA_*, vous pouvez attacher une politique de ressource sans négocier avec la sécurité.
Cela dit, l’ARN de ressource dans la politique de ressource doit être exact. Pas de wildcards. AgentCore valide et rejette.
Pattern 6 — Les permissions du plan de données Memory vivent dans une politique séparée
La politique d’identité du rôle d’exécution du runtime accorde généralement des actions de plan de contrôle comme bedrock-agentcore:CreateAgentRuntime. Les actions de plan de données sur Memory (bedrock-agentcore:CreateEvent, RetrieveMemoryRecords, ListEvents, etc.) sont une autre histoire. Vous les restreignez sur l’ARN de la memory de votre store :
{
"Sid": "AgentCoreMemoryEvents",
"Effect": "Allow",
"Action": [
"bedrock-agentcore:CreateEvent",
"bedrock-agentcore:GetEvent",
"bedrock-agentcore:ListEvents",
"bedrock-agentcore:RetrieveMemoryRecords",
"bedrock-agentcore:BatchCreateMemoryRecords",
"bedrock-agentcore:BatchUpdateMemoryRecords",
"bedrock-agentcore:BatchDeleteMemoryRecords"
],
"Resource": "arn:aws:bedrock-agentcore:<region>:<acct>:memory/<memory-id>"
}
Si vous oubliez ça, votre agent tourne bien mais chaque écriture LTM échoue silencieusement avec un Parameter validation failed: AccessDenied que le SDK tronque. L’agent semble fonctionner, le store de mémoire reste vide, et vous ne le remarquez que des semaines plus tard, en essayant de l’interroger.
Pattern 7 — Le rôle d’exécution des Evaluations a son propre pattern de confiance
Si vous activez AgentCore Evaluations (le scoring de qualité par LLM-juge), le service a besoin d’un rôle à assumer pour lire vos traces, invoquer les modèles juges et écrire les résultats. La trust policy est :
{
"Effect": "Allow",
"Principal": { "Service": "bedrock-agentcore.amazonaws.com" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<your-acct>",
"aws:ResourceAccount": "<your-acct>"
},
"ArnLike": {
"aws:SourceArn": [
"arn:aws:bedrock-agentcore:<region>:<acct>:evaluator/*",
"arn:aws:bedrock-agentcore:<region>:<acct>:online-evaluation-config/*"
]
}
}
}
Ce rôle nomme le service AgentCore comme principal, restreint aux ressources evaluator / online-eval-config de votre compte. Sous une boundary qui limite iam:CreateRole, vous en avez quand même besoin — et oui, le nom du rôle doit porter le préfixe conforme à la boundary.
Pattern 8 — Le chiffrement SNS n’est pas négociable
Si vous créez un topic SNS sans KmsMasterKeyId, votre scanner de sécurité (Prisma Cloud dans notre cas) le signale en HIGH dans l’heure. Attachez toujours le chiffrement KMS à la création, pas après. Le pattern que j’utilise désormais par programmation :
sns.create_topic(Name=name, Attributes={
"KmsMasterKeyId": "<your-project-cmk-id>",
})
Plus le statement AllowSNSUsage sur la policy de la clé CMK (pattern 4).
Les cinq tags à ne jamais oublier
Chaque ressource reçoit ces cinq tags, sinon elle est signalée rétroactivement :
ApplicationId— l’UUID de votre application enregistrée dans le référentiel d’actifs de l’entrepriseEnvironment—preprod/prodProject— identifiant court du projetServiceLine— votre business unitManagedBy— en général l’identifiant de votre CI/CD ou de votre équipe plateforme
Si vous oubliez les tags sur un rôle IAM, le scanner de sécurité vous le dira. Si vous oubliez les tags sur le runtime Bedrock AgentCore, ça peut prendre plus de temps à se voir — et un tag manquant sur une ressource critique a déjà conduit à mettre des programmes en pause pour revue.
Deux détails au niveau du service
- Le mode VPC est obligatoire pour tout MCP qui doit atteindre des systèmes on-prem via le TGW de l’entreprise. Le runtime peut aussi être
PUBLIC, selon qu’il parle uniquement à des API AWS publiques ou à de l’on-prem. requireServiceS3Endpointne peut pas être défini à la création de l’agent. Il se configure au niveau de l’organisation. L’API boto3 rejettera le paramètre avec uneValidationException. Laissez-le simplement hors de votre appelCreateAgentRuntime.
Le modèle mental qui relie tout
Les permissions boundaries ne sont pas votre ennemi. Ce sont une contrainte qui vous force à exprimer, dans le code, l’enveloppe de privilèges de votre application. Le coût est réel — un quart à une demi-journée de travail en plus la première fois que vous déployez AgentCore — mais le dividende, c’est un déploiement dont vous pouvez défendre la posture d’audit devant un comité de sécurité sans rien réécrire.
Les huit patterns ci-dessus couvrent ~90 % des frictions liées à la boundary que j’ai rencontrées. Les 10 % restants, c’était la négociation avec la sécurité pour ajouter bedrock-agentcore.amazonaws.com à la whitelist PassRole pour l’automatisation CI/CD. Ça vaut le coup d’insister.
Si vous démarrez un déploiement AgentCore dans un compte contraint par une boundary, épargnez-vous la course : nommez vos rôles LPMA_<App>_*, attachez KMS à la création sur tout, restreignez les actions de plan de données Memory sur l’ARN de la memory, et faites des politiques de ressource votre pattern cross-account préféré. Échangeons.