AnalysisType: policy
Filename: aws_access_keys_at_account_creation.py
DisplayName: "AWS Access Keys At Account Creation"
PolicyID: "AWS.AccessKeys.AccountCreation"
Enabled: true
ResourceTypes:
- AWS.IAM.User
- AWS.IAM.RootUser
Tags:
- AWS
- Identity & Access Management
Reports:
CIS:
- 1.21
Severity: Low
Description: >
This policy validates that AWS IAM user accounts do not have access keys that were
created during account creation. This results in excess keys being generated,
and unnecessary management work in auditing and rotating these keys.
Runbook: >
https://docs.runpanther.io/alert-runbooks/built-in-policies/aws-access-keys-are-not-created-at-account-creation
Reference: >
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
Tests:
- Name: Root User Access Key Created At Account Creation
ExpectedResult: false
Resource:
{
"ARN": "arn:aws:iam::123456789012:root",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"CredentialReport":
{
"ARN": "arn:aws:iam::123456789012:root",
"AccessKey1Active": false,
"AccessKey1LastRotated": "2019-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 Not Created At Account Creation
ExpectedResult: true
Resource:
{
"ARN": "arn:aws:iam::123456789012:root",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"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": 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 Rotated Since Account Creation
ExpectedResult: true
Resource:
{
"ARN": "arn:aws:iam::123456789012:root",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"CredentialReport":
{
"ARN": "arn:aws:iam::123456789012:root",
"AccessKey1Active": false,
"AccessKey1LastRotated": "2019-01-01T00:10: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: User Access Key Created At Account Creation
ExpectedResult: false
Resource:
{
"Arn": "arn:aws:iam::123456789012:user/Bobert",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"CredentialReport":
{
"ARN": "arn:aws:iam::123456789012:user/Bobert",
"AccessKey1Active": true,
"AccessKey1LastRotated": "2019-01-01T00:00:05Z",
"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",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"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 Not Created At Account Creation
ExpectedResult: true
Resource:
{
"Arn": "arn:aws:iam::123456789012:user/Bobert",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"CredentialReport":
{
"ARN": "arn:aws:iam::123456789012:user/Bobert",
"AccessKey1Active": true,
"AccessKey1LastRotated": "0001-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",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"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 Rotated Since Account Creation
ExpectedResult: true
Resource:
{
"Arn": "arn:aws:iam::123456789012:user/Bobert",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"CredentialReport":
{
"ARN": "arn:aws:iam::123456789012:user/Bobert",
"AccessKey1Active": true,
"AccessKey1LastRotated": "2019-01-01T00:00:30Z",
"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",
"TimeCreated": "2019-01-01T00:00:00.000Z",
"GroupId": "ABCDEFGHIJKLMNOP",
"GroupName": "ExampleGroup",
"Path": "/",
},
],
"InlinePolicyNames": null,
"ManagedPolicyNames": ["IAMUserChangePassword"],
"PasswordLastUsed": null,
"Path": "/",
"PermissionsBoundary": null,
"Tags": null,
"UserId": "ASDFASDFASDFASDF",
"UserName": "Bobert",
"VirtualMFA": null,
}
- Name: Observed - Timestamp Issues
ExpectedResult: true
Resource:
{
"AccountId": "123456789012",
"CredentialReport":
{
"MfaActive": true,
"AccessKey1LastUsedRegion": "us-east-1",
"Cert2LastRotated": "0001-01-01T00:00:00Z",
"AccessKey2Active": false,
"AccessKey2LastRotated": "0001-01-01T00:00:00Z",
"AccessKey1LastRotated": "2021-02-07T09:18:42Z",
"AccessKey1LastUsedService": "sts",
"AccessKey1LastUsedDate": "2021-03-01T14:31:00Z",
"UserName": "bobert",
"PasswordEnabled": true,
"PasswordLastChanged": "2021-02-09T14:05:34Z",
"UserCreationTime": "2020-06-02T09:33:48Z",
"PasswordLastUsed": "2021-03-01T10:13:14Z",
"AccessKey2LastUsedDate": "0001-01-01T00:00:00Z",
"PasswordNextRotation": "2021-05-10T14:05:34Z",
"AccessKey1Active": true,
"ARN": "arn:aws:iam::123456789012:user/bobert",
"Cert1LastRotated": "0001-01-01T00:00:00Z",
"Cert1Active": false,
"AccessKey2LastUsedService": "N/A",
"Cert2Active": false,
"AccessKey2LastUsedRegion": "N/A",
},
"PasswordLastUsed": "2021-03-01T10:13:14Z",
"InlinePolicies": null,
"Id": "XXXXXXXXXXXXXXXXXXXXX",
"TimeCreated": "2020-06-02T09:33:48Z",
"Arn": "arn:aws:iam::123456789012:user/bobert",
"Path": "/",
"VirtualMFA":
{
"SerialNumber": "arn:aws:iam::123456789012:mfa/bobert",
"EnableDate": "2020-06-02T10:10:10Z",
},
"PermissionsBoundary": null,
"Region": "global",
"Tags": null,
"ResourceId": "arn:aws:iam::123456789012:user/bobert",
"ResourceType": "AWS.IAM.User",
"Name": "bobert",
"ManagedPolicyNames": null,
}
# ------ paired body: aws_access_keys_at_account_creation.py ------
from datetime import timedelta
from panther_base_helpers import deep_get, resolve_timestamp_string
AWS_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
DEFAULT_TIME = "0001-01-01T00:00:00Z"
MAX_SECONDS_TO_AUTOGEN_KEY = timedelta(seconds=7)
def policy(resource):
# If a user is less than 4 hours old, it may not have a credential report generated yet.
# It will be re-scanned periodically until a credential report is found, at which point this
# policy will be properly evaluated.
if not resource.get("CredentialReport"):
return True
key_rot = deep_get(resource, "CredentialReport", "AccessKey1LastRotated")
if key_rot == DEFAULT_TIME:
return True
create = resource.get("TimeCreated", "")
key_rot_date = resolve_timestamp_string(key_rot)
create_date = resolve_timestamp_string(create)
if not key_rot_date or not create_date:
return True
return (key_rot_date - create_date) >= MAX_SECONDS_TO_AUTOGEN_KEY