Home > Back-end >  Why is my S3 bucket policy denying cross account access?
Why is my S3 bucket policy denying cross account access?

Time:10-14

I have an S3 bucket located in account A.

This bucket is shared with account B using ACL grant with account B's canonical id (with all permissions).

When the bucket policy is empty, EC2 instances from account B are able to list the S3 bucket on account A.

The bucket is public and I want to grant access to specific public IPs and a specific VPC configured on account A.

This is the bucket policy:

{
    "Version": "2012-10-17",
    "Id": "S3_Bucket_Policy",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::Account_B_Number:role/EC2_Role"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::s3_bucket_name",
                "arn:aws:s3:::s3_bucket_name/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::s3_bucket_name",
                "arn:aws:s3:::s3_bucket_name/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:SourceVpc": "vpc_id"
                },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "67.100.20.15/32",
                        "79.190.30.2/32"
                    ]
                }
            }
        }
    ]
}

I can access the S3 bucket from the below IP addresses and the specified VPC however, I can't access the bucket from account B's EC2 instances.

The EC2 instances have the below assigned role with the following policy:

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

Why can't I access the bucket in account A from account B?

CodePudding user response:

You have an explicit Deny statement in your S3 bucket policy, which is overriding the Allow statement so change your Deny statement to allow account B's role principal.


This policy evaluation logic is highlighted in the enter image description here

In this case, you are falling into the first red block which will make the final decision a Deny.


Change your StringNotEquals to also check for the aws:PrincipalArn of account B's role so the policy doesn't deny account B's role anymore:

"Condition": {
    "StringNotLike": {
        "aws:SourceVpc": "vpc_id",
        "aws:PrincipalArn": "arn:aws:iam::Account_B_Number:role/EC2_Role"
    },
    "NotIpAddress": {
        "aws:SourceIp": [
            "67.100.20.15/32",
            "79.190.30.2/32"
        ]
    }
}

Full working example:

{
    "Version": "2012-10-17",
    "Id": "S3_Bucket_Policy",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::Account_B_Number:role/EC2_Role"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::s3_bucket_name",
                "arn:aws:s3:::s3_bucket_name/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::s3_bucket_name",
                "arn:aws:s3:::s3_bucket_name/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:SourceVpc": "vpc_id",
                    "aws:PrincipalArn": "arn:aws:iam::Account_B_Number:role/EC2_Role"
                },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "67.100.20.15/32",
                        "79.190.30.2/32"
                    ]
                }
            }
        }
    ]
}
  • Related