Non-human identities already outnumber human ones in a typical AWS account, and Amazon Bedrock is minting more of them every week — every agent and knowledge base runs under a service role you create, each one a principal with standing permissions. Here is the part that should change how you review them: Bedrock supports no resource-based policies. There is no policy you can attach to a model or an agent to catch a bad grant, no second wall behind a mistake on the identity side. Whether a principal can invoke a model or rewrite an agent is decided entirely by the policies attached to that principal. The identity chain is not part of the control surface. It is the whole control surface.
Bedrock removes the safety net you rely on everywhere else
On S3, an over-broad identity policy can still be stopped by a restrictive bucket policy. On KMS, the key policy has the final say. Those resource-side controls are the reason a single mistake on the identity side is usually survivable — something else gets a vote. Per the AWS IAM documentation, Bedrock has none of that: no resource-based policies, no ACLs, no resource-side control that could veto an over-broad grant. What a principal can do to a model or an agent comes down to its identity policies, the SCPs above it, and the conditions on the request, and nothing else.
That is an unusually clean problem for identity-side analysis to own. There is no second policy layer to reconcile, no question of whether the bucket policy or the IAM policy wins. The question of who can invoke a given model resolves from the same chain Whocan already evaluates for human users — identity policies, permission boundaries, SCPs, and conditions — to the decision AWS itself would make.
Three questions to ask about every agent
Bedrock agents run under customer-managed service roles: IAM roles you create and hand to the agent. AWS warns against editing them casually, because changing their permissions can break the agent — but nothing warns you about a role that was over-granted the day it was created. These three questions give every agent role a list it can be reviewed against.
Who can invoke Bedrock models?
There is no model-side policy to backstop you. This is the full set of principals, human and non-human, that can reach a model — computed from identity policies, SCPs, and conditions alone.
who-can(
action: "bedrock:InvokeModel"
)Which agent roles have human-grade privileges?
An agent role should be scoped to the few actions its task needs. Any agent that computes to admin, or holds a privilege-escalation sequence, is a non-human identity with far more reach than its job requires.
agent-roles = roles where self.Tags has (
self.Key == "workload" & self.Value == "ai-agent"
)
admin-agents = agent-roles
where self.Entitlements.Abilities includes "iam-admin"
privesc-agents = agent-roles
where self.Entitlements.Abilities includes "iam-privilege-escalation"
admin-agents union privesc-agentsWho can both rewrite and run an agent?
AWS splits the Agents API into a build-time plane and a runtime plane. A principal holding both can rewrite the action group an agent runs, then trigger it — inheriting everything that agent role can do. It is the Lambda-code-injection pattern, moved to agents.
agent-builders = who-can(
action: "bedrock:UpdateAgentActionGroup"
)
agent-invokers = who-can(
action: "bedrock:InvokeAgent"
)
agent-builders where self in agent-invokersSame engine, new principals
Each of these runs through the identical authorization chain Whocan uses for human IAM — every SCP, every condition, every role hop. An agent that can read a production secret, a service role that quietly computes to admin, a build-plus-runtime toxic combination: all of them are standing facts, knowable before the agent makes its first call. Save any of these as a monitor and the answer is re-checked on every refresh.
AWS tells you to build the wall. It cannot tell you if there is a door.
The Bedrock hardening guidance is good and worth following. Route model and agent traffic through PrivateLink interface endpoints; scope those endpoints with a policy that allows only the actions you intend; and for model-customization jobs, lock the training-data buckets behind a Deny-unless-it-comes-from-your-VPC bucket policy keyed on aws:sourceVpc. Each of those is a wall.
A wall is only as good as the absence of a door around it. The question worth asking is not whether you wrote the Deny policy — it is whether any principal still reaches this bucket from outside the VPC, through a path the policy did not anticipate. That is conditional and context-dependent: it turns on the source VPC, on which role is asking, on the conditions attached at every layer in between. Source-VPC, MFA, and request context are exactly what who-can factors in, so whether the wall actually holds is something you can ask directly instead of inferring from the policy text.
The takeaway
An AI agent is not just a feature you ship — it is an IAM principal you create, with standing access that outlives any single request. Treat it like one. Before it makes its first call, ask what its role can reach, whether anyone can rewrite and re-run it, and whether the perimeter you drew around its data actually holds. Bedrock gives you no resource-side net to catch these later; the identity side is where the question lives, which makes it where the answer is too.