Topic 1.3
Identity-Based vs Resource-Based Policies
In one line
Identity-based policies attach to a user/group/role and say what that identity can do; resource-based policies attach to a resource like an S3 bucket or SQS queue and say who can touch it — and cross-account access usually needs both sides to agree.
Think of it like this
To enter a private club, your EMPLOYER may give you a letter saying 'this person may attend client events' (an IDENTITY-BASED policy — travels with you), and the CLUB keeps a guest list saying who may enter (a RESOURCE-BASED policy — lives on the door). Inside your own company, one is usually enough. Visiting a different company's club, you typically need both: your employer's permission AND your name on their list.
Key ideas
- 01
IDENTITY-BASED policies attach to a user, group, or role — they have no
Principalfield, because the principal is implied: whoever the policy is attached to. Everything in Topic 1.1 was identity-based. - 02
RESOURCE-BASED policies attach to a resource — S3 bucket policies, SQS queue policies, SNS topic policies, KMS key policies, Lambda function policies, and a role's own trust policy (which is really a resource policy on the role). They DO have a
Principalfield naming who is allowed. - 03
Within ONE account, an allow in EITHER the identity policy OR the resource policy is generally enough. ACROSS accounts, both must allow: account B's bucket policy must name account A's role, AND account A's role must have an identity policy allowing that action on B's bucket.
- 04
KMS keys are the notable exception: the key policy is the primary control. If a key policy doesn't delegate to IAM (via the
arn:aws:iam::<account>:rootprincipal), no identity policy in the account can grant use of that key — a common cause of confusing 'AccessDenied' errors on encrypted resources. - 05
Two guardrails sit ABOVE these and can only restrict, never grant: SERVICE CONTROL POLICIES (SCPs) in AWS Organizations cap what any identity in an account can ever do (e.g. 'nobody may leave ap-south-1'), and PERMISSION BOUNDARIES cap what a specific user/role can ever be granted — useful for letting teams create their own roles without letting them escalate beyond a ceiling.
Code & diagrams
Resource-based: lives on the bucket, names the other account's role as Principal. That role still needs its own identity policy allowing s3:GetObject here.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAnalyticsAccountRead",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::444455556666:role/analytics-etl" },
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::acme-events/*"
},
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::acme-events", "arn:aws:s3:::acme-events/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}
]
}An SCP. It grants nothing — it removes the ability to act outside allowed regions, even for admins. Global services like IAM are excluded so they keep working.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyOutsideApprovedRegions",
"Effect": "Deny",
"NotAction": ["iam:*", "sts:*", "organizations:*", "support:*", "cloudfront:*", "route53:*"],
"Resource": "*",
"Condition": {
"StringNotEquals": { "aws:RequestedRegion": ["ap-south-1", "us-east-1"] }
}
}
]
}A request succeeds only if nothing in any layer denies it and the relevant allow exists.
Explain it without notes
Why does cross-account S3 access typically require BOTH a bucket policy and an identity policy, when same-account access usually needs only one?
An account admin has AdministratorAccess but still gets AccessDenied launching an EC2 instance in eu-west-1. What's the most likely cause?
Practice
Name three AWS resources that support resource-based policies.
A Lambda function in account A must send messages to an SQS queue in account B. What two policies do you need to write, and where does each live?
Trade-offs
- ↔
Resource policies make cross-account sharing simple and keep access rules next to the data, but they scatter permissions across many resources — answering 'what can this role reach?' now requires checking bucket, queue, and key policies too. IAM Access Analyzer exists specifically to surface these externally-shared resources.
Done when you can
I can tell an identity-based policy from a resource-based one by the presence of
Principal.I know cross-account access needs both sides to allow.
I understand SCPs and permission boundaries only restrict — they never grant.
I know KMS key policies are the primary control for key access.