AWS Permission Policy Examples and Notes
Before diving in it's good to know a few things:
A permission policy specifies a Statement which consists of:
- An Effect (which will be allow or deny)
- An Action (which is the action controlled by the Effect)
- A Resource (which is the resource upon with the action(s) are allowed or denied)
Here's very simple policy as an example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
QUESTIONS (my AI helpers are giving me conflicting answers!!!)
- Because this policy does not specivy a principal, would it allow access to anyone on the internet?
- Is it true that this policy could not be resource-based because it does not specify a specific S3 bucket. In other words, must a resource-based policy always be applied to a specific resource?
This policy allows all S3 actions on any bucket resource. After defining a policy such as this one, you would then attach it to one or more principals.
A principal is who/what you assign/attach the policy to. Principals can be:
- IAM users or groups
- IAM roles
- A federated identity
- An AWS service (ex: an EC2 instance might need a permission policy attached to it so that it can access an AWS service)
A trust policy is a document that lists the principals that you assign a permission policy to.
A permission policy might also specify one more more principals, so there would be no need for a trust policy. If a permission policy specifies principals, it is usually known as a resource-based policy.
Identity-based policies:
- Are attached to identities (users, groups, roles).
- The principals must be within the AWS account The permission policy above could be a
Resource-based policies:
- Specifies a specific resource
- Usually specifies one or more principals ex: Principal: {"AWS": "arn:aws:iam::987654321098:someUser"}
- They can be used to allow access to resources from other AWS accounts
- If a resource-based policy does not specify a Principal, it is known as an anonymous or unrestricted policy, which means that the allowed actions specified in the policy can be performed by any principal that has been granted permission to access the resource through other means, such as an identity-based policy.
There are other types of policies, such as session, permission boundary, service control policies (SCP), but I'm not worried about them right now.
There's also inline policies that are attached directly to a role or resource and cannot be re-used.
Here's what really confused me!
I would look a policy file and ask 'is this resource-based, or identity-based?'. Apparently, a single policy could be either resource-based, or identity-based depending on how it's used. If it's attached to an identity, then it's identity-based. If specifies a principal then I believe it must be resource-based.
Apparently, if a permission policy specifies a principal, you could still create a trust policy for it that specifies additional principals.
S3
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Type: Identity-Based Policy (applied to an identity: user, group, role)
Description: This is a managed or customer-managed policy that can be attached to an IAM user, group, or role. It grants full access to S3 for any identity that has this policy attached.
Here's another example, which is also identity-based:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::my-example-bucket", // the bucket which can be listed
"arn:aws:s3:::my-example-bucket/*" // the objects that can be gotten
]
}
]
}
Description: Grants access to list objects, and get objects from a specific S3 bucket for any identity that has this policy attached.
Here is a resource-based policy that is attached to an S3 bucket (note that it specifies a Principal):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::987654321098:someUser"
// note that the number is an aws account id, which may be a different than your own
// this allows you set permissions to other AWS accounts
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-example-bucket",
"arn:aws:s3:::my-example-bucket/*"
]
}
]
}
Remember that if a resource-based policy does not specify a Principaly, then it will be applied to all principals that have access to the resource through some other meains, such as an identity-base policy. Resource policies that do not specify a Principal are known as annonymous or unrestricted.
Here is a resource-based policy that allows anyone to get objects from an S3 bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*", // applies to ALL principals, even all users on the internet
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-public-bucket/*"
}
]
}
This one allows any S3 action on a bucket where the request is coming from a specific subnet:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-secure-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.0.2.0/24"
}
}
}
]
}
Type: Resource-Based Policy or Identity or Both???????? Here's what I got from Codeium: So, to answer your question, yes, it's possible that this policy could be an identity-based policy if it were attached to an IAM user or role. The policy's type (identity-based or resource-based) depends on how it's used and attached, rather than just its contents.
EC2
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEC2InstanceAccess",
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:DescribeInstances"
],
"Resource": "arn:aws:ec2:REGION:ACCOUNT_ID:instance/i-0123456789abcdef0"
}
]
}
Type: UNRESTRICTED Resource-Based Policy or Identity-Based
Description: Allows any principals that have access to the instance to stop, start, and describe details about it. This policy can also be both a resource-based policy and an identity-based policy, depending on how it's used. If it's attached to the EC2 instance with ID i-0123456789abcdef0, it would be a resource-based policy, controlling access to that specific instance. If it's attached to an IAM user or role, it would be an identity-based policy, granting permissions to the user or role to start, stop, and describe the specified EC2 instance. So, the same policy can serve different purposes depending on how it's used!
DynamoDB
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan"
],
"Resource": "*"
}
]
}
Type: Identity-Based Policy
Description: Allows the principals to get items, query, and scan all DynamoDB tables within the AWS account.
Note: You could turn this policy to resource-based by specifying a specific arn for the resource (but if the resource is a specific table, then there are some weird exceptions - apparently DynamoDB does not directly support resource-based policies for tables in the same way.)