Currently, S3 GET and PUT actions allow users to upload anything from their local environment into S3 buckets. I am interested in restricting this.
Imagine I have two buckets:
- One called
landing-zone, which can be used by data engineers to GET and PUT objects from their local environment or all other buckets. - One called
analysis, which can only be used by data analysts to PUT objects which originate from thelanding-zoneoranalysisS3 bucket. (Ideally, analysts would be able to take data from thelanding-zoneoranalysisS3 bucket, modify it, and PUT it back intoanalysisS3.)
I created separate access points for the landing-zone and analysis S3 buckets and then created S3 bucket policies for each, for an analyst user, using the following format.
{
"Version": "2012-10-17",
"Statement" :
[
{
"Effect": "Allow",
"Principal" : {"AWS": "arn-user-analyst-name"},
"Action" : "s3:*",
"Resource" : "access-point-arn-landing-zone",
"Condition": {"StringEquals": {"s3:DataAccessPointAccount": "aws-account-id"}}
}
]
}
I then created an IAM access policy for analysts with the following S3 permissions.
...
{
"Sid": "AccessAllS3Settings",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketVersioning",
"s3:GetBucketPolicyStatus",
"s3:GetBucketPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:GetBucketAcl",
"s3:GetObjectAcl",
"s3:ListAccessPointsForObjectLambda",
"s3:ListBucketMultipartUploads",
"s3:ListAccessPoints",
"s3:GetAccessPoint",
"s3:CreateAccessPoint",
"s3:ListJobs",
"s3:CreateJob",
"s3:ListStorageLensConfigurations",
"s3:PutStorageLensConfiguration",
"s3:ListMultipartUploadParts",
"s3:ListMultiRegionAccessPoints",
"s3:GetBucketPolicy",
"s3:GetBucketLogging",
"s3:GetBucketNotification",
"s3:GetBucketLocation",
"s3:GetEncryptionConfiguration"
],
"Resource": "*",
"Condition": {"StringEquals": {"aws:RequestedRegion": "ap-southeast-2"}}
},
{
"Sid": "GetAllS3Buckets",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetObjectVersionAttributes",
"s3:GetObjectAttributes"
],
"Resource": [
"arn:aws:s3:::landing-zone",
"arn:aws:s3:::landing-zone/*",
"arn:aws:s3:::analysis",
"arn:aws:s3:::analysis/*"
],
"Condition": {"StringEquals": {"aws:RequestedRegion": "ap-southeast-2"}}
},
{
"Sid": "PutAnalysisS3BucketLimitedBySource",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::analysis",
"arn:aws:s3:::analysis/*"
],
"Condition": {
"StringEquals": {"aws:RequestedRegion": "ap-southeast-2"},
"ForAnyValue:StringEquals": {"s3:DataAccessPointArn": [
"access-point-arn-landing-zone>",
"access-point-arn-analysis>"
]}
}
}
...
However, when I test this policy as an analyst, copying an existing test dataset from the landing-zone to analysis S3 bucket fails i.e. aws s3 cp s3://landing-zone/test.txt s3://analysis/test.txt --sse AES256 produces An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied.
I can open datasets in the landing-zone to analysis S3 buckets fine.
What am I doing wrong?
