Role-based access control in AWS IAM: Principle of least privilege done right

The most common AWS security misconfiguration is not an unpatched vulnerability or a missing firewall rule. It is overpermissioned IAM identities: users with AdministratorAccess who only needed S3 read access, service accounts with wildcard permissions applied to every resource, long-lived access keys that were never rotated because rotating them is inconvenient.

Role-based access control in AWS IAM is the framework that prevents this. Permissions attach to roles, not to individual users. Roles are designed around what a job function needs, not what it might conceivably ever need. This guide covers how to implement RBAC correctly in AWS, including the components that most organisations get wrong.

IAM roles vs IAM users: the right mental model

IAM users represent a human identity with long-lived credentials: a username, password, and optionally access keys. IAM users are appropriate for very limited use cases, primarily interactive console access for human administrators who cannot use federated identity.

IAM roles represent an identity that can be assumed temporarily. Roles have no long-lived credentials: when a role is assumed, AWS issues temporary credentials valid for the session duration (15 minutes to 12 hours). When the session ends, the credentials expire. No rotation required; no stale credentials to revoke.

Use roles for: - EC2 instances, Lambda functions, ECS tasks, and all compute workloads that need AWS API access - Human access via an identity provider (Okta, Active Directory via IAM Identity Center) - Cross-account access (a role in Account A that Account B's principals can assume) - AWS services that need to act on your behalf (CloudFormation, CodePipeline, etc.)

The goal is to have zero IAM users with long-lived access keys in a production environment. Every AWS API call should be made with temporary credentials obtained by assuming a role.

Trust policies: who can assume the role

Every IAM role has two components: a trust policy and one or more permission policies.

The trust policy (also called the assume-role policy) defines who or what is permitted to assume the role. It is a JSON document in the Principal field that specifies the allowed principals.

An EC2 instance role trust policy:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }]
}

A cross-account role trust policy (Account B assuming a role in Account A):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": "arn:aws:iam::ACCOUNT_B_ID:root"},
    "Action": "sts:AssumeRole",
    "Condition": {
      "Bool": {"aws:MultiFactorAuthPresent": "true"}
    }
  }]
}

Adding a Condition requiring MFA in the trust policy means the role can only be assumed after MFA verification. For sensitive roles (production administration, security operations), MFA conditions on the trust policy are a meaningful security control.

Permission policies: what the role can do

Permission policies define which AWS API actions the role can take and on which resources. AWS provides two types:

AWS managed policies are pre-built by AWS and cover common job functions: ReadOnlyAccess, PowerUserAccess, AdministratorAccess, and dozens of service-specific policies. They are convenient but broad. ReadOnlyAccess grants read access to nearly every AWS service, which is more than most roles need.

Customer managed policies are policies you write and maintain. They are specific to your use case, which means they can implement least privilege precisely. A policy that grants s3:GetObject and s3:ListBucket on a specific bucket ARN does exactly what the application needs and nothing else.

The hierarchy of least privilege, from most specific to least:

  1. Customer managed policy scoped to specific resources and actions
  2. AWS managed service-specific policies (e.g., AmazonS3ReadOnlyAccess)
  3. AWS managed job function policies (ReadOnlyAccess, PowerUserAccess)
  4. AdministratorAccess (wildcard permissions on all resources)

Design permissions by starting from what the role actually needs to do. List the API calls the application makes. Write a policy that permits exactly those calls on exactly the resources they apply to. Add resources to the policy only as they are explicitly needed.

Permission boundaries

Permission boundaries are an advanced mechanism for delegated access management. A permission boundary defines the maximum permissions a principal can have, regardless of what permission policies are attached.

Use case: you want a development team to be able to create IAM roles for their applications, but you do not want those roles to have more permissions than the team itself has. Attach a permission boundary to any role the team creates, limiting the maximum permissions. Even if the team attaches AdministratorAccess to a role they create, the permission boundary caps what that role can actually do.

Permission boundaries are particularly useful in multi-team environments where centralised IAM management is impractical but you still need guardrails on what teams can grant.

Auditing and permission reviews

IAM permissions accumulate over time. A role designed for a specific application gets permissions added for a quick fix, then never reviewed again. After a year, the role has permissions for services it no longer uses.

Regular audits catch permission creep:

IAM Access Analyser generates findings for overpermissioned roles: roles that have permissions for actions that were never used in the trailing 90 days. Review these findings monthly and remove unused permissions.

AWS Config rule iam-policy-no-statements-with-admin-access flags policies that contain Effect: Allow with Action: * and Resource: *. Any policy matching this pattern is providing more access than any legitimate role should need.

CloudTrail analysis: The aws iam generate-service-last-accessed-details API reports the last time each service and action was used by an IAM entity. Actions not used in 90 or more days are candidates for removal.

For GDPR and FCA compliance, scheduled quarterly IAM access reviews with documented findings and remediation actions satisfy the access control review requirements that regulators ask about.

Where Critical Cloud comes in

IAM is the security foundation that everything else depends on. Overpermissioned roles, long-lived access keys, and stale permissions are the conditions that make breaches worse when they happen. We design and operate AWS IAM architectures for regulated and technology-led businesses, with access reviews, least-privilege policy design, and IAM Access Analyser findings managed as standing operational tasks. As the world's first Powered by Datadog accredited partner, we surface IAM-related security signals alongside infrastructure and application health. See how Critical Support works.