Detection rules › Panther

AWS Access Key Rotation

Severity
medium
Compliance
CIS 1.4
Tags
AWS, Identity & Access Management, Credential Access:Unsecured Credentials
Reference
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
Source
github.com/panther-labs/panther-analysis

This policy validates that AWS IAM account access keys are rotated every 90 days. Rotating access keys will reduce the window of opportunity for an access key that is associated with a compromised or terminated account to be used.

MITRE ATT&CK coverage

TacticTechniques
Credential AccessT1552 Unsecured Credentials

Rule body yaml

AnalysisType: policy
Filename: aws_access_key_rotation.py
PolicyID: "AWS.AccessKey.Rotation"
DisplayName: "AWS Access Key Rotation"
Enabled: true
ResourceTypes:
  - AWS.IAM.RootUser
  - AWS.IAM.User
Tags:
  - AWS
  - Identity & Access Management
  - Credential Access:Unsecured Credentials
Reports:
  CIS:
    - 1.4
  MITRE ATT&CK:
    - TA0006:T1552
Severity: Medium
Description: >
  This policy validates that AWS IAM account access keys are rotated every 90 days.
  Rotating access keys will reduce the window of opportunity for an access key that
  is associated with a compromised or terminated account to be used.
Runbook: >
  https://docs.runpanther.io/alert-runbooks/built-in-policies/aws-access-keys-rotated-every-90-days
Reference: >
  https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
Tests:
  - Name: Root User Access Key 1 Rotated Over 90 Days Ago
    ExpectedResult: false
    Resource:
      {
        "ARN": "arn:aws:iam::123456789012:root",
        "CreateDate": "2019-01-01T00:00:00Z",
        "CredentialReport":
          {
            "ARN": "arn:aws:iam::123456789012:root",
            "AccessKey1Active": true,
            "AccessKey1LastRotated": "2000-01-01T00:00:00Z",
            "AccessKey1LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedRegion": "N/A",
            "AccessKey1LastUsedService": "N/A",
            "AccessKey2Active": false,
            "AccessKey2LastRotated": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedRegion": "N/A",
            "AccessKey2LastUsedService": "N/A",
            "Cert1Active": false,
            "Cert1LastRotated": "0001-01-01T00:00:00Z",
            "Cert2Active": false,
            "Cert2LastRotated": "0001-01-01T00:00:00Z",
            "MfaActive": true,
            "PasswordEnabled": false,
            "PasswordLastChanged": "0001-01-01T00:00:00Z",
            "PasswordLastUsed": "2019-01-01T00:00:00Z",
            "PasswordNextRotation": "0001-01-01T00:00:00Z",
            "UserCreationTime": "2019-01-01T00:00:00Z",
            "UserName": "<root_account>",
          },
        "UserID": null,
        "UserName": "root",
        "VirtualMFA": null,
      }
  - Name: Root User Access Key 2 Rotated Less Than 90 Days Ago
    ExpectedResult: true
    Resource:
      {
        "ARN": "arn:aws:iam::123456789012:root",
        "CreateDate": "2019-01-01T00:00:00Z",
        "CredentialReport":
          {
            "ARN": "arn:aws:iam::123456789012:root",
            "AccessKey1Active": false,
            "AccessKey1LastRotated": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedRegion": "N/A",
            "AccessKey1LastUsedService": "N/A",
            "AccessKey2Active": true,
            "AccessKey2LastRotated": "3000-01-01T00:00:00Z",
            "AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedRegion": "N/A",
            "AccessKey2LastUsedService": "N/A",
            "Cert1Active": false,
            "Cert1LastRotated": "0001-01-01T00:00:00Z",
            "Cert2Active": false,
            "Cert2LastRotated": "0001-01-01T00:00:00Z",
            "MfaActive": true,
            "PasswordEnabled": false,
            "PasswordLastChanged": "0001-01-01T00:00:00Z",
            "PasswordLastUsed": "2019-01-01T00:00:00Z",
            "PasswordNextRotation": "0001-01-01T00:00:00Z",
            "UserCreationTime": "2019-01-01T00:00:00Z",
            "UserName": "<root_account>",
          },
        "UserID": null,
        "UserName": "root",
        "VirtualMFA": null,
      }
  - Name: User Access Key 1 Rotated Less Than 90 Days Ago
    ExpectedResult: true
    Resource:
      {
        "Arn": "arn:aws:iam::123456789012:user/Bobert",
        "CreateDate": "2019-01-01T00:00:00Z",
        "CredentialReport":
          {
            "ARN": "arn:aws:iam::123456789012:user/Bobert",
            "AccessKey1Active": true,
            "AccessKey1LastRotated": "3000-01-01T00:00:00Z",
            "AccessKey1LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedRegion": "N/A",
            "AccessKey1LastUsedService": "N/A",
            "AccessKey2Active": false,
            "AccessKey2LastRotated": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedRegion": "N/A",
            "AccessKey2LastUsedService": "N/A",
            "Cert1Active": false,
            "Cert1LastRotated": "0001-01-01T00:00:00Z",
            "Cert2Active": false,
            "Cert2LastRotated": "0001-01-01T00:00:00Z",
            "MfaActive": false,
            "PasswordEnabled": true,
            "PasswordLastChanged": "2019-01-01T00:00:00Z",
            "PasswordLastUsed": "0001-01-01T00:00:00Z",
            "PasswordNextRotation": "2019-04-01T00:00:00Z",
            "UserCreationTime": "2019-01-01T00:00:00Z",
            "UserName": "Bobert",
          },
        "Groups":
          [
            {
              "Arn": "arn:aws:iam::123456789012:group/ExampleGroup",
              "CreateDate": "2019-01-01T00:00:00Z",
              "GroupId": "ABCDEFGHIJKLMNOP",
              "GroupName": "ExampleGroup",
              "Path": "/",
            },
          ],
        "InlinePolicyNames": null,
        "ManagedPolicyNames": ["IAMUserChangePassword"],
        "PasswordLastUsed": null,
        "Path": "/",
        "PermissionsBoundary": null,
        "Tags": null,
        "UserId": "ASDFASDFASDFASDF",
        "UserName": "Bobert",
        "VirtualMFA": null,
      }
  - Name: User Access Key 1 Rotated Over 90 Days Ago
    ExpectedResult: false
    Resource:
      {
        "Arn": "arn:aws:iam::123456789012:user/Bobert",
        "CreateDate": "2019-01-01T00:00:00Z",
        "CredentialReport":
          {
            "ARN": "arn:aws:iam::123456789012:user/Bobert",
            "AccessKey1Active": true,
            "AccessKey1LastRotated": "2000-01-01T00:00:00Z",
            "AccessKey1LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedRegion": "N/A",
            "AccessKey1LastUsedService": "N/A",
            "AccessKey2Active": false,
            "AccessKey2LastRotated": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedRegion": "N/A",
            "AccessKey2LastUsedService": "N/A",
            "Cert1Active": false,
            "Cert1LastRotated": "0001-01-01T00:00:00Z",
            "Cert2Active": false,
            "Cert2LastRotated": "0001-01-01T00:00:00Z",
            "MfaActive": false,
            "PasswordEnabled": true,
            "PasswordLastChanged": "2019-01-01T00:00:00Z",
            "PasswordLastUsed": "0001-01-01T00:00:00Z",
            "PasswordNextRotation": "2019-04-01T00:00:00Z",
            "UserCreationTime": "2019-01-01T00:00:00Z",
            "UserName": "Bobert",
          },
        "Groups":
          [
            {
              "Arn": "arn:aws:iam::123456789012:group/ExampleGroup",
              "CreateDate": "2019-01-01T00:00:00Z",
              "GroupId": "ABCDEFGHIJKLMNOP",
              "GroupName": "ExampleGroup",
              "Path": "/",
            },
          ],
        "InlinePolicyNames": null,
        "ManagedPolicyNames": ["IAMUserChangePassword"],
        "PasswordLastUsed": null,
        "Path": "/",
        "PermissionsBoundary": null,
        "Tags": null,
        "UserId": "ASDFASDFASDFASDF",
        "UserName": "Bobert",
        "VirtualMFA": null,
      }
  - Name: User Access Key 2 Rotated Less Than 90 Days Ago
    ExpectedResult: true
    Resource:
      {
        "Arn": "arn:aws:iam::123456789012:user/Bobert",
        "CreateDate": "2019-01-01T00:00:00Z",
        "CredentialReport":
          {
            "ARN": "arn:aws:iam::123456789012:user/Bobert",
            "AccessKey1Active": false,
            "AccessKey1LastRotated": "2019-01-01T00:00:00Z",
            "AccessKey1LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedRegion": "N/A",
            "AccessKey1LastUsedService": "N/A",
            "AccessKey2Active": true,
            "AccessKey2LastRotated": "3000-01-01T00:00:00Z",
            "AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedRegion": "N/A",
            "AccessKey2LastUsedService": "N/A",
            "Cert1Active": false,
            "Cert1LastRotated": "0001-01-01T00:00:00Z",
            "Cert2Active": false,
            "Cert2LastRotated": "0001-01-01T00:00:00Z",
            "MfaActive": false,
            "PasswordEnabled": true,
            "PasswordLastChanged": "2019-01-01T00:00:00Z",
            "PasswordLastUsed": "0001-01-01T00:00:00Z",
            "PasswordNextRotation": "2019-04-01T00:00:00Z",
            "UserCreationTime": "2019-01-01T00:00:00Z",
            "UserName": "Bobert",
          },
        "Groups":
          [
            {
              "Arn": "arn:aws:iam::123456789012:group/ExampleGroup",
              "CreateDate": "2019-01-01T00:00:00Z",
              "GroupId": "ABCDEFGHIJKLMNOP",
              "GroupName": "ExampleGroup",
              "Path": "/",
            },
          ],
        "InlinePolicyNames": null,
        "ManagedPolicyNames": ["IAMUserChangePassword"],
        "PasswordLastUsed": null,
        "Path": "/",
        "PermissionsBoundary": null,
        "Tags": null,
        "UserId": "ASDFASDFASDFASDF",
        "UserName": "Bobert",
        "VirtualMFA": null,
      }
  - Name: User Access Key 2 Rotated Over 90 Days Ago
    ExpectedResult: false
    Resource:
      {
        "Arn": "arn:aws:iam::123456789012:user/Bobert",
        "CreateDate": "2019-01-01T00:00:00Z",
        "CredentialReport":
          {
            "ARN": "arn:aws:iam::123456789012:user/Bobert",
            "AccessKey1Active": false,
            "AccessKey1LastRotated": "2019-01-01T00:00:00Z",
            "AccessKey1LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey1LastUsedRegion": "N/A",
            "AccessKey1LastUsedService": "N/A",
            "AccessKey2Active": true,
            "AccessKey2LastRotated": "2000-01-01T00:00:00Z",
            "AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
            "AccessKey2LastUsedRegion": "N/A",
            "AccessKey2LastUsedService": "N/A",
            "Cert1Active": false,
            "Cert1LastRotated": "0001-01-01T00:00:00Z",
            "Cert2Active": false,
            "Cert2LastRotated": "0001-01-01T00:00:00Z",
            "MfaActive": false,
            "PasswordEnabled": true,
            "PasswordLastChanged": "2019-01-01T00:00:00Z",
            "PasswordLastUsed": "0001-01-01T00:00:00Z",
            "PasswordNextRotation": "2019-04-01T00:00:00Z",
            "UserCreationTime": "2019-01-01T00:00:00Z",
            "UserName": "Bobert",
          },
        "Groups":
          [
            {
              "Arn": "arn:aws:iam::123456789012:group/ExampleGroup",
              "CreateDate": "2019-01-01T00:00:00Z",
              "GroupId": "ABCDEFGHIJKLMNOP",
              "GroupName": "ExampleGroup",
              "Path": "/",
            },
          ],
        "InlinePolicyNames": null,
        "ManagedPolicyNames": ["IAMUserChangePassword"],
        "PasswordLastUsed": null,
        "Path": "/",
        "PermissionsBoundary": null,
        "Tags": null,
        "UserId": "ASDFASDFASDFASDF",
        "UserName": "Bobert",
        "VirtualMFA": null,
      }

Detection logic

Condition

CredentialReport 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.

FieldKindExcluded values
CredentialReportis_null(no value, null check)