Skip to content

Commit b944f3a

Browse files
authored
feat: Add check for sessionCredentialFromConsole (#26)
* sessionCredentialFromConsole * Update readme with latest provider version * Fix tflint warning
1 parent d959b0c commit b944f3a

File tree

7 files changed

+124
-7
lines changed

7 files changed

+124
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ module "clickops_notifications" {
8989

9090
| Name | Version |
9191
|------|---------|
92-
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.23.0 |
92+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.29.0 |
9393
----
9494
### Requirements
9595

iam.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ data "aws_iam_policy_document" "lambda_permissions" {
77
]
88

99
resources = [
10-
"${data.aws_s3_bucket.cloudtrail_bucket.arn}"
10+
data.aws_s3_bucket.cloudtrail_bucket.arn
1111
]
1212
}
1313

lambda/app/clickops.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def __init__(self, event) -> None:
1212
self.request_id = event.get('requestID', "NA")
1313
self.read_only = self.__readonly_event(event)
1414
self.user_email = self.__user_email(event)
15+
self.console_session = self.__console_session_event(event)
1516

1617
@staticmethod
1718
def __user_email(event) -> str:
@@ -36,6 +37,18 @@ def __readonly_event(event) -> bool:
3637
else:
3738
return False
3839

40+
@staticmethod
41+
def __console_session_event(event) -> bool:
42+
if 'sessionCredentialFromConsole' in event:
43+
if event['sessionCredentialFromConsole'] == 'true' or \
44+
event['sessionCredentialFromConsole'] or \
45+
event['sessionCredentialFromConsole'] == 1:
46+
return True
47+
else:
48+
return False
49+
else:
50+
return False
51+
3952

4053
class ClickOpsEventChecker:
4154
def __init__(self, event: CloudTrailEvent, ignored_scoped_events: List[str]) -> None:
@@ -113,7 +126,7 @@ def is_clickops(self) -> Tuple[bool, str]:
113126
if self.event.read_only:
114127
return False, "[COEC_Rule1] Readonly Event"
115128

116-
if not self.__user_agent_console():
129+
if not self.__user_agent_console() and not self.event.console_session:
117130
return False, "[COEC_Rule2] User agent does not match console"
118131

119132
if self.__match_readonly_event_name_pattern():

lambda/tests/5.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"event": {
3+
"eventVersion": "1.08",
4+
"userIdentity": {
5+
"type": "AssumedRole",
6+
"principalId": "AROA5L7R6SJPLS7EBCJPP:[email protected]",
7+
"arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_AWSAdministratorAccess_4cd06aad9151ee95/[email protected]",
8+
"accountId": "123456789012",
9+
"accessKeyId": "ASIA5L7R6SJPE5UL5SN6",
10+
"sessionContext": {
11+
"sessionIssuer": {
12+
"type": "Role",
13+
"principalId": "AROA5L7R6SJPLS7EBCJPP",
14+
"arn": "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-1/AWSReservedSSO_AWSAdministratorAccess_4cd06aad9151ee95",
15+
"accountId": "123456789012",
16+
"userName": "AWSReservedSSO_AWSAdministratorAccess_4cd06aad9151ee95"
17+
},
18+
"webIdFederationData": {},
19+
"attributes": {
20+
"creationDate": "2022-09-06T13:16:33Z",
21+
"mfaAuthenticated": "false"
22+
}
23+
}
24+
},
25+
"eventTime": "2022-09-06T14:03:07Z",
26+
"eventSource": "route53.amazonaws.com",
27+
"eventName": "ListResourceRecordSets",
28+
"awsRegion": "us-east-1",
29+
"sourceIPAddress": "AWS Internal",
30+
"userAgent": "AWS Internal",
31+
"requestParameters": {
32+
"hostedZoneId": "ZXXXXXXXXXXXXXXXXXXX",
33+
"maxItems": "300"
34+
},
35+
"responseElements": null,
36+
"requestID": "e20b0df6-aa92-4b19-a7d5-bb4d278ccd3d",
37+
"eventID": "dfb675f6-cb3a-47c7-b5bc-ad0613403d6b",
38+
"readOnly": true,
39+
"eventType": "AwsApiCall",
40+
"apiVersion": "2013-05-27",
41+
"managementEvent": true,
42+
"recipientAccountId": "123456789012",
43+
"eventCategory": "Management",
44+
"sessionCredentialFromConsole": "true"
45+
},
46+
"expect": {
47+
"is_clickops": false,
48+
"reason_contains": "[COEC_Rule1]",
49+
"user_email": "[email protected]",
50+
"readonly": true
51+
}
52+
}

lambda/tests/6.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"event": {
3+
"eventVersion": "1.08",
4+
"userIdentity": {
5+
"type": "AssumedRole",
6+
"principalId": "AROA5L7R6SJPLS7EBCJPP:[email protected]",
7+
"arn": "arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_AWSAdministratorAccess_4cd06aad9151ee95/[email protected]",
8+
"accountId": "123456789012",
9+
"accessKeyId": "ASIA5L7R6SJPE5UL5SN6",
10+
"sessionContext": {
11+
"sessionIssuer": {
12+
"type": "Role",
13+
"principalId": "AROA5L7R6SJPLS7EBCJPP",
14+
"arn": "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-1/AWSReservedSSO_AWSAdministratorAccess_4cd06aad9151ee95",
15+
"accountId": "123456789012",
16+
"userName": "AWSReservedSSO_AWSAdministratorAccess_4cd06aad9151ee95"
17+
},
18+
"webIdFederationData": {},
19+
"attributes": {
20+
"creationDate": "2022-09-06T13:16:33Z",
21+
"mfaAuthenticated": "false"
22+
}
23+
}
24+
},
25+
"eventTime": "2022-09-06T14:03:07Z",
26+
"eventSource": "route53.amazonaws.com",
27+
"eventName": "ChangeResourceRecordSets",
28+
"awsRegion": "us-east-1",
29+
"sourceIPAddress": "AWS Internal",
30+
"userAgent": "AWS Internal",
31+
"requestParameters": {
32+
"hostedZoneId": "ZXXXXXXXXXXXXXXXXXXX",
33+
"maxItems": "300"
34+
},
35+
"responseElements": null,
36+
"requestID": "e20b0df6-aa92-4b19-a7d5-bb4d278ccd3d",
37+
"eventID": "dfb675f6-cb3a-47c7-b5bc-ad0613403d6b",
38+
"readOnly": false,
39+
"eventType": "AwsApiCall",
40+
"apiVersion": "2013-05-27",
41+
"managementEvent": true,
42+
"recipientAccountId": "123456789012",
43+
"eventCategory": "Management",
44+
"sessionCredentialFromConsole": "true"
45+
},
46+
"expect": {
47+
"is_clickops": true,
48+
"reason_contains": "[COEC_Rule6]",
49+
"user_email": "[email protected]",
50+
"readonly": false
51+
}
52+
}

lambda/tests/CreateVpc_Issue.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@
8888
"sessionCredentialFromConsole": "true"
8989
},
9090
"expect": {
91-
"is_clickops": false,
92-
"reason_contains": "[COEC_Rule2]",
91+
"is_clickops": true,
92+
"reason_contains": "[COEC_Rule6]",
9393
"user_email": "[email protected]",
9494
"readonly": false
9595
}

lambda/tests/DeleteVPC_Issue.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
"sessionCredentialFromConsole": "true"
4646
},
4747
"expect": {
48-
"is_clickops": false,
49-
"reason_contains": "[COEC_Rule2]",
48+
"is_clickops": true,
49+
"reason_contains": "[COEC_Rule6]",
5050
"user_email": "[email protected]",
5151
"readonly": false
5252
}

0 commit comments

Comments
 (0)