IAM identities: users, groups, and roles
IAM users are long-term identities that represent individual people or applications. Each user has permanent credentials: a password for console access and access keys for programmatic access. Because these credentials are long-term, they should be secured carefully with MFA and rotated regularly. The root account user has unlimited access to everything in the AWS account and should only be used for tasks that specifically require it, such as changing billing settings or enabling AWS services.
IAM groups are collections of users that share the same permissions. Assign a policy to a group and every member inherits those permissions. Groups do not have credentials and cannot assume roles themselves. They are purely a management tool for applying policies to multiple users simultaneously.
IAM roles are temporary identities assumed by AWS services, applications, or users from other accounts. When an EC2 instance needs to read from S3, you attach a role to the instance rather than embedding access keys in the code. When the instance assumes the role, it receives temporary credentials that expire automatically. Roles are the correct way to grant permissions to AWS services, cross-account access, and federated identities from external providers.
Policies: identity-based and resource-based
IAM policies are JSON documents that define what actions are allowed or denied on which resources under which conditions. Identity-based policies are attached to IAM users, groups, or roles and define what that identity can do. Resource-based policies are attached to the resource itself (like an S3 bucket policy or a KMS key policy) and define who can access that resource.
The key difference matters for cross-account access. If Account A's user wants to access Account B's S3 bucket, Account B needs a bucket policy that allows Account A's user, and Account A's user needs an identity-based policy that allows the S3 action. Both sides must permit the access.
The IAM policy evaluation order is: explicit deny wins over everything. If any policy, anywhere, explicitly denies an action, that action is denied regardless of how many policies allow it. After checking for explicit denies, AWS looks for an explicit allow. If no explicit allow exists, the default is deny. This means the absence of an allow is a deny.
IAM best practices and how to choose the correct answer
Least privilege is the operating principle: grant only the minimum permissions required to perform the task. Start with no permissions and add as needed rather than starting with broad access and trying to restrict later. Managed policies (AWS-maintained) provide a starting point. Inline policies are specific to one identity and are appropriate for unique requirements.
Never embed access keys in application code. Use IAM roles for EC2, Lambda, and other AWS services. For applications running outside AWS, use AWS IAM Identity Center (formerly SSO) or OIDC federation to provide temporary credentials rather than long-term keys.
Policy evaluation: explicit deny beats explicit allow. If no explicit deny and an explicit allow exists, allow. If no explicit allow, implicit deny.
IAM role vs IAM user: role = temporary credentials, assumed by services or external identities. User = long-term credentials, for specific humans. EC2, Lambda, ECS all use roles, not embedded user credentials.
Permission boundaries: an advanced feature that sets the maximum permissions an identity can have, even if their policies allow more. Used to safely delegate permission management to developers without letting them grant themselves more access than the boundary allows.