IAM
Every IAM identity is created by one of the two stacks. Neither imports an existing role.
|
|
Roles
| Role | Created by | Assumed by |
|---|---|---|
|
CDK |
|
|
CDK |
|
Five |
SAM |
|
Neither CDK role sets an explicit roleName, so CloudFormation generates physical names such
as AgentCoreStack-agentcoreRuntimeRole3DA72390-og2sjxN8EWYw. That name changes if the role
is replaced, which is why agentcore/.bedrock_agentcore.yaml pins the ARN and has to be
refreshed after a stack recreate.
No AWS managed policies are attached to either CDK role. Every permission is an inline statement.
MemoryExecutionRole
One statement, in an inline policy named MemoryPolicy:
| Actions | Resources |
|---|---|
|
|
AgentCore Memory assumes this role to run its own extraction strategies — the fact extractor, the preference extractor, and the summariser each invoke a model to condense a session. See AgentCore Memory.
agentcore-RuntimeRole
Inline policy RuntimeAccessPolicy, ten statements:
| Sid | Actions | Resources |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The default workload-identity directory and |
|
|
|
|
|
|
|
|
|
Plus a memory statement added through addToPolicy:
| Actions | Resources |
|---|---|
|
|
Three of these deserve comment.
BedrockModelInvocationspans all regions-
The foundation-model resource is
arn:aws:bedrock:*::foundation-model/*, with a wildcard region. That is required, not sloppy: theus.model ids are cross-region inference profiles, and the underlying invocation is dispatched to whichever region serves the request. Pinning it tous-east-1would break every model inAgentModelIds. CloudWatchMetricsis conditioned, not scoped-
cloudwatch:PutMetricDatacannot be restricted by resource, so the policy restricts it by condition instead — the runtime can only publish into thebedrock-agentcorenamespace. This is the correct pattern for actions with no resource-level control, and it is the only place the stack uses it. MarketplaceModelAccessgrantsSubscribe-
The runtime can subscribe the account to a Marketplace model offering, which has a billing consequence. It is present because first use of certain Bedrock models requires an implicit subscription. It is the widest grant in the policy.
SAM function roles
SAM generates one role per function from its Policies block. The policies in use:
| Policy | Effect |
|---|---|
|
|
|
|
Inline |
Scoped to |
Inline |
|
Inline |
Resource |
The SAM policy templates are resource-scoped by construction: a function that sends to
CrmSyncQueue cannot receive from it, and cannot touch EnrichmentPipelineQueue at all. The
producer/consumer topology in Queues and dead-letter queues is enforced by
IAM, not just by convention.
|
The Bedrock statements use |
Three things the functions notably do not have IAM permission for, because those systems do not use IAM: PostgreSQL (a connection string in the secret), HubSpot (an OAuth token or private app token), and BigQuery (a Google service-account JSON). Losing the AWS role does not protect any of them — see credentials.
Where the model is wide
Worth knowing, and each is a deliberate trade rather than an oversight:
| Grant | Reason |
|---|---|
|
Cross-region inference profiles |
|
First-use model subscription; has a billing effect |
|
The scraper rotates its SmartScout session token; the API cannot scope to one JSON key |
|
The runtime creates its own per-session log groups |
The corresponding narrow points are real too: every queue permission names one queue, secret reads name one secret, and memory actions name one memory ARN.
Reviewing a change
-
cdk diffprints an IAM change summary and, without--require-approval never, prompts before applying it. Read the summary — it is the only IAM review in the deploy path. -
sam deployrequiresCAPABILITY_IAM, which is set insamconfig.tomland therefore never prompts. Inspect the changeset when aPoliciesblock changed. -
Prefer a SAM policy template over an inline statement.
SQSPollerPolicycannot be accidentally over-scoped; a hand-written statement can. -
If an action supports no resource scoping, add a
Conditioninstead of accepting*.