Detection rules › Panther
AWS KMS Key Restricts Usage
This policy validates that KMS Keys restrict what entities can use them and how. This is to ensure that encryption keys are limited in who can use them in order to prevent unapproved decryption.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access | T1552 Unsecured Credentials |
Rule body yaml
AnalysisType: policy
Filename: aws_kms_key_policy_restricts_usage.py
PolicyID: "AWS.KMS.RestrictsUsage"
DisplayName: "AWS KMS Key Restricts Usage"
Enabled: true
ResourceTypes:
- AWS.KMS.Key
Tags:
- AWS
- PCI
- Credential Access:Unsecured Credentials
Reports:
PCI:
- 3.5.2
MITRE ATT&CK:
- TA0006:T1552
Severity: High
Description: >
This policy validates that KMS Keys restrict what entities can use them and how. This is to ensure that encryption keys are limited in who can use them in order to prevent unapproved decryption.
Runbook: Add appropriate limitations to the KMS Key's policy.
Reference: https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html
Tests:
- Name: Key Usage Not Restricted
ExpectedResult: false
Resource:
{
"KeyRotationEnabled": true,
"AWSAccountId": "1122334455",
"Arn": "arn:aws:kms:us-west-2:11223344:key/1122233-asdf-adsf-111222333",
"CloudHsmClusterId": null,
"CreationDate": "2019-01-01T00:00:00Z",
"CustomKeyStoreId": null,
"DeletionDate": null,
"Description": "Default master key that protects my Secrets Manager data when no other key is defined",
"Enabled": false,
"ExpirationModel": null,
"KeyId": "1122233-asdf-adsf-111222333",
"KeyManager": "AWS",
"KeyState": "Enabled",
"KeyUsage": "ENCRYPT_DECRYPT",
"Origin": "AWS_KMS",
"ValidTo": null,
"Policy": "{\n \"Version\" : \"2012-10-17\",\n \"Id\" : \"use-key\",\n \"Statement\" : [ {\n \"Sid\" : \"Allow access\",\n \"Effect\" : \"Allow\",\n \"Principal\" : {\n \"AWS\" : \"*\"\n },\n \"Action\" : [ \"kms:*\", \"kms:Decrypt\", \"kms:ReEncrypt*\", \"kms:GenerateDataKey*\", \"kms:CreateGrant\", \"kms:DescribeKey\" ],\n \"Resource\" : \"*\"} ]\n}",
}
- Name: Key Restricts Usage With Condition
ExpectedResult: true
Resource:
{
"KeyRotationEnabled": true,
"AWSAccountId": "1122334455",
"Arn": "arn:aws:kms:us-west-2:11223344:key/1122233-asdf-adsf-111222333",
"CloudHsmClusterId": null,
"CreationDate": "2019-01-01T00:00:00Z",
"CustomKeyStoreId": null,
"DeletionDate": null,
"Description": "Example key",
"Enabled": false,
"ExpirationModel": null,
"KeyId": "1122233-asdf-adsf-111222333",
"KeyManager": "AWS",
"KeyState": "Enabled",
"KeyUsage": "ENCRYPT_DECRYPT",
"Origin": "AWS_KMS",
"ValidTo": null,
"Policy": "{\n \"Version\" : \"2012-10-17\",\n \"Id\" : \"use key\",\n \"Statement\" : [ {\n \"Sid\" : \"Allow access\",\n \"Effect\" : \"Allow\",\n \"Principal\" : {\n \"AWS\" : \"*\"\n },\n \"Action\" : [ \"kms:Encrypt\", \"kms:Decrypt\"],\n \"Resource\" : \"*\",\n \"Condition\" : {\n \"StringEquals\" : {\n \"kms:CallerAccount\" : \"123456789012\",\n \"kms:ViaService\" : \"lambda.us-east-1.amazonaws.com\"\n }\n }\n } ]\n}",
}
Detection logic
Condition
Policy not is_null
This rule also runs imperative logic the parser cannot express as a filter; the conditions above are the structured part it could extract.
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
Policy | is_null |