If I have a bucket with this policy:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "EB73SOC545AIK",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EB73SOC545AIK"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket-app-dev-bucket/*"
}
]
}
And I delete the CloudFront distribution that use OAI EB73SOC545AIK something automatically update my bucket policy with this value
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "EB73SOC545AIK",
"Effect": "Allow",
"Principal": {
"AWS": "AIDAIHJ7YKCENOC6XHCIQ"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket-app-dev-bucket/*"
}
]
}
It is a malformed policy.
This is very annoying because happened without you noticed, and later if you use boto3 to append a new statement (without change the previews one) for example like this:
client = boto3.client('s3')
pol = client.get_bucket_policy(Bucket=bucket)['Policy']
pol = json.loads(pol)
pol['Statement'].append(....)
client.put_bucket_policy(
Bucket=bucket,
Policy=json.dumps(bucket_policy)
)
you get a MalformedPolicy error and you waste a lot of time checking your new statement when the real problem is other statement.
How can avoid this?
IAM always uses its internal unique identifiers when referencing principals, when you put a role in the policy IAM will store not the role name or arn but the unique identifier, similar to AIDAIHJ7YKCENOC6XHCIQ
. And IAM checks if the identifier in the policy actually exists, which it does not in your case. Therefore the policy is rejected.
The purpose of this is that if you grant permissions to user Lukas, then Lukas leaves your company, you delete the user, later a new Lukas joins, you create a new user Lukas - then the new Lukas should not have permissions that were initially granted to the old Lukas. But that would happen if you only checked / compared the name / arn and not the internal identifier.
Solution: do not use an OAI
but instead add a condition checking the CloudFront distribution (best practice anyway): https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3