Skip to content
TaeyoungKim.dev

AWS IAM read-only EC2 access: Why RunInstances is denied until a group allows it

SecurityWritten 3 min readTaeyoungKim
LinkedInX

You can see the EC2 instance list, but clicking “Launch instance” reports insufficient permissions. The console shows both controls, yet IAM evaluates viewing resources and creating one as different API actions. Follow one user with a read-only policy, then see what changes when a group policy is added.

Why can you list instances but not create one?

Suppose IAM user reader has only AmazonEC2ReadOnlyAccess. The current managed policy permits EC2 Describe operations but does not allow ec2:RunInstances, the operation used to launch an instance. AWS publishes the policy's default-version document.

The diagram evaluates one RunInstances request. The read-only policy supplies no matching Allow; a group's EC2 full-access policy supplies one. A matching Allow does not guarantee that every real instance launch succeeds, because other limits and request requirements can still apply.

Policies applied to readerec2:DescribeInstancesec2:RunInstances
User has only AmazonEC2ReadOnlyAccessAllowedImplicitly denied: no matching Allow
Read-only user policy plus group AmazonEC2FullAccessAllowedGroup policy has a matching Allow

The first denial does not require an explicit Deny statement. IAM generally denies a request by default when no applicable Allow exists. The action being requested matters more than which console button is visible.

What changes when a group policy is attached?

Now put reader in an ec2-operators group with AmazonEC2FullAccess. Its ec2:* Allow covers ec2:RunInstances. The user's read-only policy need not be removed: IAM evaluates the user's and group's applicable identity-based permissions together. AWS documents the full-access policy.

For this one request, the explanatory evaluation becomes:

text
Request: reader → ec2:RunInstances

Before group: User ReadOnly has no matching Allow → default deny
After group:  User ReadOnly has no matching Allow
              Group EC2 Full has ec2:* Allow → this action has an Allow

This comparison is based on published policy definitions, not a claim that an instance was launched in a live AWS account. A group Allow is not a promise of successful provisioning: resource conditions, permission boundaries, organization controls, explicit Deny statements, or a separate iam:PassRole requirement can still block the workflow.

What if AccessDenied remains after the group Allow?

First read the denied action name. Was it ec2:RunInstances or another action used during launch? Then verify the signed-in principal, group membership, attached policy, and default policy version. A similarly named user or group can lead you to inspect the wrong policy for a long time.

An applicable explicit Deny overrides an Allow. A permission boundary or AWS Organizations service control policy can further restrict what is permitted. The AWS IAM evaluation guide distinguishes default denial, explicit denial, and matching Allow. Narrow down the blocking boundary instead of attaching broader policies blindly.

AmazonEC2FullAccess makes the example easy to compare but is broad for day-to-day production access. Grant only the required actions, resources, and conditions, and prefer temporary role credentials over long-lived user keys where feasible.

Key takeaways

Being allowed to describe EC2 instances does not establish permission to launch one. Trace the denied action → user policy → group Allow → explicit Deny and other boundaries. A group policy can change the action's evaluation, but actual launch success still depends on the full request and applicable controls.

Author

TaeyoungKim

Connecting technical foundations with implementation, verification, and production decisions.

#AWS IAM#IAM policy#AmazonEC2ReadOnlyAccess#EC2 permissions#AccessDenied

Read next