One of the most common AWS errors is "Access Denied." IAM (Identity and Access Management) is the core AWS security service that decides "who can do what on which resources." This guide explains IAM from the basics to advanced concepts in a beginner-friendly way.
IAM Basic Components
Think of a company's access control system. Employees each carry a badge (user). Different departments can access different areas. IAM follows the same structure.
A User is an individual person or application that accesses AWS. Each user has unique credentials — either a password for console access or an access key for programmatic access.
A Group is a collection of users that share the same permissions. Create a "development team" group and all developers in it automatically get the same permissions. When a new developer joins, just add them to the group. Important: groups cannot contain other groups.
A Role grants temporary permissions to AWS services or external users, not long-term credentials. When an EC2 instance needs to access an S3 bucket, you attach a role to the instance instead of embedding access keys. The role issues temporary credentials that expire automatically.
A Policy is a JSON document that says "allow or deny these specific actions on these specific resources for this specific service."
Types of Policies
IAM has several policy types, each serving a different purpose.
Identity-based Policies are attached to users, groups, or roles. They define what the identity can do. These come in two forms: AWS Managed Policies (created and maintained by AWS) and Customer Managed Policies (created by you).
Resource-based Policies are attached directly to resources like S3 buckets, SQS queues, and KMS keys. They define who can access the resource. Unlike identity-based policies, they require a Principal (who is being granted access). This is particularly useful for granting access to users from other accounts.
Permission Boundaries set the maximum permissions a user or role can ever have. Think of it as a fence that says "you can only grant permissions within this boundary." For example, you give a team lead permission to create IAM users, but add a Permission Boundary so they cannot create users with more permissions than they themselves have.
SCPs (Service Control Policies) are the organization-level restrictions covered in the previous article.
| Policy Type | Applied To | Key Characteristic | |-------------|------------|-------------------| | Identity-based | Users, groups, roles | Defines what the identity can do | | Resource-based | S3, SQS, KMS etc. | Requires Principal, enables cross-account | | Permission Boundary | Users, roles | Maximum permissions ceiling | | SCP | OUs, accounts | Organization-level restriction, not applied to management account |
Policy Evaluation Logic — How AWS Decides to Allow or Deny
This is the most difficult and important part of IAM. When a request arrives, AWS examines multiple policies to determine whether to allow it.
The core rule has three steps. First, if there is an Explicit Deny anywhere, the request is denied unconditionally. No other Allow policy can override a Deny. Second, if there is an Explicit Allow and no Deny, the request is permitted. Third, if there is neither, the result is an Implicit Deny. In AWS, everything is denied by default unless explicitly allowed.
Same-account rule: if either the identity-based policy or the resource-based policy allows the action, access is permitted (union).
Cross-account rule: both the identity-based policy in the requesting account and the resource-based policy on the target resource must allow the action. A single Allow in only one of them is not enough (intersection).
A real scenario: Developer A has an Allow policy for reading an S3 bucket, but access is denied. Possible causes include: an SCP blocking the S3 service for that account, a Permission Boundary on the user that excludes S3, an explicit Deny in the S3 bucket's resource-based policy, or a VPC endpoint policy blocking the request.
Exam tip: "Allow policy exists but access is still denied" — the answer is to check for an explicit Deny somewhere (SCP, Permission Boundary, resource-based policy).
MFA — Protecting Accounts with Two-Factor Authentication
Protecting an account with only a password is not enough. If the password is stolen, the account is immediately compromised. MFA (Multi-Factor Authentication) requires a second form of verification beyond the password — like an ATM that requires both your card and your PIN.
There are three MFA types. Virtual MFA devices are smartphone apps like Google Authenticator or Authy. They generate a six-digit code that changes every thirty seconds. Hardware MFA devices are physical tokens like YubiKey. U2F security keys are USB-based FIDO standard security keys.
You can enforce MFA through IAM policy conditions. Using the aws:MultiFactorAuthPresent condition key, you can create a policy that denies specific actions unless MFA was used to authenticate. For example: "deny terminating EC2 instances unless the user authenticated with MFA."
The root account must have MFA enabled without exception. The root account has unlimited power over the entire AWS account and must be protected at the highest level.
Exam tip: "Block API calls from users who have not authenticated with MFA" — the answer is adding the aws:MultiFactorAuthPresent condition to the IAM policy.
Federation — Logging into AWS with External Accounts
Your company employees already have Active Directory accounts. You want them to access AWS using those same company accounts without creating separate AWS IAM accounts for each person. That is federation.
SAML 2.0 Federation is most common in enterprise environments. It connects your company's Active Directory or ADFS (Active Directory Federation Services) to AWS. Employees log into the company's SSO portal, and through STS AssumeRoleWithSAML they receive temporary AWS credentials and access the AWS console.
OIDC Federation is used in mobile or web applications. Users log in with Google, Facebook, or Apple accounts, and access AWS resources through that identity. Amazon Cognito simplifies this integration.
AWS IAM Identity Center (formerly AWS SSO) provides centralized SSO across multiple AWS accounts. One login gives access to the console of any account you have permissions for. It integrates with Organizations and manages per-account permissions through Permission Sets. This is the recommended approach for multi-account environments.
Exam tip: "Company Active Directory users need to access the AWS console" — the answer is SAML 2.0 federation or IAM Identity Center.
IAM Access Analyzer — Finding Externally Exposed Resources
One day you discover an S3 bucket is publicly accessible to anyone in the world. You need to know when that happened and whether other resources are also exposed. IAM Access Analyzer finds these situations automatically.
IAM Access Analyzer automatically identifies resources that are accessible from outside your account — whether from other AWS accounts or from the public internet. It is like a security inspection that finds unlocked doors.
Resources analyzed include: S3 bucket policies, IAM role Trust Policies, KMS key policies, SQS queue policies, Lambda function policies, and Secrets Manager secret policies.
When externally accessible resources are found, Access Analyzer creates a "Finding." You review each Finding: if the external sharing is intentional, mark it as "Archive." If it is unintended exposure, fix the policy to remove the access.
Access Analyzer has two additional capabilities worth knowing. The policy generation feature analyzes your CloudTrail logs and automatically generates a least-privilege policy based on what actions were actually used. The policy validation feature checks IAM policy syntax and flags best-practice violations.
Exam tip: "Automatically detect if an S3 bucket is publicly accessible" — the answer is IAM Access Analyzer.
Service-Linked Roles
These are special IAM roles that AWS services automatically create to manage other AWS resources on your behalf. Auto Scaling needs permissions to create and terminate EC2 instances — a service-linked role provides those permissions automatically.
Users cannot easily modify or delete service-linked roles, and only the specific service that created them can use them. Auto Scaling, ElastiCache, RDS, CloudFormation, and many other services rely on service-linked roles.
Access Key Management
When a program calls AWS APIs directly — through the AWS CLI, an SDK, or server-side code — it uses access keys (Access Key ID plus Secret Access Key) instead of a password.
Best practices for access key management: each user can have a maximum of two active access keys (useful during key rotation to allow overlap). Rotate keys regularly. Never create access keys for the root account, or delete them immediately if they exist. Generate an IAM Credential Report to see all users' access key usage and last-used dates.
STS Temporary Credentials
AWS STS (Security Token Service) issues temporary credentials with an expiration time. They are safer than long-term credentials like access keys.
AssumeRole obtains temporary credentials by assuming a role in the same account or a different account.
AssumeRoleWithSAML is used in SAML-based federation scenarios.
AssumeRoleWithWebIdentity is used in OIDC-based federation with providers like Google and Facebook.