What is the purpose of the second (Effect:Deny, Condition:Null) Statement of this S3 bucket policy?

Reading this doc it give an example for forcing encryption on bucket:

{
  "Version": "2012-10-17",
  "Id": "PutObjPolicy",
  "Statement": [
    {
      "Sid": "DenyIncorrectEncryptionHeader",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::YourBucket/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    },
    {
      "Sid": "DenyUnEncryptedObjectUploads",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::YourBucket/*",
      "Condition": {
        "Null": {
          "s3:x-amz-server-side-encryption": "true"
        }
      }
    }
  ]
}

What is the second condition actually doing and why is it necessary, to me, looks like I'd only need the first one? I don't understand what NULL is even doing here.


Solution 1:

According to the documentation,

Use a Null condition operator to check if a condition key is present at the time of authorization. In the policy statement, use either true (the key doesn't exist — it is null) or false (the key exists and its value is not null).

So in your example if the key s3:x-amz-server-side-encryption doesn't exist, it should be null to make the condition successful.

Solution 2:

The Null condition in the condition block evaluates to true if the s3:x-amz-server-side-encryption key value is null. This rule is checking for a missing header.

In the first rule in this policy, the encryption value is being compared. In order for this comparison to occur the header must be present. The second rule detects that the header is missing, thereby enforcing that an encryption selection occurs.

Summary:

The first rule checks the value of the encryption header.

The second rule checks if the header is present.