AWS KMS Key Policy Analyzer

A KMS key policy is unlike almost everything else in AWS: it is the root of authority for its key, and an IAM policy alone cannot grant access to it.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Analyze. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A policy with no IAM delegation

IAM policies cannot grant access to this key at all

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AppOnly",
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:role/App" },
      "Action": ["kms:Decrypt", "kms:PutKeyPolicy"],
      "Resource": "*"
    }
  ]
}

A policy nobody can edit

Permanently unmanageable, and the data is unrecoverable if it is ever deleted

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:role/App" },
      "Action": ["kms:Decrypt", "kms:Encrypt"],
      "Resource": "*"
    }
  ]
}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Removing the Enable IAM User Permissions statement to tighten the policy

    It is what tells KMS to honour IAM policies for this key. Without it, IAM grants nothing and only the principals named here can use the key.

    Instead:Leave it. Tighten access with IAM policies and conditions instead.

  2. Writing a key policy with no principal able to call kms:PutKeyPolicy

    Nobody can edit it afterwards, including AWS Support. The key becomes unmanageable and the data under it is at the mercy of a deletion nobody can prevent.

    Instead:Always keep a durable administrator. The account root statement is the usual way.

  3. Auditing key access from the key policy alone

    Grants give principals use of the key without appearing there, and AWS services create them for you.

    Instead:Run aws kms list-grants as well.

Removing the wrong statement locks the key permanently

If no principal in the document can call kms:PutKeyPolicy, the policy cannot be edited by anybody, including the account root and AWS Support.

And the data goes with it

The key can still be scheduled for deletion, and when that completes every ciphertext under it is unrecoverable by anyone. This is the one AWS misconfiguration with no way back, which is why the default key policy contains a statement most people are tempted to tidy away.

That statement is a delegation, not a grant

Allowing the account root kms:* does not give the root user anything special. It tells KMS to honour IAM policies for this key. Without it, only the principals named in the key policy can use the key, however many IAM policies say otherwise, and the resulting access denied mentions neither.

A key policy grants directly

Unlike a bucket policy, where an IAM policy is a second gate the caller also has to pass, a key policy can grant on its own. So a wildcard principal here is a grant to every AWS account rather than a widening of something IAM still controls.

Grants are a separate path this document does not show

A KMS grant gives a principal use of a key without appearing in the key policy at all, and AWS services create them on your behalf. Reviewing the key policy alone is not a review of who can use the key: aws kms list-grants is the other half.

kms:ViaService is the most useful condition here

It restricts use to requests arriving through a named service, such as s3.eu-west-1.amazonaws.com, so a principal cannot decrypt data outside the context it was meant for. Note the value includes the region.

Deletion is a waiting period, and that is the only undo

Scheduling deletion starts between seven and thirty days during which the key is unusable and the deletion can be cancelled. Set the longest you can tolerate and alarm on ScheduleKeyDeletion.