Cloud / AWS IAM (Identity and Access Management) Interview questions
Last updated
1. What is AWS IAM?
AWS Identity and Access Management (IAM) is the AWS service that controls who can do what inside an AWS account. It lets you create identities - users, groups, and roles - and attach policies that grant or deny specific permissions on specific resources.
Every API request, whether it comes from the console, the CLI, an SDK, or another AWS service, is checked by IAM for authentication (confirming who is making the request) and authorization (confirming what that identity is allowed to do) before it is permitted to run.
IAM is a global service rather than a regional one, it costs nothing extra to use, and it underpins almost every other AWS security control, from S3 bucket policies to KMS key policies.
Take quiz
Encrypting data at rest in S3
Controlling who can do what within an AWS account
Routing traffic between VPCs
A regional service billed per request
A global service offered at no additional charge
A paid add-on for Enterprise Support only
2. What is the purpose of an IAM policy?
An IAM policy is a JSON document that defines permissions - it lists which actions are allowed or denied, on which resources, and optionally under which conditions. Policies are the mechanism IAM uses to actually enforce access control, once an identity has been authenticated.
A policy does nothing on its own; it must be attached to an identity (a user, group, or role) or, for resource-based policies, directly to a resource such as an S3 bucket, before it has any effect.
Without at least one policy granting access, a brand-new IAM identity can authenticate successfully but cannot call any AWS API - IAM denies everything by default until a policy explicitly allows it.
Take quiz
Define what actions are allowed or denied on which resources
Store the account's billing information
Encrypt objects stored in S3
Call any AWS API by default
Only read S3 buckets by default
Authenticate but call nothing, since access is denied by default
3. What are the types of IAM identities?
IAM supports three types of identities: users, groups, and roles.
- Users represent a single person or application and have their own long-term credentials (a password, access keys, or both).
- Groups are just collections of users used to attach policies to many users at once - a group cannot be logged into and has no credentials of its own.
- Roles are identities with no long-term credentials; instead, they are assumed temporarily by a user, an application, or an AWS service, which then receives short-lived credentials from AWS STS.
In practice, most teams manage humans through federated access rather than IAM users, and use roles for almost everything workloads and services need to do.
Take quiz
User
Group
Role
Logging in directly with a permanent password
Storing a group's shared access key
Being assumed temporarily to obtain short-lived credentials
4. What is an IAM user?
An IAM user is an identity created inside an AWS account to represent a specific person or application that needs long-term access to that account. Each user gets a unique name and, optionally, a console password and/or programmatic access keys.
Permissions come from policies attached directly to the user, from groups the user belongs to, or from a permissions boundary that caps what those policies can grant.
AWS recommends limiting IAM users in favor of federated access through IAM Identity Center for humans, and roles for workloads, because user access keys are long-lived and, if leaked, remain valid until manually rotated or deleted.
Take quiz
Only policies attached directly to that user
Directly attached policies and any groups the user belongs to
The billing console only
Expire automatically every hour
Stay valid until manually rotated or deleted
Only work from the AWS Console
5. What is an IAM group?
An IAM group is a named collection of IAM users used purely to simplify permission management. Instead of attaching the same policy to ten individual users, you attach it once to a group and add those users as members.
Groups cannot be nested inside other groups, cannot be referenced as the principal in a resource-based policy, and cannot be assumed the way a role can - they exist only to organize users.
A common pattern is one group per job function, such as Developers, Billing-ReadOnly, or SecurityAudit, each carrying the managed policies appropriate to that function.
Take quiz
Attach the same permissions to many users at once
Provide temporary credentials to an application
Encrypt console login sessions
Groups can be nested inside other groups
Groups can be assumed like a role
Groups exist only to organize users, not to be assumed or nested
6. What is an IAM role?
An IAM role is an identity that grants a defined set of permissions but is not owned by a specific person - it has no password and no long-term access keys. Instead, a trusted entity (an IAM user, an AWS service like EC2 or Lambda, or a federated identity) assumes the role and receives temporary security credentials from AWS STS.
A role has two parts: a trust policy (also called an assume-role policy), which lists who is allowed to assume it, and one or more permissions policies, which list what the role can actually do once assumed.
Roles are the recommended way to grant access to EC2 instances, Lambda functions, and cross-account users, because the credentials they issue automatically expire, typically within 15 minutes to 12 hours.
Take quiz
Can only be used by the root account
Has no long-term credentials and is assumed for temporary access
Cannot have any permissions policies attached
What actions the role can perform
Who is allowed to assume the role
How long the AWS account has existed
7. What are the types of IAM policies?
IAM supports several distinct policy types, each serving a different purpose:
| Policy Type | Attached To | Purpose |
| Identity-based | Users, groups, roles | Grants permissions to the identity |
| Resource-based | Resources (S3, SQS, KMS) | Grants access directly on the resource |
| Permissions boundary | Users, roles | Caps the maximum permissions an identity can have |
| Service control policy (SCP) | AWS Organizations OU/account | Sets guardrails account-wide |
| Session policy | A single AssumeRole session | Further restricts one session's permissions |
All applicable policy types are evaluated together for any given request, and a single explicit Deny anywhere in that set wins over any number of Allow statements.
Take quiz
Permissions boundary
Session policy
Resource-based policy
Is ignored if another policy has an Allow
Overrides any Allow and blocks the request
Only applies to the root user
8. Describe the structure of an AWS IAM policy?
An IAM policy is a JSON document built around one or more statements, each of which has a small, fixed set of elements:
Effect- eitherAlloworDeny.Action- the API operations the statement applies to, such ass3:GetObject.Resource- the ARN(s) the statement applies to.Condition(optional) - extra constraints, such as source IP or time of day.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowReadOnBucket", "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::example-bucket/*", "Condition": {"IpAddress": {"aws:SourceIp": "203.0.113.0/24"}} } ] }
The Version field should almost always be "2012-10-17", the current policy language version, since it enables features like policy variables that the older 2008-10-17 version does not support.
Take quiz
Effect
Version
Sid
2008-10-17
1.0
2012-10-17
9. What is the principle of least privilege?
Least privilege means granting an identity only the exact permissions it needs to do its job - nothing more. If a Lambda function only ever reads from one specific S3 bucket, its role's policy should allow s3:GetObject on that one bucket's ARN, not s3:* on *.
The practical benefit is blast-radius reduction: if that function's credentials are ever compromised, the attacker inherits only that narrow set of permissions instead of broad account access.
AWS provides tools that make least privilege achievable rather than purely aspirational, including IAM Access Analyzer, which generates a policy from a role's actual CloudTrail activity, and the last accessed data shown on every IAM identity, which flags permissions that have never been used.
Take quiz
Full administrator access by default
Access to every service just in case
Only the exact permissions it needs to do its job
AWS Budgets
IAM Access Analyzer
Amazon GuardDuty
10. What are IAM permissions boundaries?
A permissions boundary is a managed policy attached to a user or role that sets the maximum permissions that identity can ever have, regardless of what its identity-based policies grant. The identity's effective permissions are the intersection of its policies and its boundary, not the union.
Boundaries are most often used to let a team safely delegate role or user creation: an admin can allow a developer to create IAM roles, but attach a boundary so any role that developer creates can never exceed a defined permission ceiling, such as never reaching S3 or IAM itself.
A boundary that grants broad access does nothing by itself - it only limits, it never grants; an identity still needs an actual identity-based policy allowing an action before it can perform it.
Take quiz
The intersection of its policies and the boundary
The union of its policies and the boundary
Whichever policy was attached most recently
Grants that access automatically
Grants nothing by itself - an identity-based policy must still allow it
Overrides any explicit Deny elsewhere
11. Define an IAM trust policy?
A trust policy (formally an assume-role policy document) is the JSON document attached to a role that specifies who is allowed to assume it. It is the only policy type where the Principal element is required, since its whole job is naming the trusted principal - an account, a specific IAM role or user, an AWS service, or a federated identity provider.
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole" }] }
A trust policy only controls entry into the role; it grants no permissions on its own. What the role can actually do once assumed is decided separately by the permissions policies attached to it.
Take quiz
What actions a role can perform
How long a password must be
Who is allowed to assume the role
Resource
Principal
Sid
12. Describe the AWS account root user?
The root user is created automatically when an AWS account is opened and is identified by the email address used to sign up. It is the only identity with truly unrestricted access - it cannot be limited by any IAM policy and, by default, cannot be denied by an SCP either unless the organization explicitly targets it.
Because of that unlimited power, AWS recommends the root user be used only for a short list of tasks that genuinely require it, such as closing the account, changing the support plan, or restoring an IAM administrator's own access after a lockout - not for everyday administration.
Best practice is to secure the root user with a strong, unique password and hardware or virtual MFA, avoid creating access keys for it, and set up an IAM administrator (or IAM Identity Center) immediately for day-to-day work.
Take quiz
An IAM user name
The email address used to sign up for the account
An automatically generated role ARN
Everyday administrative tasks
A short list of tasks that specifically require it, like closing the account
Running all production workloads
13. What is Multi-Factor Authentication (MFA) in IAM?
MFA adds a second verification factor - typically a time-based one-time code from a virtual or hardware authenticator, or a FIDO2 security key - on top of a username and password. Even if a password is stolen, an attacker still cannot sign in without that second factor.
IAM supports MFA for console sign-in and can require it for specific API calls through a policy condition like aws:MultiFactorAuthPresent, which is commonly used to demand MFA before allowing sensitive actions such as deleting a CloudTrail trail or an S3 bucket.
MFA should always be enabled on the root user at a minimum, and AWS strongly recommends enabling it for every human identity, particularly anyone with administrative permissions.
Take quiz
Requiring a second verification factor beyond the password
Encrypting the password before storage
Rotating access keys automatically
aws:SourceIp
aws:CurrentTime
aws:MultiFactorAuthPresent
14. What is an IAM access key?
An access key is a long-term credential pair - an access key ID and a secret access key - that lets a user or application authenticate programmatically to AWS APIs through the CLI, SDKs, or direct HTTP calls, since there is no password prompt outside the console.
A user can have up to two active access keys at once, which supports zero-downtime rotation: create a new key, update the application to use it, verify it works, then deactivate and delete the old one.
Because access keys do not expire on their own, AWS treats them as a significant leak risk if hardcoded into source code or committed to a repository, and increasingly recommends IAM roles with temporary credentials instead, wherever a workload can use one.
Take quiz
Logging into the AWS console with a password
Programmatic authentication via CLI, SDKs, or direct API calls
Encrypting S3 objects
One
Two
Unlimited
15. List the types of AWS managed policies?
AWS managed policies come in two categories, both created and maintained by AWS rather than by the account owner:
- AWS managed policies - broad, general-purpose policies like
AmazonS3ReadOnlyAccessorAdministratorAccess, usable across any AWS account and automatically updated by AWS as services evolve. - Job function policies - a subset of AWS managed policies mapped to common roles, such as
DataScientistorNetworkAdministrator, intended as a practical starting point rather than a precise fit.
These sit alongside two account-owned options: customer managed policies, which an account creates and controls itself, and inline policies, embedded directly in a single identity. AWS managed policies are convenient but, being shared across all customers, are usually broader than least privilege requires for a specific workload.
Take quiz
Created and owned by the individual AWS account
Created and maintained by AWS itself
Only usable within a single AWS Organization
Usually broader than least privilege requires for a specific workload
Impossible to attach to more than one identity
Editable directly by the customer
16. What is AWS IAM Identity Center?
IAM Identity Center (formerly AWS SSO) is AWS's service for managing workforce access to multiple AWS accounts and business applications from one place, using a single sign-on experience instead of separate IAM users per account.
It can use its own built-in identity store or connect to an external identity provider such as Okta, Microsoft Entra ID, or an on-premises Active Directory via SAML 2.0, so existing corporate credentials and group memberships carry over.
Access is defined through permission sets - reusable templates of IAM policies applied per AWS account - rather than by creating individual IAM users in every account, which is why AWS recommends it as the default way to give people, not workloads, access across an organization.
Take quiz
Granting EC2 instances permissions
Encrypting data across accounts
Single sign-on workforce access across multiple AWS accounts
Individual IAM users created in every account
Permission sets applied per AWS account
Root user credential sharing
17. How do you create an IAM user?
In the console, this is done from IAM > Users > Create user: you supply a user name, choose whether to grant console access (and set a password policy for it), then either add the user to a group, copy permissions from an existing user, or attach policies directly.
The same can be done with the CLI:
aws iam create-user --user-name jane-doe aws iam add-user-to-group --user-name jane-doe --group-name Developers
Access keys, if the user needs programmatic access, are generated as a separate step after the user exists, from Security credentials on the user's detail page or via aws iam create-access-key. AWS explicitly recommends attaching permissions through a group rather than directly to the user, so access stays manageable as team membership changes.
Take quiz
Adding the user to a group rather than attaching policies directly
Sharing the root user's credentials
Copying the AdministratorAccess policy by default
aws iam create-role
aws iam create-user
aws iam create-group
18. How do you attach a policy to an IAM user?
A managed policy is attached with a single call - no separate creation step is needed if it already exists:
aws iam attach-user-policy \ --user-name jane-doe \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
In the console, this is the Add permissions button on the user's Permissions tab, where you can search for and select an existing managed policy, create a new customer managed policy, or add an inline policy scoped to just that user.
To detach it later, the equivalent command is aws iam detach-user-policy with the same user name and policy ARN. For an inline policy, the calls are put-user-policy to create or update it and delete-user-policy to remove it.
Take quiz
aws iam put-user-policy
aws iam attach-user-policy
aws iam create-policy-version
attach-user-policy
put-user-policy
create-user-policy
19. What is an ARN in IAM?
An Amazon Resource Name (ARN) is the globally unique identifier AWS uses to reference a specific resource in a policy, API call, or console link. IAM policies use ARNs in their Resource element to say exactly which resource a statement applies to.
The general format is:
arn:partition:service:region:account-id:resource-type/resource-id
For example, an IAM role's ARN looks like arn:aws:iam::123456789012:role/DeployRole - note that IAM is a global service, so the region field is left empty. An S3 object ARN, by contrast, includes no region or account ID at all: arn:aws:s3:::example-bucket/reports/2026.csv, because bucket names are globally unique on their own.
Take quiz
Set the policy version
Encrypt the resource
Uniquely identify exactly which resource a statement applies to
Always set to us-east-1
Left empty, since IAM is a global service
Required and cannot be blank
20. What are IAM inline policies?
An inline policy is a policy embedded directly inside a single user, group, or role, rather than existing as a standalone object that can be attached elsewhere. It has no independent ARN and cannot be reused - it lives and dies with the identity it was created on.
This makes inline policies useful when a permission genuinely must never be reused or accidentally attached to another identity, for example, a one-off exception unique to a single role. However, they make permissions harder to audit at scale, since there is no central policy list to review - each inline policy must be inspected on its own identity.
AWS's general guidance favors customer managed policies over inline policies for most cases, precisely because managed policies are visible, versioned, and reusable, and deleting the identity does not silently delete a policy someone might have wanted to keep.
Take quiz
Embedded directly in a single identity with no independent ARN
Automatically shared across every identity in the account
Only usable on resource-based policies
Cannot be deleted once created
Have no central list, making them harder to audit
Are always more permissive than managed policies
21. What is the difference between IAM users and IAM roles?
The core difference is credential lifetime and ownership. A user is a persistent identity with long-term credentials belonging to one person or application, while a role has no credentials of its own and is assumed temporarily by whoever the trust policy allows.
| IAM User | IAM Role |
| Long-term password and/or access keys | Temporary credentials issued by STS |
| Belongs to exactly one identity | Can be assumed by many different trusted entities |
| Credentials must be manually rotated | Credentials expire automatically |
| Requires a trust relationship | No trust policy needed |
In modern AWS architectures, users are increasingly reserved for a small number of break-glass or service-account cases, while roles handle everything else - EC2 instance profiles, Lambda execution, cross-account access, and federated human sign-in.
Take quiz
Only roles can have policies attached
Users have long-term credentials; roles issue temporary ones when assumed
Only users can be used by AWS services
IAM user
IAM role
IAM group
22. What is the difference between identity-based and resource-based policies?
An identity-based policy is attached to a user, group, or role and answers the question "what can this identity do?" A resource-based policy is attached directly to a resource - an S3 bucket, an SQS queue, a KMS key - and answers "who can access this resource, and how?"
The key practical distinction is that a resource-based policy can grant access to a principal in a different AWS account without that account needing any corresponding identity-based policy at all, since the resource itself is doing the granting. Identity-based policies, by contrast, can only be granted by an administrator within the identity's own account.
{ "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::999999999999:root"}, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::shared-bucket/*" }
Most services, including IAM roles themselves, support only identity-based policies (plus a trust policy); only a specific subset of services, such as S3, SNS, SQS, KMS, and Lambda, support resource-based policies.
Take quiz
An IAM user
The resource itself, such as an S3 bucket
An IAM group
Grant a principal in a different AWS account access with no identity-based policy needed
Be attached to an IAM group
Replace the need for authentication entirely
23. Why should you avoid using the root account for daily tasks?
The root user has permissions that cannot be restricted by any IAM policy - no Deny statement, no permissions boundary, and by default no SCP can fully limit what it can do. Using it daily means every routine task carries the full, unlimited blast radius of the entire account if that session or its credentials are ever compromised.
Root actions also bypass the fine-grained accountability IAM gives you elsewhere: while CloudTrail still logs root activity, you lose the ability to scope, review, or revoke root's access the way you can granularly manage an IAM role or user, and multiple humans sharing root credentials makes it impossible to attribute an action to a specific person.
Practically, this is also unnecessary: virtually everything root can do - including billing, most account settings, and all resource management - is also available to an IAM administrator role, so there is rarely a task that genuinely requires signing in as root.
Take quiz
Are weaker than an IAM administrator's
Cannot be restricted by IAM policies, so any compromise has the largest possible blast radius
Automatically expire every 24 hours
Each action is automatically attributed to the correct person
It becomes impossible to attribute a specific action to a specific person
CloudTrail stops logging root activity
24. Why do we use IAM roles instead of long-term access keys on EC2?
An EC2 instance profile attaches an IAM role to an instance, and the instance metadata service delivers temporary credentials to any process running on it - no access key is ever stored on disk, in an AMI, or in application config.
Because those credentials are short-lived and rotated automatically by AWS behind the scenes (roughly every few hours, well before expiry), a leaked credential - through a log file, a misconfigured metadata endpoint, or a compromised container - has a small, self-limiting window of usefulness, unlike a hardcoded access key that stays valid indefinitely.
Roles also simplify operations: there is nothing to rotate manually, nothing to store in a secrets manager for this specific purpose, and permissions can be changed centrally on the role without touching the instance or redeploying anything.
Take quiz
Requiring the AMI to embed an access key
Delivering temporary credentials via the instance metadata service
Storing the root user's password on the instance
Expires automatically within a short window
Never grants any real permissions
Only works from the AWS console
25. How does IAM policy evaluation logic work?
For every request, IAM gathers all applicable policies - identity-based, resource-based, permissions boundaries, session policies, and any SCPs - and evaluates them together using a fixed order of precedence, not a first-match-wins scan.
flowchart TD
A["Request received"] --> B{Explicit Deny in any policy?}
B -- Yes --> C[DENY]
B -- No --> D{SCP allows the action?}
D -- No --> C
D -- Yes --> E{Resource-based policy allows it?}
E -- Yes --> F[ALLOW]
E -- No --> G{Identity-based policy allows it?}
G -- No --> C
G -- Yes --> H{Permissions boundary allows it, if present?}
H -- No --> C
H -- Yes --> F
The default is implicit deny: if nothing explicitly allows the action, it is denied, and that default cannot be overridden. Only an explicit Allow from a resource-based policy or, more commonly, an identity-based policy changes that default to allow - and even then, an explicit Deny anywhere always wins.
Take quiz
Allow
Implicit deny
The request is queued for manual review
Is ignored if an Allow exists elsewhere
Only matters if it is listed first
Always wins over any Allow
26. How is an explicit deny different from an implicit deny?
An implicit deny is simply the absence of an allow - IAM's default posture for any action nothing has spoken to. An explicit deny is an actual "Effect": "Deny" statement in a policy, deliberately blocking an action.
| Implicit Deny | Explicit Deny |
| No policy mentions the action | A policy statement sets Effect: Deny |
| Can be overridden by an Allow elsewhere | Cannot be overridden by any Allow |
| The IAM default | Requires a deliberate statement |
This difference matters most when you need a guardrail that must hold no matter what other policies say - for example, denying iam:* outside a specific IP range. An implicit deny would be defeated the moment any policy grants that action; an explicit deny cannot be.
Take quiz
No policy mentions the action at all
A policy explicitly sets Effect: Deny
The root user makes a request
Can always be overridden by an Allow
Can never be overridden by any Allow
Only applies to resource-based policies
27. When should you use a resource-based policy instead of an identity-based policy?
Reach for a resource-based policy when the access you're granting crosses an account boundary, or when it needs to be centrally visible on the resource itself rather than scattered across many identities' policies.
- Cross-account sharing - letting a different account read from your S3 bucket or invoke your Lambda function without creating a role for them in your account.
- Anonymous or public access - a public S3 website bucket, where there is no identity to attach a policy to.
- Service-to-service invocation - allowing an event source like S3 or SNS to invoke a Lambda function, expressed as a resource policy on the function.
For same-account access controlled by "what can this specific team or application do," an identity-based policy is usually the better fit, since it keeps permissions centralized on the identity rather than spread across every resource it touches.
Take quiz
Access needs to cross an AWS account boundary
You want to grant permissions to a single team within one account
You need to encrypt data at rest
An IAM group policy
A resource-based policy on the Lambda function
The root user's permissions
28. When would you choose an IAM role over an IAM user?
Choose a role whenever the entity needing access is a workload rather than a long-term human identity: an EC2 instance, a Lambda function, an ECS task, another AWS account, or a federated identity signing in through IAM Identity Center or a SAML/OIDC provider.
Roles are also the right tool for granting temporary, scoped-down access - for example, a support engineer who needs 30 minutes of elevated access to debug a production issue should assume a role for that window, rather than being given a standing user with those permissions permanently.
A genuinely rare case for a user is a legacy application that cannot use STS-issued temporary credentials at all and truly must have a static key - even then, that should be treated as an exception requiring compensating controls like key rotation and tight scoping, not a default choice.
Take quiz
A workload, service, or federated identity rather than a standing human user
Always the root user
Never an AWS service
Be given a permanent user with those permissions
Assume a role scoped to that access for the needed window
Be given the root user's credentials
29. What happens when multiple IAM policies conflict?
IAM does not treat this as a true "conflict" needing resolution rules the way some systems do - it collects every applicable statement across every policy type attached to the request and applies one fixed rule: any explicit Deny wins, regardless of how many Allow statements exist elsewhere.
If, for example, a user's identity-based policy allows s3:DeleteObject on a bucket, but a separate permissions boundary or SCP does not explicitly allow that action, the request is still denied - not because of a conflict, but because the boundary or SCP's implicit deny for anything unlisted still applies at its layer.
If two identity-based policies both allow the same action with different conditions, both are evaluated, and the request succeeds if it satisfies at least one Allow and triggers no Deny - there's no "most specific policy wins" rule like in some other systems' policy models.
Take quiz
The most recently attached policy wins
Any explicit Deny wins over any Allow
The most specific policy always wins
Denied, since the boundary's own implicit deny still applies
Allowed, because the identity policy takes priority
Allowed only if MFA is present
30. What is the difference between AssumeRole and AssumeRoleWithWebIdentity?
Both are AWS STS API calls that return temporary credentials, but they authenticate the caller differently. AssumeRole is used by an existing IAM identity (a user or another role) that already has permission, per the target role's trust policy, to assume it.
AssumeRoleWithWebIdentity is used when the caller has no IAM identity at all, but instead holds a token from a public web identity provider - Google, Facebook, Amazon Cognito, or any OpenID Connect (OIDC) provider - which IAM validates against the trust policy before issuing credentials.
A closely related third call, AssumeRoleWithSAML, works the same way for SAML 2.0 assertions from an enterprise identity provider. All three ultimately produce the same kind of result: a temporary access key, secret key, and session token, but the input credential type and trust policy condition keys used to validate it differ for each.
Take quiz
Is an existing IAM user in the same account
Holds a token from a public OIDC/web identity provider and has no IAM identity
Is the AWS account root user
A permanent access key pair
Temporary credentials: access key, secret key, and session token
A new IAM user
31. How do you troubleshoot an "Access Denied" error in AWS?
Start with the error message itself - modern AWS API errors often name the specific action and resource that were denied, which narrows the search immediately. If the message is generic, enable and check AWS CloudTrail for the exact failed event.
- Run the request through the IAM Policy Simulator or call
iam:SimulateCustomPolicyto see which policy is actually blocking it. - Check every layer that could deny it: the identity-based policy, any permissions boundary, any SCP on the account, and, for a role, the trust policy if the failure happened during
AssumeRoleitself. - Look specifically for an explicit
Deny, since that overrides everything else and is easy to miss if you're only reading the identity's main policy. - Check
Conditionblocks - a mismatched source IP, missing MFA, or an unexpected tag value is one of the most common causes of an otherwise-correct policy failing.
For a newer, more targeted alternative to the policy simulator, IAM Access Analyzer's policy check features can flag exactly which statement is responsible without manually simulating each one.
Take quiz
Amazon CloudWatch Alarms
AWS CloudTrail
Amazon Inspector
The policy's Version field
A Condition block, like source IP or MFA, that isn't being met
The order the statements appear in the JSON
32. What is the difference between a managed policy and an inline policy?
A managed policy is a standalone object with its own ARN that can be attached to, and detached from, any number of users, groups, or roles - reusable by design. An inline policy has no ARN and is permanently embedded in exactly one identity.
| Managed Policy | Inline Policy |
| Standalone object with its own ARN | Embedded directly in one identity |
| Reusable across many identities | Tied to exactly one identity |
| Versioned, up to 5 versions kept | No versioning - edits overwrite in place |
| Survives if unattached from an identity | Deleted automatically with the identity |
Managed policies are generally preferred for auditability and reuse, but a genuinely one-off permission that must never accidentally end up on another identity is a legitimate reason to use an inline policy instead.
Take quiz
Can only be attached to one identity ever
Is a standalone, reusable object with its own ARN
Is deleted automatically when the identity is deleted
Is deleted automatically along with the role
Remains as a standalone policy in the account
Automatically attaches itself to another role
33. Why doesn't attaching a new policy to a role revoke already-issued temporary credentials immediately?
IAM policy evaluation happens on every single API call, using the policies attached to the role at the moment of that call - not the policies that existed when the temporary credentials were originally issued. So in one sense, a newly attached, more restrictive policy does take effect on the very next request.
What it cannot do is force an already-issued session to stop working before its natural expiry if the change actually needs to revoke access mid-session rather than just narrow future calls - for instance, if you need to invalidate credentials that were potentially compromised right now, changing the policy alone isn't guaranteed to be fast enough or complete, since some authorization decisions can be briefly cached.
For genuine emergency revocation, AWS recommends attaching an explicit inline Deny policy to the role scoped with the aws:TokenIssueTime condition key, denying any session issued before the current time - or deleting/recreating the role - rather than relying on a permissions edit alone.
Take quiz
Only the policies that existed when credentials were issued
The policies attached to the role at the moment of each API call
A cached snapshot refreshed once per day
Simply waiting for natural token expiry
An explicit Deny using the aws:TokenIssueTime condition key
Changing the account's root password
34. How does cross-account access work with IAM roles?
Cross-account access uses a role in the target account whose trust policy names the source account (or a specific principal in it) as a trusted principal, allowing sts:AssumeRole.
sequenceDiagram
participant U as User in Account A
participant STS as AWS STS
participant R as Role in Account B
U->>STS: AssumeRole(RoleArn in Account B)
STS->>R: Check trust policy for Account A principal
R-->>STS: Trust confirmed
STS-->>U: Temporary credentials for Account B
U->>R: Call AWS APIs using temporary credentials
A user or role in account A calls sts:AssumeRole against the target role's ARN in account B. STS checks the target role's trust policy; if account A (or that specific principal) is listed, STS issues temporary credentials scoped to whatever permissions policies are attached to the target role in account B.
For an added layer of protection against the "confused deputy" problem, AWS recommends requiring an ExternalId condition in the trust policy whenever a third party is assuming the role on your behalf, so only requests bearing the pre-shared external ID are trusted.
Take quiz
The source account's billing settings
The target role's trust policy naming the source account or principal
The source account's SCPs alone
A longer session duration
An ExternalId condition in the trust policy
Disabling CloudTrail logging
35. What is IAM Access Analyzer and how does it work?
IAM Access Analyzer is a service that continuously reviews resource-based policies (S3 buckets, IAM roles, KMS keys, Lambda functions, and more) and identifies resources shared with an entity outside the zone of trust you define - typically your account or your entire AWS Organization.
It works by applying automated reasoning: it mathematically analyzes all possible access paths a policy allows, rather than just pattern-matching known-bad configurations, so it can catch unintended external access even in complex, multi-condition policies.
Beyond external-access findings, Access Analyzer also offers policy generation from a role's actual CloudTrail activity to help build least-privilege policies, policy validation that flags syntax errors and security warnings before you save a policy, and unused access findings that surface permissions and identities that haven't been used in a configurable period.
Take quiz
Slow-running Lambda functions
Resources shared with an entity outside your defined zone of trust
Unpatched EC2 operating systems
A static list of known-bad policy patterns only
Automated reasoning that mathematically analyzes all possible access paths
Manual review submitted by AWS support
36. What is the difference between the StringEquals and StringLike condition operators?
Both compare string values in a policy Condition block, but StringEquals requires an exact match, while StringLike supports wildcard characters (* and ?) for pattern matching.
"Condition": { "StringEquals": {"aws:PrincipalTag/team": "payments"}, "StringLike": {"s3:prefix": "logs/2026-*"} }
Use StringEquals when the value is fixed and known, such as a specific tag value or account ID. Use StringLike when you need to match a family of values sharing a prefix or suffix, such as any object key starting with logs/2026-, without listing every exact key.
A common mistake is using StringEquals with a value that happens to contain a literal * character, expecting it to behave as a wildcard - it won't; StringEquals treats * as a literal character, not a wildcard, so pattern matching always requires StringLike.
Take quiz
StringEquals
StringLike
Neither operator supports wildcards
Treat it as a wildcard automatically
Treat it as a literal character, not a wildcard
Cause the policy to fail validation
37. Which is better and why: managed policies or inline policies for a large team?
For a large team, customer managed policies are almost always the better choice. Because they are standalone, reusable objects, a security team can maintain one canonical PaymentsServiceRole-Permissions policy, attach it to every relevant role, and update it once when requirements change - every attached identity picks up the update immediately.
Inline policies, by contrast, would require finding and editing every individual identity's embedded copy separately, which does not scale and is prone to drift, where nominally identical roles quietly end up with different effective permissions over time.
Managed policies also support up to five saved versions with easy rollback and integrate cleanly with tools like IAM Access Analyzer's policy validation and CI/CD-based policy review, since they can be stored, diffed, and reviewed as code independent of any single identity - inline policies, tied to one identity, are harder to track that way.
The narrow exception remains a permission so specific to one identity that reuse is actually undesirable, but that case is rare enough that it shouldn't drive the default choice for a whole team.
Take quiz
Can be updated once and the change applies to every attached identity
Cannot be reviewed or versioned
Are automatically more restrictive
They automatically stay in sync with each other
Drift, where nominally identical roles end up with different effective permissions
They cannot be attached to roles at all
38. What is the difference between a permissions boundary and a service control policy?
Both are guardrails that cap what an identity-based policy can grant, but they operate at different scopes and use different mechanics. A permissions boundary is a managed policy attached to a single user or role and only limits that one identity. A service control policy (SCP) is attached to an AWS Organizations account, organizational unit, or the whole organization, and limits every identity in every account it covers - including identities created after the SCP was applied.
| Permissions Boundary | Service Control Policy |
| Attached to one user or role | Attached to an account, OU, or org |
| Requires IAM to manage | Requires AWS Organizations |
| Does not affect the root user | Can restrict the root user too |
| Set per identity as needed | Inherited by every identity in scope |
Both work as ceilings, never as grants - an SCP that "allows" S3 does not itself give anyone S3 access, it just permits identity-based policies within its scope to grant it. A common enterprise pattern layers both: SCPs enforce non-negotiable org-wide guardrails (like blocking region usage outside approved regions), while permissions boundaries fine-tune what individual delegated administrators can grant within those guardrails.
Take quiz
SCPs only apply to a single IAM user
SCPs apply to whole accounts or OUs, while boundaries apply to one identity
Permissions boundaries require AWS Organizations, but SCPs don't
Automatically grants that action to every identity in scope
Only permits identity-based policies within its scope to grant it
Overrides any identity-based Deny
39. Explain the lifecycle of temporary security credentials issued by STS?
Temporary credentials go through four stages: request, issuance, active use, and expiry.
sequenceDiagram
participant C as Caller
participant STS as AWS STS
participant AWS as AWS Services
C->>STS: AssumeRole / GetSessionToken / etc.
STS->>STS: Validate trust policy & caller identity
STS-->>C: AccessKeyId, SecretAccessKey, SessionToken, Expiration
C->>AWS: API calls signed with temp credentials
AWS->>AWS: Evaluate policies at each call
Note over C,AWS: Credentials stop working at Expiration
A caller requests credentials via one of several STS API calls (AssumeRole, AssumeRoleWithWebIdentity, AssumeRoleWithSAML, GetSessionToken, or GetFederationToken). STS validates the request against the relevant trust policy, then issues a triplet: an access key ID, a secret access key, and a session token, plus an expiration timestamp.
During their active window, the credentials are used exactly like long-term ones for signing requests, except every request must include the session token. Duration is configurable per role, from 15 minutes up to a maximum set on the role (up to 12 hours for most role-based sessions). At expiration, the credentials simply stop being valid - there's no manual revocation step for the normal case, since expiry is enforced by AWS itself, not by anything the caller does.
Take quiz
Just an access key ID
An access key ID, secret access key, and session token
A permanent password
Simply stop being valid, enforced automatically by AWS
Require the caller to manually revoke them
Automatically renew forever
40. Explain the execution flow of an AssumeRole API call?
When a caller invokes sts:AssumeRole, several checks happen in sequence before credentials are ever issued:
- STS authenticates the caller using its own existing credentials (an IAM user's keys, or another role's temporary credentials).
- STS checks the caller's own identity-based policy to confirm it is allowed to call
sts:AssumeRoleon the target role's ARN. - STS evaluates the target role's trust policy to confirm the caller is a principal it trusts, and that any conditions in the trust policy (like
ExternalIdor MFA) are satisfied. - If an optional session policy or explicit session duration was passed in the request, STS validates those too - a session policy can only further restrict the role's permissions, never expand them.
- Only if every check passes does STS mint temporary credentials and return them, scoped to the intersection of the role's permissions policies and any session policy supplied.
A failure at any step returns an error before reaching the next - most commonly, this surfaces as AccessDenied either because the caller's own policy doesn't allow the AssumeRole call, or because the target role's trust policy doesn't list the caller as trusted.
Take quiz
Expand the role's permissions beyond its attached policies
Only further restrict the role's existing permissions
Replace the role's trust policy
The billing policy of the account
The target role's trust policy
The CloudTrail logging policy
41. Explain the internal working of IAM policy evaluation logic?
Internally, IAM gathers every statement from every applicable policy for the request context - identity-based policies attached to the caller (directly and via groups), any resource-based policy on the target resource, any permissions boundary, any session policy, and any organization SCPs - into one evaluation set. It does not evaluate policies one at a time in isolation; it reasons over the union.
flowchart TD
A["Collect all applicable statements"] --> B{Any explicit Deny matches?}
B -- Yes --> Z[DENY]
B -- No --> C{SCP has an Allow for this action?}
C -- No --> Z
C -- Yes --> D{Resource policy or identity policy has an Allow?}
D -- No --> Z
D -- Yes --> E{Permissions boundary allows it, if present?}
E -- No --> Z
E -- Yes --> F{Session policy allows it, if present?}
F -- No --> Z
F -- Yes --> G[ALLOW]
Each layer independently must not deny the action, and at least one layer among the resource-based or identity-based policies must contain an explicit Allow, since the baseline is implicit deny. Because boundaries, SCPs, and session policies can only narrow, not expand, permissions, the final effective access is the intersection of everything that is allowed, minus anything explicitly denied anywhere in that set.
This is why a permission can appear correctly in a role's main policy and still fail - the evaluator is not looking at that one document alone, but at the full stack applicable to that specific request.
Take quiz
Evaluates policies one at a time, stopping at the first match
Collects statements from every applicable policy and reasons over the union
Only ever looks at the identity's own policy
The union of every policy's permissions, with no restrictions
The intersection of everything allowed, minus anything explicitly denied
Whichever single policy was created most recently
42. How can you optimize IAM policies for a large multi-account organization?
At scale, the goal shifts from writing individual good policies to designing a system that stays correct as accounts, teams, and workloads multiply.
- Push non-negotiable guardrails to SCPs at the OU level - deny root actions, restrict regions, block leaving the organization - so they apply uniformly without relying on every account team to configure them correctly.
- Standardize on a small set of customer managed policies and permission sets deployed via IAM Identity Center or infrastructure-as-code, rather than letting each account invent its own.
- Use permissions boundaries when delegating IAM administration to account or team owners, so delegated admins can create roles freely without ever exceeding an org-defined ceiling.
- Automate policy right-sizing with IAM Access Analyzer's unused-access findings and policy generation, run on a schedule, rather than a one-time cleanup.
- Manage policies as code - version-controlled, reviewed in pull requests, and deployed through CI/CD - so changes are auditable and consistent across hundreds of accounts.
The common thread is reducing per-account manual judgment calls: the more that correct behavior is the automatic default, the less least-privilege depends on every engineer getting it right independently.
Take quiz
Individual inline policies per account
SCPs applied at the OU level
Emailing each account owner a policy document
Perform a one-time manual cleanup and never revisit it
Run IAM Access Analyzer's unused-access findings on a schedule
Grant AdministratorAccess to every new role by default
43. How do you troubleshoot a role that cannot be assumed cross-account?
Work through the chain a cross-account AssumeRole call actually depends on, checking each link:
- Caller's own policy - does the calling identity in account A have an identity-based policy that allows
sts:AssumeRoleon the specific role ARN in account B? Missing this is the single most common cause. - Target role's trust policy - does it list account A, or the specific calling principal's ARN, in its
Principalelement? A trust policy naming the wrong account ID, or a principal ARN with a typo, fails silently with a generic AccessDenied. - Conditions on the trust policy - if an
ExternalIdoraws:MultiFactorAuthPresentcondition is present, confirm the caller is actually supplying it. - SCPs in both accounts - an SCP in either account A or account B that denies
sts:AssumeRole, or restricts allowed regions or principals, blocks the call even if IAM policies look correct. - Session duration request - requesting a duration longer than the role's configured maximum session duration causes a validation error distinct from an access-denied error, which is easy to misdiagnose as a permissions problem.
CloudTrail's AssumeRole event in account B will show exactly which check failed, which is usually faster than re-reading every policy from scratch.
Take quiz
The caller's own identity policy not allowing sts:AssumeRole on that role ARN
The target account having too much free storage
CloudTrail being disabled
The role automatically extending its maximum
A validation error distinct from access-denied
The credentials being issued anyway, capped silently
44. Explain the lifecycle of an IAM role's trust relationship?
A role's trust relationship is created the moment the role itself is created - every role must have a trust policy from the start, since AWS requires knowing who can assume a role before it can exist.
flowchart LR
A["Role created with initial trust policy"] --> B["Trust policy edited as needs change"]
B --> C["Principal calls sts:AssumeRole"]
C --> D{Principal matches trust policy?}
D -- Yes --> E["Conditions checked: ExternalId, MFA, etc."]
D -- No --> F[AccessDenied]
E -- Pass --> G["Temporary credentials issued"]
E -- Fail --> F
B -.-> H["Trust policy removed/narrowed"]
H --> I["Previously trusted principal can no longer assume"]
Over the role's life, the trust policy can be edited freely - adding a new trusted account, tightening an ExternalId condition, or removing a principal entirely - and each change takes effect on the very next AssumeRole attempt, though sessions already issued before the change continue running until they expire.
If every principal is removed from the trust policy, the role becomes unassumable by anyone except, potentially, an account administrator editing the trust policy back - it isn't deleted, just permanently un-assumable until trust is restored, which is a useful technique for temporarily disabling a role without losing its permissions configuration.
Take quiz
Is optional and can be added later
Must exist from the moment the role is created
Cannot be edited after creation
Deletes the role immediately
Makes the role un-assumable while keeping its permissions configuration
Automatically restores it to AdministratorAccess
45. How can you implement least privilege at scale using IAM Access Analyzer?
Rather than hand-writing policies and hoping they're minimal, Access Analyzer supports a data-driven loop for scaling least privilege across many roles:
- Generate a starting policy from a role's actual CloudTrail activity over a chosen lookback window, using
iam:GenerateServiceLastAccessedDetails-backed analysis, so the policy reflects what the role actually calls, not a guess. - Validate the generated (or any hand-written) policy before saving, catching syntax errors, overly permissive wildcards, and security warnings automatically.
- Deploy the tightened policy, ideally through the same CI/CD pipeline used for infrastructure changes so it's reviewed like code.
- Monitor continuously using unused-access findings, which flag permissions, roles, or even entire identities that have gone quiet for a configurable period (commonly 90 days), so scope creep gets caught rather than accumulating silently.
Running this as a recurring, org-wide process - not a one-off audit - is what actually keeps hundreds or thousands of roles close to least privilege as workloads and team ownership change over time.
Take quiz
A guess at what the role might need
The role's actual CloudTrail activity
A copy of the AdministratorAccess policy
Reviewed once at initial setup and never again
Run as a recurring, ongoing process
Disabled to reduce noise
46. How does a session policy differ from an identity-based policy on a role?
An identity-based policy is permanently attached to the role and defines its standing maximum permissions - it exists whether or not anyone has assumed the role right now. A session policy is passed as a parameter to a specific AssumeRole (or related STS) call and applies only to that one resulting session.
Critically, a session policy can only narrow the role's permissions for that session - it can never grant anything beyond what the role's identity-based policies already allow. This makes session policies useful for issuing a deliberately scoped-down session from a broader role, for example, a CI/CD pipeline that assumes a broad DeployRole but passes a session policy restricting that particular run to just the one S3 prefix and Lambda function it's deploying.
Once that session's credentials expire, the session policy disappears with them; it was never saved anywhere and has no effect on the next time the same role is assumed unless a session policy is passed again.
Take quiz
Every future assumption of the role, permanently
Only the single session it was passed into
Every role in the account
Grant additional permissions beyond it
Only further narrow what that session can do
Replace the role's trust policy
47. Explain the difference between IAM policy evaluation with an SCP present versus without one?
Without any SCP, evaluation for an in-account request rests entirely on identity-based, resource-based, and boundary policies: implicit deny by default, an explicit Allow needed from at least one applicable policy, and any explicit Deny overriding everything.
With an SCP in force, an extra, mandatory ceiling is added before those account-level policies are even considered relevant. An SCP does not grant permissions on its own - even AdministratorAccess at the account level is powerless for any action the SCP doesn't explicitly allow. The account's own IAM policies are only ever able to grant a subset of what the applicable SCPs permit.
SCP allows: s3:*, ec2:* Identity policy allows: s3:*, ec2:*, iam:* Effective permissions: s3:*, ec2:* (iam:* is blocked by the SCP ceiling)
This is why an experienced administrator, when facing an unexpected Access Denied on a permission that clearly looks granted in IAM, checks for an SCP first if the account belongs to an AWS Organization - the IAM policy may be entirely correct, and the actual constraint sits one layer above it, invisible from inside the account's own IAM console unless you know to look at the organization's policies.
Take quiz
Grant more than the SCP allows, if needed
Grant a subset of what the SCP permits
Ignore the SCP entirely for AdministratorAccess
The account's billing alarms
Any SCPs applied to the account or its OU
The IAM password policy
48. How do you troubleshoot IAM policies that exceed the size limit?
IAM enforces hard character limits: 6,144 characters for a managed policy, 2,048 for an inline user policy, 10,240 for an inline role policy, and a combined limit across all managed policies attached to one identity (typically 20 managed policies per identity, with a shared character quota). Hitting these usually shows up as a validation error at save time, not a runtime failure.
- Consolidate statements - combine multiple statements that share the same
Effect,Actionlist, andConditioninto one statement with a multi-valueResourcearray, which is often the single biggest space saver. - Use wildcards judiciously in resource ARNs where the security model genuinely allows it, such as
arn:aws:s3:::app-logs-*/*instead of listing dozens of bucket ARNs individually. - Split into multiple managed policies and attach several to the same identity, since the per-policy limit is separate from the per-identity total (subject to the aggregate quota).
- Move stable, broad permissions to a permissions boundary or a shared managed policy, keeping only identity-specific exceptions in a smaller, dedicated policy.
If none of that is enough, it's often a signal the identity is doing too much and would benefit from being split into more narrowly scoped roles rather than one policy trying to cover everything.
Take quiz
A silent runtime failure with no error
A validation error at save time
An automatic policy split by AWS
Remove the Version field
Consolidate statements sharing the same Effect and Action into one, with a Resource array
Convert the policy to an SCP
49. Describe the internal working of federated access via SAML with IAM?
SAML federation lets users authenticate against a corporate identity provider (Okta, Entra ID, ADFS) and receive temporary AWS credentials without ever having an IAM user.
sequenceDiagram
participant U as User
participant IdP as Corporate IdP
participant STS as AWS STS
participant AWS as AWS Console/API
U->>IdP: Authenticate (corporate login)
IdP-->>U: SAML assertion (signed XML)
U->>STS: AssumeRoleWithSAML(assertion, RoleArn, PrincipalArn)
STS->>STS: Validate assertion signature & trust policy
STS-->>U: Temporary credentials
U->>AWS: Access AWS using temporary credentials
First, an IAM SAML identity provider object is created in AWS, importing the IdP's metadata (its signing certificate and entity ID) so IAM can validate assertions it later receives. A role's trust policy then names that identity provider as a trusted principal.
When a user signs in, the corporate IdP issues a signed SAML assertion containing the user's attributes and, typically, one or more role ARNs the user is entitled to via IdP-side group mappings. The user's client calls sts:AssumeRoleWithSAML, passing the assertion plus the chosen role and identity provider ARNs. STS cryptographically validates the assertion's signature against the stored certificate, confirms the role's trust policy permits that identity provider, and only then issues temporary credentials - the user never has an IAM identity or long-term AWS credential at any point in this flow.
Take quiz
A permanent IAM access key
A signed SAML assertion
A new IAM user automatically
Only the user's job title
The assertion's signature and the role's trust policy
The account's billing plan
50. How can you optimize an organization's IAM strategy for third-party vendor access?
Vendor access is one of the highest-risk categories precisely because you don't control the requesting side, so the design should assume the vendor's own security posture could fail and limit the damage that causes.
- Always use cross-account roles, never shared IAM user credentials - a role's trust policy can be edited or removed instantly to cut off access, while a shared access key handed to a vendor is far harder to fully retire.
- Require a unique
ExternalIdper vendor in the trust policy to prevent the confused-deputy problem, where another AWS customer of the same vendor could otherwise be tricked into triggering access to your account. - Scope permissions to only what the vendor's integration needs, validated against their documented required actions, not a broad managed policy chosen for convenience.
- Set a short maximum session duration on the role and monitor
AssumeRoleevents for that vendor's principal via CloudTrail, alerting on activity outside expected patterns. - Review vendor roles on a recurring schedule, since integrations that were scoped correctly at signup often accumulate unused permissions, or get forgotten entirely after the vendor relationship ends.
Treating every vendor role as a standing liability to be minimized and periodically re-justified, rather than a one-time setup task, is what keeps this category of access from becoming the weakest link in the account's overall security posture.