How do I use wildcards with a Principal element and explicit deny in an Amazon S3 bucket policy?

Last updated: 2021-08-16

I want to use wildcards with a Principal element and an explicit deny in an Amazon Simple Storage Service (Amazon S3) bucket policy. How can I do that?

Short description

To prevent certain AWS Identity and Access Management (IAM) entities from accessing your Amazon S3 buckets, designate specific permissions in a bucket policy. The bucket policy must use a NotPrincipal element and an explicit deny. For more information, see using NotPrincipal with Deny.

However, because wildcards aren't supported with the NotPrincipal element, you must use Principal as the target entity in each statement block. Each statement block must also include the condition for each allow block.

Resolution

Instead of using NotPrincipal, use Principal as the target entity in each statement block, which includes the condition for each allow block.

Before beginning, you must have the following resources:

In this example, wildcards are used in aws:userid to include all names that are passed by the calling process. For example, the wildcards are used for an application, service, or instance ID when calls are made to obtain temporary credentials. For more information, see Information available in all requests. The AWS account root user is included to prevent lockout.

Note: Be sure that you replace the example names with your own role IDs and bucket names.

StringNotLike in the deny block:

"Condition": {
        "StringNotLike": {
          "aws:userid": [
            "AROAID2GEXAMPLEROLEID:*",
            "444455556666"
          ]
        }
      }

Here is the complete policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::444455556666:role/s3-access-role"
        ]
      },
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::awsexamplebucket1"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::444455556666:role/s3-access-role"
        ]
      },
      "Action": [
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::awsexamplebucket1/*"
    },
    {
      "Sid": "",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:ListBucket",
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::awsexamplebucket1/*",
        "arn:aws:s3:::awsexamplebucket1"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userid": [
            "AROAID2GEXAMPLEROLEID:*",
            "444455556666"
          ]
        }
      }
    }
  ]
}