Create a least privilege S3 bucket policy

Scenario:

You’re tasked with locking down access to a ‘sensitive-app-data’ bucket so that only these principals have access:

  • Administrators: admin (role), ci (user) - to administer the bucket
  • Application: app (role) - read & write data to/from bucket
  • Support: cust-service (role) - to read data
Administrators,
Customer Service
Continuous
Integration &
Delivery

Process of granting least privilege

First, deny access to the bucket and its objects to everyone who is not one of the intended principals:

{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "DenyEveryoneElse",      "Effect": "Deny",      "Action": "s3:*",      "Resource": [        "arn:aws:s3:::sensitive-app-data/*", "arn:aws:s3:::sensitive-app-data"      ],      "Principal": {        "AWS": "*"      },      "Condition": {        "ArnNotEquals": {          "aws:PrincipalArn": [            "arn:aws:iam::111:user/ci", "arn:aws:iam::111:role/cust-service",            "arn:aws:iam::111:role/app", "arn:aws:iam::111:role/admin"          ]        }      }    },

Then, grant the administrators privileges to administer the bucket:

{  "Sid": "AllowRestrictedAdministerResource",  "Effect": "Allow",  "Action": [    "s3:PutBucketPolicy",    "s3:PutBucketAcl"  ],  "Resource": [    "arn:aws:s3:::sensitive-app-data/*",    "arn:aws:s3:::sensitive-app-data"  ],  "Principal": {    "AWS": "*"  },  "Condition": {    "ArnEquals": {      "aws:PrincipalArn": [        "arn:aws:iam::111:user/ci",        "arn:aws:iam::111:role/admin"      ]    }  }},

Now, allow the application and customer support roles to read:

{  "Sid": "AllowRestrictedReadData",  "Effect": "Allow",  "Action": [    "s3:GetObject",    "s3:ListBucket"  ],  "Resource": [    "arn:aws:s3:::sensitive-app-data/*",    "arn:aws:s3:::sensitive-app-data"  ],  "Principal": {    "AWS": "*"  },  "Condition": {    "ArnEquals": {      "aws:PrincipalArn": [        "arn:aws:iam::111:role/cust-service",        "arn:aws:iam::111:role/app"      ]    }  }},

Then, allow the application to write data into the bucket:

{  "Sid": "AllowRestrictedWriteData",  "Effect": "Allow",  "Action": [    "s3:AbortMultipartUpload",    "s3:PutObject"  ],  "Resource": [    "arn:aws:s3:::sensitive-app-data/*",    "arn:aws:s3:::sensitive-app-data"  ],  "Principal": {    "AWS": "*"  },  "Condition": {    "ArnEquals": {      "aws:PrincipalArn": "arn:aws:iam::111:role/app"    }  }}  ]}

Add other policy enforcements here such as requiring encryption in transport and at rest

Pro Tip:

Organize statements by capabilities granted to principals so you can track who has those capabilities over time.

For you to only grant access to intended principals and resources, two things should be included in your security policies:

  1. Identity policies attached to principals should scope resource access to implement the least privilege for the principal
  2. Resource policies should allow intended principals and explicit deny everyone else to implement the least privilege for the resources

Use this cheat sheet with AI

Copy a ready-to-use prompt into your preferred AI assistant.

Preview prompt