A developer thinks before running an AWS command. An AI coding agent runs whatever command it believes the task requires. That gap is where your IAM policy either holds the line or doesn’t.
The security boundary has to exist outside the model. Here is how to build it.
️ Start With a Capability Matrix, Not a Policy
Before writing a single IAM statement, define what the agent actually needs to do. An agent reviewing a .NET application may need to read repository files, run dotnet build, run dotnet test, and read application logs. It does not need to delete databases, modify IAM, or touch production networking.
Map every capability to a required/not-required column and a risk level before you open the IAM console. That matrix becomes the source of truth for the policy.
Separate Coding Permissions From Deployment Permissions
This is the single highest-leverage architectural decision. A coding agent may need to build, test, read logs, and inspect configuration. None of that requires deployment authority. Use separate roles:
- AI-Coding-Role: repository access, build and test resources, limited read-only cloud access
- Deployment-Role: deployment and infrastructure permissions, not available to the coding agent by default
The deployment role should not become available just because the agent can execute shell commands.
Restrict Both Actions and Resources
Resource-level restrictions alone are not enough. An agent that needs to read objects from a specific S3 bucket needs s3:GetObject scoped to that bucket’s ARN. It does not need s3:DeleteObject, s3:PutBucketPolicy, or s3:DeleteBucket.
The policy design principle is: required action plus required resource plus required scope. Avoid wildcards when the resource can be identified precisely.

⚠️ Treat iam:PassRole as High Risk
Broad IAM permissions are an obvious problem. The less obvious one is iam:PassRole. If an agent can create or modify resources and pass a highly privileged role to those resources, its effective authority becomes much larger than the policy statement suggests. Restrict iam:PassRole to specific roles where it is genuinely required and review it like you would production infrastructure.
Similarly, lock down sts:AssumeRole. If an agent only needs to assume one or two roles, name them explicitly in the policy rather than allowing assumption against *.
Build a Permission Usage Baseline Iteratively
Don’t guess at every required permission upfront. Start with a broader but controlled policy in a non-production environment, run representative agent tasks, and collect the API actions actually used via AWS audit logging. Then remove everything that never appeared. Repeat the cycle until the policy reflects real usage, not assumptions.
Also test from the other direction. Verify that dangerous operations like deleting an S3 bucket, modifying an IAM role, or assuming a production-admin role actually produce a denial. A policy that looks restrictive on paper should prove it adversarially.
Consider Account Separation for High-Risk Workloads
For workloads where the blast radius concern is high, account separation provides a stronger boundary than IAM alone. The coding agent operates in a development account with meaningful permissions there but has no direct access to the production account. Even a destructive command stays contained.

Store IAM Policies in Version-Controlled Infrastructure Code
Don’t hand-create AI agent IAM policies in the console and leave them undocumented. Store them in version-controlled infrastructure code alongside the rest of your stack. An AI-generated pull request that changes application code is worth reviewing carefully. One that changes IAM deserves even more scrutiny.
When reviewing an IAM change, ask: why is this permission required, can the resource ARN be narrowed, does this enable role assumption, and does it affect production? Don’t approve IAM changes just because the agent failed without them.
The Core Principle
IAM is one enforcement layer, not the only one. The overall security boundary also requires tool restrictions, secret management, network controls, and deployment controls. But the IAM design sets the floor. The goal is a boundary strong enough that an incorrect command, a hallucinated infrastructure change, or a compromised tool cannot exceed the authority required for the job.
