Study guide
Technical reference and lesson notes
Purpose of This Lesson
AWS IAM policy evaluation is a core topic for the AWS Certified Solutions Architect – Professional SAP-C02 exam because many architecture scenarios involve deciding where permissions should live: on an IAM identity, on an AWS resource, or on an IAM role trust relationship. This lesson focuses on the difference between identity-based policies and resource-based policies, especially for authorization, cross-account access, and role delegation.
Key Concepts
IAM Policies Control Authorization After Authentication
In AWS, authentication proves who you are. Authorization determines what you are allowed to do.
IAM policies are JSON documents that define permissions. In AWS, an “action” usually maps to an AWS API call, such as:
s3:GetObjectec2:StartInstanceslambda:InvokeFunctionkms:Decryptsqs:SendMessage
For the SAP-C02 exam, think of IAM policy design as answering three questions:
- Who is making the request?
- What action are they trying to perform?
- Which resource are they trying to access?
Identity-based and resource-based policies answer those questions from different directions.
Identity-Based Policies
Identity-based policies are attached to IAM identities:
- IAM users
- IAM groups
- IAM roles
They define what the attached identity is allowed to do.
For example, an identity-based policy attached to an IAM role might allow that role to start EC2 instances:
{
"Effect": "Allow",
"Action": "ec2:StartInstances",
"Resource": "*"
}
This policy answers the question:
What can this IAM identity do?
Where Identity-Based Policies Are Used
Identity-based policies are commonly used for permissions inside an AWS account.
Examples:
- Grant developers access to specific development resources
- Allow a billing team to view billing data
- Allow an EC2 instance role to read objects from S3
- Allow a Lambda execution role to write logs to CloudWatch Logs
- Allow an operations role to start, stop, or describe EC2 instances
For internal permissions, identity-based policies are usually the default design pattern.
AWS-Managed Policies
AWS-managed policies are prebuilt policies created and maintained by AWS.
Examples include policies for common job functions or service access patterns, such as:
- Administrator access
- Billing access
- Read-only access
- Service-specific access policies
These are useful for quick setup or common roles, but they are often broader than what a production environment should use.
Exam Perspective
AWS-managed policies may appear in exam scenarios, but for least privilege, the better answer is often a custom customer-managed policy that grants only the permissions required.
Customer-Managed Policies
Customer-managed policies are identity-based policies that you create and manage yourself.
They are reusable and can be attached to multiple users, groups, or roles.
Use customer-managed policies when you need:
- Reusable permissions
- Version control
- Centralized management
- Custom least-privilege permissions
- Standardized access patterns across teams
For enterprise environments, customer-managed policies are usually preferred over inline policies because they are easier to audit and maintain.
Inline Policies
Inline policies are embedded directly inside a single IAM user, group, or role.
They do not exist as standalone policies in the IAM policy list. They have a one-to-one relationship with the identity they are attached to.
If the identity is deleted, the inline policy is deleted with it.
When Inline Policies May Be Used
Inline policies can be useful when a permission should never be reused elsewhere and must remain tightly bound to a specific identity.
However, in most real-world environments, inline policies are harder to manage at scale.
Exam-Relevant Point
If a question emphasizes reusability, auditing, centralized management, or standardized permissions, choose a customer-managed policy, not an inline policy.
Resource-Based Policies
Resource-based policies are attached directly to AWS resources.
They define:
- Who can access the resource
- What actions those principals can perform
- Which resource the permissions apply to
A common example is an Amazon S3 bucket policy.
Resource-based policies answer the question:
Who can access this resource?
The Principal Element
A key difference between identity-based and resource-based policies is the Principal element.
Resource-based policies include a Principal because the policy must identify who is allowed to access the resource.
Example concept:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::222222222222:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
}
Identity-based policies do not include a Principal element because the principal is already known: it is the IAM user, group, or role the policy is attached to.
Exam Trap
If you see a policy with a Principal element, it is most likely a resource-based policy or a role trust policy, not a standard identity-based permissions policy.
AWS Services That Support Resource-Based Policies
Not every AWS service supports resource-based policies.
Common services that do include:
| AWS Service | Resource-Based Policy Type |
|---|---|
| Amazon S3 | Bucket policies |
| AWS Lambda | Function resource policies |
| Amazon SNS | Topic policies |
| Amazon SQS | Queue policies |
| Amazon DynamoDB | Resource policies for tables, indexes, and streams |
| AWS KMS | Key policies |
| IAM Roles | Trust policies |
Resource-based policies are especially important for services that are commonly shared across accounts or invoked by other AWS services.
Amazon S3 Bucket Policies
Amazon S3 bucket policies are one of the most common examples of resource-based policies.
They can be used to:
- Grant cross-account access to a bucket
- Allow public access when appropriate
- Require encryption
- Restrict access by VPC endpoint
- Restrict access by source IP
- Enforce TLS
- Control object-level access
For SAP-C02, S3 bucket policies are frequently used in scenarios involving centralized logging, shared data lakes, cross-account access, and organization-wide governance.
AWS Lambda Resource-Based Policies
Lambda functions can have resource-based policies that allow another service or account to invoke the function.
For example, when API Gateway is connected to a Lambda function, AWS can create permissions that allow API Gateway to invoke the function.
This is different from the Lambda execution role.
| Component | Purpose |
|---|---|
| Lambda execution role | What the Lambda function can do after it runs |
| Lambda resource-based policy | Who or what can invoke the Lambda function |
Exam-Relevant Distinction
If the question asks what permissions the Lambda function needs to access DynamoDB, S3, or CloudWatch Logs, think execution role.
If the question asks what allows API Gateway, EventBridge, or another AWS account to invoke the function, think Lambda resource-based policy.
Amazon SNS and SQS Resource Policies
SNS topic policies and SQS queue policies control who can publish to a topic or send messages to a queue.
These are commonly used in event-driven architectures.
Examples:
- Allow an S3 bucket to publish events to an SNS topic
- Allow SNS to send messages to an SQS queue
- Allow another AWS account to send messages to a queue
- Restrict message publishing to specific services or accounts
For SAP-C02, this matters in decoupled architectures where services need to communicate securely across accounts or across service boundaries.
AWS KMS Key Policies
KMS key policies are resource-based policies attached to KMS keys.
They are extremely important because access to encrypted data often depends on access to the KMS key.
A user or role may have permission to read an S3 object, but if the object is encrypted with a customer managed KMS key and the principal lacks kms:Decrypt, the read operation can fail.
Real Exam Pattern
A question may describe a cross-account S3 access issue where the bucket policy looks correct, but the object is encrypted with a KMS key.
In that case, the answer often requires updating the KMS key policy or granting KMS permissions to the external principal.
IAM Role Trust Policies
IAM roles have two important policy components:
| Policy Type | Purpose |
|---|---|
| Trust policy | Defines who can assume the role |
| Permissions policy | Defines what the role can do after it is assumed |
The trust policy is a type of resource-based policy because it is attached to the role and specifies the principals allowed to assume it.
The permissions policy is an identity-based policy because it defines the permissions granted to the assumed role session.
Cross-Account Access
Cross-account access is one of the biggest reasons to understand the difference between identity-based and resource-based policies.
There are two main patterns.
Pattern 1: Cross-Account Access Using AssumeRole
With identity-based permissions, cross-account access usually requires an IAM role.
Example:
- Account A contains a user or role.
- Account B contains a role.
- The role in Account B has a trust policy allowing the principal from Account A to assume it.
- The principal in Account A calls
sts:AssumeRole. - The assumed role session receives temporary credentials.
- The permissions policy on the role in Account B determines what the session can do.
This is the standard pattern for many enterprise cross-account designs.
Use this when you need:
- Temporary credentials
- Auditable role assumption
- Centralized access management
- Separation between accounts
- Access to many services in the target account
Pattern 2: Direct Cross-Account Access Using Resource-Based Policies
Some AWS resources can directly trust principals from another AWS account using a resource-based policy.
Example:
- Account A owns an S3 bucket.
- Account A adds a bucket policy allowing a role from Account B to run
s3:GetObject. - The role in Account B can access the bucket directly, assuming its own identity policies also allow the action.
This avoids creating a role in the resource-owning account for every access pattern.
Use this when:
- The service supports resource-based policies
- You want to grant access directly to a specific resource
- The access scope is narrow
- You are sharing resources such as S3 buckets, SQS queues, SNS topics, Lambda functions, or KMS keys
Important Cross-Account Policy Nuance
When using resource-based policies for cross-account access, the resource policy grants permission from the resource-owning side.
However, the external principal usually still needs its own identity-based permissions in its home account allowing it to make the API call.
For example, if Account B role needs to read from an Account A S3 bucket, you commonly need:
- Account A bucket policy allowing the Account B role or account.
- Account B role policy allowing
s3:GetObjecton the Account A bucket ARN.
This dual-sided permission model is a common source of real-world troubleshooting issues.
Identity-Based vs Resource-Based Policies
| Feature | Identity-Based Policy | Resource-Based Policy |
|---|---|---|
| Attached to | IAM users, groups, roles | AWS resources |
| Answers | What can this identity do? | Who can access this resource? |
Includes Principal? | No | Yes |
| Common use | Internal permissions | Resource sharing and cross-account access |
| Cross-account pattern | Usually requires sts:AssumeRole | Can grant direct access to external principals |
| Reusability | Customer-managed policies can be reused | Bound to the specific resource |
| Service support | Works broadly through IAM permissions | Only supported by certain AWS services |
| Example | Role policy allowing ec2:StartInstances | S3 bucket policy allowing another account to read objects |
Exam-Relevant Takeaways
For the SAP-C02 exam, remember these points:
- Identity-based policies are attached to IAM users, groups, and roles.
- Resource-based policies are attached directly to AWS resources.
- Identity-based policies do not use the
Principalelement. - Resource-based policies use the
Principalelement to identify who can access the resource. - AWS-managed policies are convenient but may be too broad for least privilege.
- Customer-managed policies are reusable and better for standardized access control.
- Inline policies are tightly bound to a single IAM identity and are not reusable.
- Resource-based policies are commonly used for cross-account access.
- Cross-account access with identity-based policies usually requires assuming an IAM role.
- IAM role trust policies are resource-based policies.
- IAM role permissions policies are identity-based policies.
- Lambda invocation permissions and Lambda execution permissions are different.
- KMS key policies can block access even when an S3 bucket policy or IAM policy looks correct.
- Not all AWS services support resource-based policies.
Architecture Decision Guide
| Scenario | Best AWS Choice | Why |
|---|---|---|
| Grant a team of developers the same permissions inside one AWS account | IAM group with customer-managed identity-based policy | Reusable, centralized, and easier to audit |
| Grant an EC2 instance permission to read from S3 | IAM role attached to the EC2 instance profile | Avoids long-term credentials and follows AWS best practice |
| Allow API Gateway to invoke a Lambda function | Lambda resource-based policy | Invocation permission belongs on the Lambda function |
| Allow a Lambda function to write to DynamoDB | Lambda execution role with identity-based policy | Defines what the function can do after it runs |
| Allow another AWS account to read objects from an S3 bucket | S3 bucket policy, plus required identity permissions in the external account | Resource-based policies are designed for direct resource sharing |
| Allow a user in another account to administer many resources in your account | Cross-account IAM role with trust policy and permissions policy | Better for broad access, temporary credentials, and auditing |
| Create a reusable least-privilege policy for operations staff | Customer-managed identity-based policy | Easier to update, version, and attach to multiple identities |
| Bind a one-off permission directly to a specific role | Inline policy | Useful when the permission should not be reused elsewhere |
| Control who can use a KMS key | KMS key policy, possibly combined with IAM policy | KMS access depends heavily on key policy permissions |
| Define who can assume an IAM role | Role trust policy | Trust policy is the resource-based policy attached to the role |
Common Exam Traps
Trap 1: Confusing Role Trust Policies and Role Permissions Policies
An IAM role has both:
- A trust policy that defines who can assume the role
- A permissions policy that defines what the role can do
If a principal cannot assume the role, check the trust policy.
If the assumed role cannot perform the desired action, check the permissions policy.
Trap 2: Assuming Resource-Based Policies Work for Every AWS Service
Not all AWS services support resource-based policies.
If a service does not support resource-based policies, cross-account access usually requires an IAM role and sts:AssumeRole.
Trap 3: Missing the Principal Element
Identity-based policies do not include Principal.
Resource-based policies do.
If an exam question shows a policy with a Principal, think resource policy, bucket policy, key policy, queue policy, topic policy, Lambda permission, or role trust policy.
Trap 4: Thinking arn:aws:iam::ACCOUNT-ID:root Means Only the Root User
In a resource-based policy, using an account root ARN as the principal usually represents the AWS account as a whole, not only the root user login.
This allows the account to delegate access to IAM identities inside that account.
Trap 5: Forgetting KMS Permissions
For encrypted resources, access to the resource is not always enough.
If an S3 object is encrypted with a customer managed KMS key, the principal may also need KMS permissions such as:
kms:Decryptkms:GenerateDataKeykms:DescribeKey
Trap 6: Choosing Inline Policies for Scalable Access Management
Inline policies are not reusable and are harder to audit across many identities.
For scalable enterprise access control, customer-managed policies are usually the better answer.
Trap 7: Confusing Lambda Execution Role with Lambda Invocation Permission
The Lambda execution role controls what the function can access.
The Lambda resource policy controls who can invoke the function.
These are separate permission paths.
Real-World Engineer Notes
In production AWS environments, IAM policy design has a direct impact on security, operations, troubleshooting, and governance.
Use Customer-Managed Policies for Standard Access Patterns
For a real cloud engineering team, customer-managed policies are usually easier to manage than inline policies. They can be named clearly, reviewed, versioned, and reused across roles.
Examples:
ReadOnlySecurityAuditPolicyEC2StartStopOperationsPolicyS3DataLakeReadOnlyPolicyCloudWatchLogsReadWritePolicy
This helps with audit reviews and reduces one-off permission sprawl.
Avoid Overusing AWS-Managed Administrator Policies
AWS-managed policies are helpful for labs and quick setup, but production environments should avoid broad access unless it is truly required.
For example, giving many users AdministratorAccess creates risk and makes incident response harder.
A better design is to create job-function roles with least-privilege customer-managed policies.
Resource-Based Policies Are Powerful but Easy to Misconfigure
S3 bucket policies, KMS key policies, SNS topic policies, and SQS queue policies are common sources of access issues.
When troubleshooting, verify:
- The requesting principal ARN
- The resource ARN
- The action name
- The resource policy
- The identity policy on the principal
- Any explicit denies
- Service control policies
- Permissions boundaries
- KMS key policies
- VPC endpoint policies, if applicable
Access failures are often caused by one missing layer, not by the obvious policy alone.
Cross-Account Access Should Be Designed Intentionally
For enterprise multi-account AWS environments, role assumption is often cleaner for administrative access.
Resource-based policies are better for narrow resource sharing.
Example:
- Use
sts:AssumeRolefor operations staff managing workloads across accounts. - Use an S3 bucket policy to allow a logging account to write logs into a central bucket.
- Use an SQS queue policy to allow another account to send messages into a queue.
- Use a KMS key policy to allow approved external roles to decrypt specific data.
IAM Role Design Matters for Auditability
Cross-account role assumption produces clear CloudTrail events showing the role session and source principal.
That makes it easier to investigate who accessed what.
Direct resource-based access can also be logged, but role-based access is often cleaner for human or administrative workflows.
Quick Reference Summary
Identity-based policies are attached to IAM users, groups, and roles. They define what an identity can do.
Resource-based policies are attached to AWS resources. They define who can access the resource and what actions they can perform.
Use identity-based policies for normal permissions inside an account.
Use resource-based policies for direct resource sharing, especially cross-account access.
Use IAM roles and sts:AssumeRole when cross-account access requires temporary credentials, broad access, or strong auditability.
Remember: resource-based policies include Principal; identity-based policies do not.
Flashcards
Q: What is an identity-based policy?
A: A JSON permissions policy attached to an IAM user, group, or role that defines what actions the identity can perform.
Q: What is a resource-based policy?
A: A JSON permissions policy attached directly to an AWS resource that defines which principals can access the resource and what actions they can perform.
Q: Which policy type includes the Principal element?
A: Resource-based policies include the Principal element.
Q: Why do identity-based policies not include Principal?
A: Because the policy is already attached to the identity, so the principal is implied.
Q: What is the standard cross-account access pattern using identity-based policies?
A: Use an IAM role in the target account and allow the source principal to assume it with sts:AssumeRole.
Q: What type of policy is an IAM role trust policy?
A: A resource-based policy.
Q: What does an IAM role trust policy define?
A: Who is allowed to assume the role.
Q: What does an IAM role permissions policy define?
A: What actions the role can perform after it is assumed.
Q: When should you use a customer-managed policy?
A: When you need reusable, centrally managed, least-privilege permissions.
Q: What is an inline policy?
A: A policy embedded directly into a single IAM user, group, or role that is not reusable as a standalone policy.
Q: Name three AWS services that support resource-based policies.
A: Amazon S3, AWS Lambda, Amazon SQS, Amazon SNS, AWS KMS, and Amazon DynamoDB are common examples.
Q: What controls who can invoke a Lambda function?
A: The Lambda function’s resource-based policy.
Q: What controls what a Lambda function can access after it runs?
A: The Lambda execution role.
Q: Why can KMS cause access denied errors even when an S3 bucket policy is correct?
A: The principal may have access to the S3 object but lack permission to use the KMS key for decryption.
Q: What is the best policy type for directly sharing an S3 bucket with another AWS account?
A: An S3 bucket policy, usually combined with appropriate identity permissions in the external account.
Practice Questions
Question 1:
A company has an S3 bucket in Account A. A role in Account B needs to read objects from the bucket. The company wants to grant access directly to the bucket without creating a role in Account A. Which policy should be used?
A. IAM group policy in Account A
B. S3 bucket policy in Account A
C. Inline policy attached to the root user in Account A
D. Service control policy attached to Account B
Correct Answer:
B. S3 bucket policy in Account A
Explanation:
An S3 bucket policy is a resource-based policy and can directly grant access to principals from another AWS account. The role in Account B may also need its own identity-based policy allowing s3:GetObject.
Question 2:
An IAM role exists in Account B. A user in Account A needs to assume the role. Which policy controls whether the user is allowed to assume the role?
A. The role trust policy
B. The role permissions policy
C. The user’s MFA policy
D. The S3 bucket policy
Correct Answer:
A. The role trust policy
Explanation:
The trust policy is the resource-based policy attached to the IAM role. It defines which principals are allowed to assume the role.
Question 3:
A Lambda function needs to write items to a DynamoDB table. Where should the permission be granted?
A. Lambda resource-based policy
B. Lambda execution role
C. API Gateway resource policy
D. IAM user inline policy
Correct Answer:
B. Lambda execution role
Explanation:
The Lambda execution role defines what the function can do after it runs. Writing to DynamoDB requires permissions such as dynamodb:PutItem on the execution role.
Question 4:
A policy document contains a Principal element. What does this usually indicate?
A. It is an identity-based policy
B. It is an AWS-managed policy only
C. It is a resource-based policy or role trust policy
D. It is invalid JSON for IAM
Correct Answer:
C. It is a resource-based policy or role trust policy
Explanation:
The Principal element identifies who is allowed access. Identity-based policies do not need this element because they are already attached to the principal.
Question 5:
A company wants to create a reusable least-privilege permissions policy for its cloud operations team. The same permissions will be attached to multiple roles. Which policy type is most appropriate?
A. Inline policy
B. Customer-managed identity-based policy
C. Resource-based policy
D. Lambda resource policy
Correct Answer:
B. Customer-managed identity-based policy
Explanation:
Customer-managed policies are reusable and centrally managed. Inline policies are attached to a single identity and are not ideal for scalable access management.