AWS IAM Explained: Users, Roles, Policies and Access

AWS 9 min readPublished 31 August 2026

Quick answer

Learn how AWS IAM users, roles and policies control access. Follow practical CLI examples, least-privilege methods and troubleshooting steps.

AWS Identity and Access Management (IAM) controls who can access AWS resources and what actions they can perform. This guide has AWS IAM explained through practical examples covering users, roles, policies, permission evaluation and least privilege.

What Is AWS IAM?

AWS IAM is the global AWS service used to manage identities and permissions within an AWS account. It authenticates principals such as users and roles, then authorises or denies their requests according to applicable policies.

IAM itself does not create application users for your website. It controls administrative and programmatic access to AWS services and resources.

Important IAM characteristics include:

  • IAM is a global service, not a regional service.
  • New AWS accounts include a root user with unrestricted account access.
  • IAM permissions deny requests by default.
  • An explicit Deny overrides an Allow.
  • IAM roles provide temporary credentials through AWS Security Token Service (STS).
  • IAM policies are JSON documents describing allowed or denied actions.

Use the root user only for tasks that specifically require it. Protect it with multi-factor authentication (MFA), do not create root access keys, and use an administrative role or federated access for regular work.

IAM request flow: a diagram in words

Visualise IAM as a security checkpoint:

Person or workload
        |
        v
Authentication: Who are you?
        |
        v
Principal: IAM user, assumed role or AWS service
        |
        v
Authorisation: Which policies apply?
        |
        v
Decision: Explicit deny, allow or implicit deny
        |
        v
AWS resource: S3 bucket, EC2 instance, DynamoDB table, etc.

Authentication establishes an identity. Authorisation evaluates whether that identity can perform a particular action on a particular resource under the request conditions.

What Is the Difference Between IAM Users and Roles?

An IAM user is a long-term identity in one AWS account, while an IAM role is an assumable identity that supplies temporary credentials. Roles are normally the safer choice for applications, AWS services, federation and cross-account access.

FeatureIAM userIAM role
Credential typePassword or long-term access keysTemporary STS credentials
Typical useLimited human or legacy accessWorkloads, federation and cross-account access
Direct sign-inCan have a console passwordAssumed through a trusted identity or service
Credential rotationAccess keys require managementCredentials expire automatically
Trust policyNot usedRequired
Recommended for EC2 applicationsNoYes, through an instance profile

When should an IAM user be used?

Use IAM users only when a workload or person cannot use federation or roles. For workforce access, AWS IAM Identity Center is generally preferable because it provides centrally managed access and temporary credentials.

An IAM user can have:

  • A console password
  • Up to two access keys, although unused keys should be removed
  • MFA devices
  • Identity-based policies attached directly or through groups

Do not place access keys inside source code, container images or public repositories. Where long-term keys are unavoidable, store them securely, monitor their use and rotate them according to your organisation's process.

When should an IAM role be used?

Use a role when an application, AWS service, federated user or another AWS account needs temporary access. A role has a trust policy defining who may assume it and permission policies defining what the resulting role session may do.

Examples include:

  • An EC2 application reading an S3 bucket
  • A Lambda function writing logs to CloudWatch Logs
  • A deployment pipeline updating an ECS service
  • An administrator accessing a production account from a central identity account
  • A user signing in through IAM Identity Center

These patterns are covered through guided labs in the AWS Solutions Architect course, including role-based access for common AWS architectures.

How Do IAM Policies Work?

An IAM policy is a JSON document containing permission statements. Each statement normally specifies an effect, one or more actions, resources and optional conditions.

Consider this identity-based policy for an application that must read objects from one S3 prefix:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadReportsPrefix",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": "arn:aws:s3:::company-reports/monthly/*"
    }
  ]
}

This permits s3:GetObject only for objects below monthly/. It does not allow bucket listing, uploads, deletions or reads from another prefix.

To list that prefix, a separate bucket-level permission is required because s3:ListBucket applies to the bucket ARN:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListMonthlyReports",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::company-reports",
      "Condition": {
        "StringLike": {
          "s3:prefix": [
            "monthly/*"
          ]
        }
      }
    },
    {
      "Sid": "ReadMonthlyReports",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::company-reports/monthly/*"
    }
  ]
}

What are the main types of IAM policies?

AWS evaluates several policy types depending on the identity, account structure, resource and request. Understanding their different purposes prevents incorrect assumptions about effective access.

Policy typeAttached to or used byPurpose
Identity-based policyUser, group or roleGrants permissions to an identity
Resource-based policyResource such as an S3 bucket or KMS keyDefines which principals can access the resource
Permissions boundaryUser or roleSets the maximum permissions an identity-based policy can grant
Service control policyAWS Organizations account or organisational unitLimits maximum permissions in member accounts
Session policyRole or federated sessionFurther restricts a temporary session
Access control listSupported resources such as S3 objectsProvides resource-level access in specific services

AWS-managed policies are maintained by AWS. Customer-managed policies are created and managed within your account, while inline policies are embedded directly in one identity. Customer-managed policies are usually easier to review, version and reuse than inline policies.

How Does AWS Evaluate IAM Permissions?

AWS begins with an implicit deny, looks for applicable allows and then checks for explicit denies. An explicit deny in any applicable policy takes precedence over an allow.

A practical decision sequence is:

Request received
  -> Is there an applicable explicit Deny? Yes: Deny
  -> Is there an applicable Allow? No: Implicit Deny
  -> Do boundaries, session policies or SCPs limit it? Yes: Deny
  -> Do all required policy checks permit it? Yes: Allow

For permissions granted through identity-based policies, effective permissions are broadly the intersection of identity policies, permissions boundaries, session policies and applicable service control policies. Resource-based policies and role trust policies add further checks, especially for cross-account access.

A role's trust policy does not grant access to S3, EC2 or other services. It only defines which principal can call an operation such as sts:AssumeRole for that role.

How Do You Create and Assume an IAM Role?

Create a role by defining its trusted principal, attaching only the required permissions and assuming it through STS. The following lab creates a role trusted by a specific IAM user for demonstration purposes.

Create trust-policy.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:user/lab-user"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Create the role:

aws iam create-role \
  --role-name ReportsReadRole \
  --assume-role-policy-document file://trust-policy.json

Save the S3 policy from the previous section as reports-read-policy.json, then create and attach it:

aws iam create-policy \
  --policy-name ReportsReadPolicy \
  --policy-document file://reports-read-policy.json

aws iam attach-role-policy \
  --role-name ReportsReadRole \
  --policy-arn arn:aws:iam::111122223333:policy/ReportsReadPolicy

The calling user also needs permission to run sts:AssumeRole against this role. After both sides are configured, assume it:

aws sts assume-role \
  --role-arn arn:aws:iam::111122223333:role/ReportsReadRole \
  --role-session-name reports-lab

The output contains an access key, secret access key, session token and expiration time. Configure these as environment variables for the lab shell:

export AWS_ACCESS_KEY_ID="temporary-access-key"
export AWS_SECRET_ACCESS_KEY="temporary-secret-key"
export AWS_SESSION_TOKEN="temporary-session-token"

aws sts get-caller-identity

Expected identity output includes an ARN similar to:

arn:aws:sts::111122223333:assumed-role/ReportsReadRole/reports-lab

The assumed-role ARN confirms that the shell is using a role session rather than the original user. For production automation, use an AWS SDK credential provider instead of manually copying temporary credentials. Engineers building deployment systems can study related role and pipeline patterns in the AWS DevOps course.

What Does Least Privilege Mean in AWS IAM?

Least privilege means granting only the actions, resources and conditions required for a task. Permissions should be reviewed and reduced as actual usage becomes clear rather than remaining broad indefinitely.

A weak policy might use:

{
  "Effect": "Allow",
  "Action": "s3:*",
  "Resource": "*"
}

A least-privilege design asks four questions:

  1. Which exact API actions are required?
  2. Which resource ARNs should those actions target?
  3. Can conditions restrict location, network path, tags or identity context?
  4. How long is the access needed?

Useful controls include:

  • Require MFA for sensitive human actions with aws:MultiFactorAuthPresent.
  • Restrict access by resource tags using supported condition keys.
  • Use aws:SourceArn and aws:SourceAccount when an AWS service assumes or invokes access on behalf of a resource.
  • Use VPC endpoint conditions only after confirming the operational impact.
  • Separate read, deploy and administrative roles.
  • Remove permissions that IAM Access Analyzer identifies as unused after suitable observation and review.
  • Use permissions boundaries for delegated IAM administration.
  • Use SCPs as organisation-wide guardrails, not as permission grants.

Avoid blindly generating policies from console actions. The console may call supporting read and list APIs, while automation may need a smaller or different permission set.

Security teams also need to connect IAM activity with logs, alerts and incident response. These operational controls are introduced in the Cybersecurity & SOC course.

How Can You Validate and Test an IAM Policy?

Validate policy syntax before deployment, then test expected allowed and denied actions in a non-production environment. Policy simulation is helpful, but a real service call is still important because resource policies, service-specific behaviour and runtime context can affect the result.

Validate an identity policy with IAM Access Analyzer:

aws accessanalyzer validate-policy \
  --policy-document file://reports-read-policy.json \
  --policy-type IDENTITY_POLICY

Simulate selected actions for an IAM role:

aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::111122223333:role/ReportsReadRole \
  --action-names s3:GetObject s3:DeleteObject \
  --resource-arns arn:aws:s3:::company-reports/monthly/report.csv

Review the EvalDecision field. In this example, s3:GetObject should be allowed and s3:DeleteObject should not be allowed, assuming no other relevant policies change the decision.

Then run a real test:

aws s3api get-object \
  --bucket company-reports \
  --key monthly/report.csv \
  /tmp/report.csv

Also test a request that should fail. Negative tests confirm that the policy prevents unintended access rather than merely supporting the expected path.

How Do You Troubleshoot IAM Access Denied Errors?

Start by identifying the current principal, denied API action and target resource ARN. Then inspect every relevant policy layer instead of repeatedly adding broader permissions.

Step 1: Confirm the active identity

aws sts get-caller-identity

A common problem is using an unexpected CLI profile, stale environment variables or an EC2 role different from the intended role.

Step 2: Capture the exact denied operation

Run the command with debug logging if necessary:

aws s3api get-object \
  --bucket company-reports \
  --key monthly/report.csv \
  /tmp/report.csv \
  --debug

Debug output can be extensive and may contain request metadata. Store and share it carefully.

Step 3: Check action and resource matching

Confirm that the policy uses the correct API action and ARN format. For S3, bucket operations often require a bucket ARN, while object operations require an object ARN ending in /* or a narrower object path.

Step 4: Check every restricting policy layer

Review:

  • Identity-based policies
  • Resource-based policies
  • Role trust policy for assumption failures
  • Permissions boundaries
  • Session policies
  • AWS Organizations SCPs
  • KMS key policies when encrypted data is involved
  • VPC endpoint policies where applicable

An S3 policy may allow s3:GetObject, but an object encrypted with a customer-managed KMS key can also require kms:Decrypt and permission through the key policy.

Step 5: Inspect CloudTrail events

Search AWS CloudTrail event history or your CloudTrail Lake/event data store for the denied API request. Check userIdentity, eventSource, eventName, requestParameters and errorMessage to understand which principal made the request and what it attempted.

Common IAM problems

SymptomLikely causePractical check
AccessDenied on AssumeRoleCaller permission or trust policy missingCheck both sides of role assumption
S3 list works but download failss3:GetObject missingCheck the object ARN and action
S3 download allowed but KMS deniesKMS permission or key policy missingReview kms:Decrypt and the key policy
Policy says allow but request failsExplicit deny, boundary or SCPInspect all applicable policy layers
CLI uses the wrong accountWrong profile or environment credentialsRun aws sts get-caller-identity
Temporary credentials suddenly failSTS session expiredRefresh or assume the role again

Do not resolve access errors by attaching AdministratorAccess unless full administration is genuinely required. It can hide the original design problem and grant unrelated capabilities.

Summary

AWS IAM provides authentication and authorisation for AWS accounts through users, roles and policies. Prefer temporary role credentials, protect root access, test both allowed and denied actions, and reduce permissions to the minimum required actions and resources.

A reliable IAM workflow is: identify the principal, define the task, write a narrow policy, validate it, test it in a safe environment, inspect logs and review permissions regularly.

To practise IAM, STS, S3 permissions and secure architecture through guided labs, enquire about upcoming batch details for the AWS Solutions Architect course.

Reviewed by Network Rhinos AWS and cloud trainers.

Related reading: Terraform Basics for AWS: Build Your First Resource

Frequently asked questions

Is AWS IAM a global or regional service?

AWS IAM is a global service. IAM users, groups, roles and policies are created at the AWS account level rather than separately in each Region, although their permissions can target regional resources.

What is the main difference between an IAM user and an IAM role?

An IAM user is a long-term identity that can have a password or access keys. An IAM role is assumed when needed and provides temporary STS credentials, making it preferable for workloads, federation and cross-account access.

Does an IAM role trust policy grant access to AWS resources?

No. A trust policy defines which principals can assume the role, while permission policies define what an assumed role session can do with AWS resources.

Does an explicit deny override an allow in AWS IAM?

Yes. If an applicable policy contains an explicit deny for the request, it overrides applicable allows. Without an applicable allow, the request is denied implicitly.

Should applications store AWS access keys in configuration files?

No. Applications running on AWS should normally use roles and temporary credentials delivered through the AWS credential provider chain. Long-term keys in files or source repositories create avoidable exposure and rotation problems.

Why does S3 return AccessDenied when the IAM policy allows access?

Another control may be blocking the request, such as a bucket policy, SCP, permissions boundary, VPC endpoint policy or KMS key policy. Confirm the caller with `aws sts get-caller-identity`, verify the action and resource ARN, and inspect the related CloudTrail event.

Related articles

Train with Network Rhinos

Hands-on CCNA, CCNP, AWS, Azure, DevOps and cybersecurity training in Chennai & Bangalore, with placement support. Talk to our team or attend a free demo class.