S3 has three separate mechanisms:
| Mechanism | Description | Example |
|---|---|---|
| Bucket policies | JSON policies attached to buckets | ”allow public read from this bucket” |
| IAM/Identity policies | Policies attached to users/roles | ”user Alice can read bucket X” |
| Object ACLs | Per-object access control lists | ”this specific object is readable by user Bob” |
Bucket policy
Here’s what one looks like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:user/alice",
"arn:aws:iam::123456789012:user/bob",
"arn:aws:iam::123456789012:role/data-processor"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/documents/*",
"Condition": {
"IpAddress": { "aws:SourceIp": "192.0.2.0/24" }
}
}
]
}Identity policy
This is syntactically like a Bucket policy but it has no Principal field because it is bound to a principal.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-bucket/documents/*",
"Condition": {
"IpAddress": {"aws:SourceIp": "192.0.2.0/24"}
}
}
]
}Object ACL
These things are ugly and deprecated.
<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy>
<Owner>
<ID>79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be</ID>
<DisplayName>bucket-owner</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="CanonicalUser">
<ID>79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be</ID>
<DisplayName>bucket-owner</DisplayName>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="CanonicalUser">
<ID>a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2</ID>
<DisplayName>alice</DisplayName>
</Grantee>
<Permission>READ</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>The ID tag (a1b2c3d4e... for alice) is a canonical user ID which is equivalent to arn:aws:iam::123456789012:user/alice. You can use these canonical user IDs in bucket policies if you want; that would look like "Principal": { "CanonicalUser": "a1b2c3d4e....