amazon-web-servicesamazon-s3amazon-iamamazon-s3-access-points

Authorize a role to Amazon S3 through access point


The goal is to limit an Amazon S3 Read-Write (list,get,put,delete) access to a single role and access S3 only through access point, with a bucket policy locked to access point only.

The setup I did so far is

but experience AccessDenied on any of the mentioned operations

here is S3 Bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AuthorizeS3ObjectsReadModifyThroughAccessPointsOnly",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::XXX-YYY-ZZZ/*",
            "Condition": {
                "ForAllValues:StringNotEquals": {
                    "s3:DataAccessPointArn": "arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ"
                }
            }
        },
        {
            "Sid": "AuthorizeS3ObjectsListThroughAccessPointsOnly",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::XXX-YYY-ZZZ",
            "Condition": {
                "ForAllValues:StringNotEquals": {
                    "s3:DataAccessPointArn": "arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ"
                }
            }
        }
    ]
}

and here is the access point policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AuthorizeReadModifyS3ObjectsThroughSpecificRoleOnly",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ/object/*",
            "Condition": {
                "ForAllValues:StringNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::XXX-YYY-ZZZ:role/XXX-YYY-ZZZ"
                }
            }
        },
        {
            "Sid": "AuthorizeListS3ObjectsThroughSpecificRoleOnly",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ",
            "Condition": {
                "ForAllValues:StringNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::XXX-YYY-ZZZ:role/XXX-YYY-ZZZ"
                }
            }
        }
    ]
}

and here is the role policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadModifyS3Objects",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ/object/*",
            ]
        },
        {
            "Sid": "ListS3Objects",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ"
            ]
        }
    ]
}

This does not work - AccessDenied. I'm testing with a proper role assumed and for example with this command aws s3 ls "s3://arn:aws:s3:us-east-1:XXX-YYY-ZZZ:accesspoint/XXX-YYY-ZZZ/"

What is strange is that if the role policy resources are extended with S3 bucket ARN (like arn:aws:s3:::XXX-YYY-ZZZ/* and arn:aws:s3:::XXX-YYY-ZZZ) so both access and s3 bucket resources are present then the access is allowed. And if remove any of the accesspoint resource makes the AccessDenied appear again. Can not understand this, seems I'm missing something fundamental, will be very grateful for any pointers in docs or solution/advice.


Solution

  • None of your policies actually allows the operations in S3. You have only denies. So naturally, your role has no permission to access S3. From docs:

    Permissions granted in an access point policy are only effective if the underlying bucket also allows the same access.

    This means that having Allow in your role for access point resources is not enough.

    What is strange is that if the role policy resources are extended with S3 bucket

    Permissions to access S3 access point are not a replacement for actually having permissions to access S3. Thus your role needs both permissions for S3 access point and the actual s3 bucket and objects themself.