security

AWS IAM

The execution role a Lambda, EC2 instance, or API Gateway integration assumes to call other AWS services — no hardcoded access keys. Here's what an IAM role is, how it connects to your compute, the difference between trust and permissions policies, and the mistakes Design Beaver catches as you draw.

Updated July 12, 2026

What IAM is

IAM governs who can do what in your AWS account. On an architecture diagram the piece that matters most is the role: an identity a compute principal assumes to get short-lived, automatically-rotated credentials scoped to a specific set of actions. A Lambda execution role is the identity a function runs as; an EC2 instance profile passes a role to an instance; an API Gateway integration role is what the API assumes to call a service directly. In every case the principal reads temporary credentials the platform keeps refreshed, so you never embed access keys.

Design Beaver models IAM as the execution role or instance profile you attach to a compute principal — a global, account-level node with no VPC or subnet. It validates as you draw which principals a role can grant and what each connection needs to be correct.

When to use IAM (and when not to)

Reach for an IAM role any time a compute principal calls another AWS service. The call needs a role, and putting it on the canvas makes the required permissions explicit — reviewers can see exactly which actions a Lambda or EC2 instance is granted. Use it to scope a principal down to only the actions it actually uses, which is what least privilege means in practice.

Don’t reach for IAM to solve a network problem. Security groups, subnets, and routing govern packet flow; IAM governs API-level authorization, and the two are separate. Granting dynamodb:GetItem does nothing for reachability. It’s also the wrong model for resource-based access into a principal — an S3 bucket invoking a Lambda uses a resource policy on the Lambda, not the function’s execution role.

How IAM connects to other services

An IAM role attaches to the principal that assumes it — a Lambda, an EC2 instance, or an API Gateway doing a direct service integration — and the arrow reads “provides the role for.” Attaching it clears the execution-role warnings on that principal’s outbound connections all at once, and the connection detail panel generates the concrete policy: per connected resource, the exact actions the role should grant, straight from the knowledge base. Design Beaver models each of these edges, so it knows what a role can attach to and what that role has to cover.

  • Provides the Lambda function's execution role — the identity it assumes to call other AWS services, scoped to the actions its connections require

  • EC2

    Provides the EC2 instance profile/role — the identity applications on the instance assume to call AWS services without stored access keys

  • Provides the IAM role API Gateway assumes for a direct AWS service integration — e.g. calling DynamoDB straight from the API with no Lambda in between

If you attach the role to a data resource like DynamoDB or S3 instead of a principal, that’s a modeling mistake — the access is granted through the principal’s role, so the role belongs on the Lambda or EC2, not the table or bucket. Design Beaver points you back to the right target rather than letting the edge stand.

Gotchas that bite in production

  • Trust policy and permissions policy are separate — and both must be right. A role’s permissions policy says what it can do; its trust policy says who’s allowed to assume it. A role that grants dynamodb:GetItem still fails if its trust policy doesn’t let the principal assume it — for a Lambda execution role, the trust policy has to name lambda.amazonaws.com.
  • Don’t store access keys on an EC2 instance. The whole point of an instance profile is that the SDK pulls short-lived credentials from the Instance Metadata Service automatically, and AWS rotates them. Baking long-lived keys into the AMI or app config is the anti-pattern the role exists to remove — and those keys don’t rotate.
  • Prefer IMDSv2. Applications read instance credentials over IMDS, and IMDSv2’s session-token requirement hardens that endpoint against SSRF-style credential theft. Treat IMDSv1-only as a finding, not a default.
  • Action: "*" / Resource: "*" defeats the purpose. A wildcard policy is easy to write and impossible to reason about. Least privilege means listing the specific actions the principal calls on the specific resources it touches — exactly what the generated policy on the canvas shows you.
  • A role is not a network path. If the target lives in a VPC — an RDS database, a private service — the principal still needs network access on top of the IAM permission: security groups, subnets, VPC attachment. The role authorizes the API call; it doesn’t move the packet.

Further reading

Frequently asked questions

When should you use an IAM role?
Use an IAM role any time a compute principal — a Lambda function, an EC2 instance, or an API Gateway direct integration — calls another AWS service. The role is the identity that principal assumes to get temporary, auto-rotated credentials scoped to the actions it needs, instead of hardcoded access keys. It's not the tool for network-level reachability (that's security groups and subnets), and it's not what grants a service access into a principal — an S3 bucket invoking a Lambda uses a resource policy on the Lambda, not the function's execution role.
How much does AWS IAM cost?
IAM itself is free. There's no charge for roles, policies, or the temporary credentials AWS STS issues for them. You pay only for the resources your principals actually access.
Can an IAM role connect directly to DynamoDB or S3?
No — not the way you'd draw it. A role attaches to the principal that assumes it (a Lambda, EC2 instance, or API Gateway integration), and that principal's connections grant access to DynamoDB or S3 through the role. Drawing IAM straight to a table or bucket is a modeling mistake, and Design Beaver points you back to attaching the role to the principal instead.
Does a Lambda function need an IAM role to call DynamoDB?
Yes. A Lambda function calls DynamoDB, S3, or any other AWS service through its execution role — the identity it runs as. The role's permissions policy lists the specific actions it can take (like dynamodb:GetItem), and its trust policy lets lambda.amazonaws.com assume it. Attach an IAM role to the function in Design Beaver and the per-connection execution-role warnings clear.

Validate your IAM Role architecture as you draw

Design Beaver checks your AWS design in real time — missing queues, invalid connections, and security anti-patterns, caught before you ship. It’s live in beta, free, and runs in your browser with no account.

Open the app →

Prefer email? Get new features in your inbox:

← All supported services