Demystifying AWS IAM Policies: Unraveling De Morgan’s Laws and S3 Buckets Policy¶
Condition Evaluation¶
Before we get into it we need to review how Condition evaluation works:
The images on this page does a nice job of summarizing.
New IAM Deny reason Error Messages¶
As of September 2021 You will now get error messages that detail the source of a IAM access block for the following policy types:
SCP
VPC Endpoint policy
Permission Boundaries
Session Policies
Resource Based policy
Identity Based policy
This saves a lot of time especially if you do not have access to all of these.
When there is no additional context¶
For S3 if you do not have permission on the default KMS key that is configured
on the bucket you will get an AccessDenied
with no further information.
A good indicator of this is if you can list_objects
which requires no KMS
permission. If that works, but PutObject
or GetObject
give AccessDenied
check very closely that say your lambda role has permission to use the default
KMS key of the bucket.
De Morgan’s laws and IAM¶
We all know that multiple conditions in a IAM Condition statement are joined by logical AND. Having an understanding of using Not operator conditions in AWS IAM policy by applying De Morgans laws can give you powerful flexibility, that can be mind boggling to read and understand.
Lets take a look at this example policy. Have a think about what will happen if you access it using the named role via the internet S3 endpoint.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyNonVPCAccessExceptNamedRole",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": ["vpc-123", "vpc-456"]
},
"ArnNotEquals": {
"aws:PrincipalArn": "arn:aws:iam::12345678902:role/role_that_cannot_use_vpc"
}
}
}
]
}
This Bucket policy will deny all access unless it is from the named VPC - If the
role is arn:aws:iam::12345678902:role/role_that_cannot_use_vpc
and not from a
VPC allow it.
Lets break it down:
The StringNotEquals condition for aws:sourceVpc
ensures that the request’s
source VPC is not equal to vpc-123
. The ArnNotEquals
condition for
aws:PrincipalArn
checks if the request’s principal ARN is not equal to
arn:aws:iam::12345678902:role/role_that_cannot_use_vpc
. if you access the
bucket using the role called role_that_cannot_use_vpc
and do not access it
from the VPCs listed in the policy:
If bucket is accessed from a VPC other than vpc-123
using the role
role_that_cannot_use_vpc
the StringNotEquals
condition for aws:sourceVpc
evaluates to true since the VPC ID does not match. However, the ArnNotEquals
condition for aws:PrincipalArn
evaluates to false since the principal ARN
matches the specified role ARN. As a result, the deny statement is not
triggered, and access to the bucket is allowed.
If bucket is accessed from VPC vpc-123
but not using the role
role_that_cannot_use_vpc
, the StringNotEquals
condition for aws:sourceVpc
evaluates to false since the VPC ID matches. The ArnNotEquals
condition for
aws:PrincipalArn
evaluates to true since the principal ARN does not match the
specified role ARN. The deny statement is not triggered, and access to the
bucket is allowed.
If bucket is accessed from a VPC other than vpc-123
and using a role other
than role_that_cannot_use_vpc
, both conditions (StringNotEquals
for
aws:sourceVpc
and ArnNotEquals
for aws:PrincipalArn
) evaluate to true.
Consequently, the deny policy statement is not triggered, and access to the
bucket is allowed.
Comments
comments powered by Disqus