I needed this for a scenario where the client could not authenticate to S3 but still needed to be able to download files from the S3. So I created this policy which allows all files to be downloaded but restricts access to the download action (s3:GetObject) by source IP. Since we knew the specific filenames, we did not need list functionality.
Notes:
- Block public access (bucket settings) MUST be disabled/OFF for this to work.

AWS S3 block public access settings - All boxes should be unchecked
- This is a S3 Bucket Policy and is applied directly to the bucket.
- Bucket > Permissions > Bucket Policy
- The policy grants all (public) access to download all files from the bucket.
- The policy restricts access to the download action to specific IPs.
- The policy does not grant read or list actions.
- Note:
/32(at the end of the IPs) is CIDR notation for “only one ip”, specifying it is NOT a range of IPs.
Line notes:
- Line 3
Id= Name of the policy, no spaces allowed - Line 6
Sid= Closest thing to a comment allowed in a policy. No spaces. - Line 10
Resource= This is where you identify the bucket and file(s)./*for all files in the bucket.- Or you can identify a specific file or files
- Line 14, 15 (and as many as needed) = IP addresses to be allowed access.
- Notice that the last IP does not have a comma at the end. Has to be proper JSON formatting
- 1 IP per line.
Template:
{
"Version": "2012-10-17",
"Id": "S3AllowList",
"Statement": [
{
"Sid": "S3-Alllow-List",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<s3-bucket>/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"###.###.###.###/32",
"###.###.###.###/32"
]
}
}
}
]
}
