Demystifying AWS IAM Policies: Unraveling De Morgan’s Laws and S3 Buckets Policy

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