What is IAM and how does the policy evaluation logic work?
Quick Answer
IAM (Identity and Access Management) controls who can do what in AWS. Policy evaluation follows a strict order: explicit Deny always wins, then Organizations SCPs, then resource-based policies, then identity-based policies, then permissions boundaries, then session policies. The default is implicit deny — no access unless explicitly granted.
Detailed Answer
AWS Identity and Access Management (IAM) is the foundation of every security decision in AWS. Think of it as the security system for an entire corporate campus — it manages who people are (authentication), what badge they carry (identity), what doors they can open (authorization), and logs every door they walk through (auditing).
IAM has four core building blocks. Users are individual identities with long-term credentials (access keys and passwords). Groups are collections of users that share the same permissions — like giving all developers the same badge level. Roles are temporary identities that anyone or anything can assume — humans, EC2 instances, Lambda functions, even users from other AWS accounts. Roles issue short-lived credentials via AWS STS (Security Token Service), making them far more secure than long-term user access keys. Policies are JSON documents that define permissions — they are the actual rules that say allow or deny specific actions on specific resources under specific conditions.
Policies come in several types. Identity-based policies are attached to users, groups, or roles and define what that identity can do. Resource-based policies are attached to resources (S3 buckets, SQS queues, KMS keys) and define who can access that resource. Permissions boundaries set the maximum permissions an identity can have — they do not grant access themselves but cap what identity-based policies can grant. Think of it as a fence around what an identity is allowed to request. Organizations Service Control Policies (SCPs) set the maximum permissions for an entire AWS account — they are guardrails applied at the organizational level.
The policy evaluation logic is where most engineers get confused, and getting it wrong leads to security vulnerabilities. AWS evaluates policies in a specific order with a strict hierarchy. The algorithm works as follows:
Step 1: All policies are gathered — identity-based, resource-based, SCPs, permissions boundaries, and session policies. Step 2: AWS checks for any explicit Deny across ALL policies. If any single policy statement has Effect: Deny that matches the request, access is denied immediately — no exceptions. This is the most important rule and cannot be overridden. Step 3: AWS checks Organizations SCPs. If the action is not allowed by SCPs, the request is denied even if an identity policy allows it. Step 4: For resource-based policies, if the resource policy explicitly grants access AND is in the same account, access can be granted even without an identity-based policy allowing it. This is a critical nuance — resource-based policies can grant cross-principal access within an account. Step 5: AWS checks identity-based policies. The action must be explicitly allowed here. Step 6: If a permissions boundary exists, the action must ALSO be allowed by the boundary. The effective permission is the intersection of the identity policy and the boundary. Step 7: If session policies exist (used with assumed roles or federated sessions), the action must also be allowed by the session policy.
The default state is implicit deny — if no policy explicitly allows an action, it is denied. This is the principle of least privilege enforced at the platform level.
A common production gotcha is the confused deputy problem in cross-account access. If your account lets another account assume a role, you must use the ExternalId condition to prevent a malicious third party from tricking the trusted account into accessing your resources. Another gotcha is policy size limits: managed policies max at 6,144 characters, and inline policies max at 2,048 characters for users and 10,240 for roles. Complex environments often hit these limits and must refactor into multiple policies.
In production, best practice is to use roles exclusively (never long-term access keys), enforce MFA for console access, use permissions boundaries for delegated administration, and audit with IAM Access Analyzer to find unintended external access.