Skip to content

Instantly share code, notes, and snippets.

@jhrr
Forked from magnetikonline/README.md
Created October 19, 2023 15:23
Show Gist options
  • Save jhrr/f2f40d95a2c9c532fb7399156bb7d724 to your computer and use it in GitHub Desktop.
Save jhrr/f2f40d95a2c9c532fb7399156bb7d724 to your computer and use it in GitHub Desktop.
AWS S3 bucket and IAM policy recipes.

AWS S3 bucket and IAM policy recipes

Recipes

Anonymous GET access

Type: bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "*"
        ]
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    }
  ]
}

Anonymous GET access - match HTTP referrer

Type: bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject"
      ],
      "Condition": {
        "StringLike": {
          "aws:Referer": [
            "http://domain.com/*",
            "http://www.domain.com/*"
          ]
        }
      },
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "*"
        ]
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    }
  ]
}

Full access for specific IAM user/role

Type: bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:*"
      ],
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::ACCOUNT_ID:user/USERNAME_A",
          "arn:aws:iam::ACCOUNT_ID:user/USERNAME_B",
          "arn:aws:iam::ACCOUNT_ID:user/USERNAME_C",
          "arn:aws:iam::ACCOUNT_ID:role/ROLE_A",
          "arn:aws:iam::ACCOUNT_ID:role/ROLE_B",
          "arn:aws:iam::ACCOUNT_ID:role/ROLE_C"
        ]
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME",
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    }
  ]
}

GET/PUT/DELETE access to specific path within a bucket

Type: user/group/role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME"
      ]
    },
    {
      "Action": [
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/BUCKET_PATH/*"
      ]
    }
  ]
}

Note: The s3:ListBucket action against the bucket as a whole allows for the listing of bucket objects.

Restricted LIST & PUT/DELETE access to specific path within a bucket

Type: user/group/role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:ListBucket"
      ],
      "Condition": {
        "StringEquals": {
          "s3:delimiter": ["/"],
          "s3:prefix": ["","BUCKET_PATH/"]
        }
      },
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME"
      ]
    },
    {
      "Action": [
        "s3:ListBucket"
      ],
      "Condition": {
        "StringLike": {
          "s3:prefix": ["BUCKET_PATH/BUCKET_SUB_PATH/*"]
        }
      },
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME"
      ]
    },
    {
      "Action": [
        "s3:DeleteObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/BUCKET_PATH/BUCKET_SUB_PATH/*"
      ]
    }
  ]
}

Note: This policy effectively provides protected user folders within an S3 bucket:

  • The first s3:ListBucket action allows listing only of objects at the bucket root and under BUCKET_PATH/.
  • The second s3:ListBucket action allows listing of objects from the path of BUCKET_PATH/BUCKET_SUB_PATH/ and below.
  • Technique is covered here under the heading Block 2: Allow listing objects in root and home folders.

Full access (and S3 console) for specific IAM users

Type: user/group/role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:ListAllMyBuckets"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::*"
      ]
    },
    {
      "Action": [
        "s3:*"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    }
  ]
}

Bucket and object delete deny

Type: bucket

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "s3:DeleteBucket",
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    },
    {
      "Action": "s3:DeleteObject",
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    }
  ]
}

CloudTrail log receive

Type: bucket

See: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetBucketAcl"
      ],
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:cloudtrail:AWS_REGION:AWS_ACCOUNT_ID:trail/TRAIL_NAME"
        }
      },
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ]
    },
    {
      "Action": [
        "s3:PutObject"
      ],
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:cloudtrail:AWS_REGION:AWS_ACCOUNT_ID:trail/TRAIL_NAME",
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      },
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/AWSLogs/AWS_ACCOUNT_ID/*"
      ]
    }
  ]
}

CloudFront origin access control (OAC) GET access

Type: bucket

See: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "s3:GetObject",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Resource": [
        "arn:aws:s3:::BUCKET_NAME/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:cloudfront::AWS_ACCOUNT_ID:distribution/DISTRIBUTION_ID"
        }
      }
    }
  ]
}

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment