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:

Note that you can use AWS CloudTrail to track how access and policies are being used by users and roles.

Here's very simple policy as an example:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

This policy allows all S3 actions on any bucket resource (which is very permissive and may not adhere to the least privilege principle!). After defining a policy such as this one, you would then attach it to one or more principals.

A principal refers to an entity that can make a request to AWS resources.

Types of Principals

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:

The policy above is an identity based policy because it would be attached to an identity.

Resource-based policies:

Here is a resource based policy because it is appliect to a specific resource (a specific S3 bucket):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-public-bucket/*"
    }
  ]
}

Because the Principal is set to a wildcard, this policy allows public access to read a specific S3 bucket.

You can combine identity and resource-based policies, for example an identity-based policy might grant an IAM user broad permissions to an AWS account, but a resource-based policy on a specific S3 bucket could further restrict access to only certain actions or specific identities.

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.

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 Principal, 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.)