Skip to content

Commit 309e3ab

Browse files
authored
Expand on the CloudTrail event (#909)
* Expand on the CloudTrail event The initial contribution of the CloudTrail event was not complete, but rather constructed from a handful of event examples. The structure is documented at https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html which covers a number of optional fields and fields that are not already covered. * Add three example tests for CloudTrail events
1 parent 4b5ffc8 commit 309e3ab

4 files changed

+184
-5
lines changed

lambda-events/src/event/cloudwatch_events/cloudtrail.rs

+72-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use chrono::{DateTime, Utc};
12
use serde::{Deserialize, Serialize};
23
use serde_json::Value;
34

@@ -26,23 +27,89 @@ pub struct AWSAPICall<I = Value, O = Value> {
2627

2728
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
2829
#[serde(rename_all = "camelCase")]
29-
pub struct UserIdentity {
30+
pub struct SessionIssuer {
3031
pub r#type: String,
32+
pub user_name: Option<String>,
3133
pub principal_id: String,
3234
pub arn: String,
3335
pub account_id: String,
34-
pub session_context: Option<SessionContext>,
3536
}
3637

3738
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
3839
#[serde(rename_all = "camelCase")]
39-
pub struct SessionContext {
40-
pub attributes: Attributes,
40+
pub struct WebIdFederationData {
41+
pub federated_provider: Option<String>,
42+
pub attributes: Option<String>,
4143
}
4244

4345
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
4446
#[serde(rename_all = "camelCase")]
4547
pub struct Attributes {
4648
pub mfa_authenticated: String,
47-
pub creation_date: String,
49+
pub creation_date: DateTime<Utc>,
50+
}
51+
52+
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
53+
#[serde(rename_all = "camelCase")]
54+
pub struct SessionContext {
55+
pub session_issuer: Option<SessionIssuer>,
56+
pub web_id_federation_data: Option<WebIdFederationData>,
57+
pub attributes: Attributes,
58+
pub source_identity: Option<String>,
59+
pub ec2_role_delivery: Option<String>,
60+
}
61+
62+
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
63+
#[serde(rename_all = "camelCase")]
64+
pub struct OnBehalfOf {
65+
pub user_id: String,
66+
pub identity_store_arn: String,
67+
}
68+
69+
// https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html
70+
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
71+
#[serde(rename_all = "camelCase")]
72+
pub struct UserIdentity {
73+
pub r#type: String,
74+
pub account_id: Option<String>,
75+
pub arn: Option<String>,
76+
pub credential_id: Option<String>,
77+
pub invoked_by: Option<String>,
78+
pub principal_id: Option<String>,
79+
pub session_context: Option<SessionContext>,
80+
pub user_name: Option<String>,
81+
pub on_behalf_of: Option<OnBehalfOf>,
82+
}
83+
84+
#[cfg(test)]
85+
mod tests {
86+
use super::AWSAPICall;
87+
88+
#[test]
89+
#[cfg(feature = "cloudwatch_events")]
90+
fn example_cloudwatch_cloudtrail_unknown_assumed_role() {
91+
let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json");
92+
let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
93+
let output: String = serde_json::to_string(&parsed).unwrap();
94+
let reparsed: AWSAPICall = serde_json::from_slice(&output.as_bytes()).unwrap();
95+
assert_eq!(parsed, reparsed);
96+
}
97+
#[test]
98+
#[cfg(feature = "cloudwatch_events")]
99+
fn example_cloudwatch_cloudtrail_unknown_federate() {
100+
let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json");
101+
let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
102+
let output: String = serde_json::to_string(&parsed).unwrap();
103+
let reparsed: AWSAPICall = serde_json::from_slice(&output.as_bytes()).unwrap();
104+
assert_eq!(parsed, reparsed);
105+
}
106+
#[test]
107+
#[cfg(feature = "cloudwatch_events")]
108+
fn example_cloudwatch_cloudtrail_assumed_role() {
109+
let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json");
110+
let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
111+
let output: String = serde_json::to_string(&parsed).unwrap();
112+
let reparsed: AWSAPICall = serde_json::from_slice(&output.as_bytes()).unwrap();
113+
assert_eq!(parsed, reparsed);
114+
}
48115
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"eventVersion": "1.08",
3+
"userIdentity": {
4+
"type": "AssumedRole",
5+
"principalId": "ZZZZZZZZZZZZZZZZZZZZZ:[email protected]",
6+
"arn": "arn:aws:sts::123456789000:assumed-role/AWSReservedSSO_AWSAdministratorAccess_abcdef1234567890/[email protected]",
7+
"accountId": "123456789000",
8+
"accessKeyId": "ABCDEFGHI12345678890",
9+
"sessionContext": {
10+
"sessionIssuer": {
11+
"type": "Role",
12+
"principalId": "ZZZZZZZZZZZZZZZZZZZZZ",
13+
"arn": "arn:aws:iam::123456789000:role/aws-reserved/sso.amazonaws.com/eu-west-1/AWSReservedSSO_AWSAdministratorAccess_abcdef1234567890",
14+
"accountId": "123456789000",
15+
"userName": "AWSReservedSSO_AWSAdministratorAccess_abcdef1234567890"
16+
},
17+
"webIdFederationData": {},
18+
"attributes": {
19+
"creationDate": "2024-07-10T16:03:25Z",
20+
"mfaAuthenticated": "false"
21+
}
22+
},
23+
"invokedBy": "servicecatalog.amazonaws.com"
24+
},
25+
"eventTime": "2024-07-10T16:48:26Z",
26+
"eventSource": "controltower.amazonaws.com",
27+
"eventName": "CreateManagedAccount",
28+
"awsRegion": "eu-west-1",
29+
"sourceIPAddress": "servicecatalog.amazonaws.com",
30+
"userAgent": "servicecatalog.amazonaws.com",
31+
"requestParameters": {
32+
"accountEmail": "HIDDEN_DUE_TO_SECURITY_REASONS",
33+
"accountName": "Account Name",
34+
"parentOrganizationalUnitName": "Organizational Unit (ou-a1b2-abcdef12)",
35+
"sSOUserEmail": "HIDDEN_DUE_TO_SECURITY_REASONS",
36+
"sSOUserFirstName": "HIDDEN_DUE_TO_SECURITY_REASONS",
37+
"sSOUserLastName": "HIDDEN_DUE_TO_SECURITY_REASONS",
38+
"provisionedProductId": "pp-abcdefg123456",
39+
"idempotencyToken": "abcdef12345-abcdef12345"
40+
},
41+
"responseElements": {
42+
"createManagedAccountExecutionId": "123456789000-abcdef12345-abcdef12345"
43+
},
44+
"requestID": "00000000-0000-0000-0000-000000000000",
45+
"eventID": "00000000-0000-0000-0000-000000000000",
46+
"readOnly": false,
47+
"eventType": "AwsApiCall",
48+
"managementEvent": true,
49+
"recipientAccountId": "123456789000",
50+
"eventCategory": "Management",
51+
"sessionCredentialFromConsole": "true"
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"eventVersion": "1.08",
3+
"userIdentity": {
4+
"type": "Unknown",
5+
"principalId": "00000000-0000-0000-0000-000000000000",
6+
"accountId": "123456789000",
7+
"userName": "[email protected]"
8+
},
9+
"eventTime": "2024-07-10T18:41:56Z",
10+
"eventSource": "sso.amazonaws.com",
11+
"eventName": "Federate",
12+
"awsRegion": "eu-west-1",
13+
"sourceIPAddress": "1.1.1.1",
14+
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
15+
"requestParameters": null,
16+
"responseElements": null,
17+
"requestID": "00000000-0000-0000-0000-000000000000",
18+
"eventID": "00000000-0000-0000-0000-000000000000",
19+
"readOnly": false,
20+
"eventType": "AwsServiceEvent",
21+
"managementEvent": true,
22+
"recipientAccountId": "123456789000",
23+
"serviceEventDetails": {
24+
"relayId": "00000000-0000-0000-0000-000000000000_00000000-0000-0000-0000-000000000000"
25+
},
26+
"eventCategory": "Management"
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"eventVersion": "1.08",
3+
"userIdentity": {
4+
"type": "Unknown",
5+
"principalId": "123456789000",
6+
"arn": "",
7+
"accountId": "123456789000",
8+
"accessKeyId": ""
9+
},
10+
"eventTime": "2024-07-10T16:05:11Z",
11+
"eventSource": "signin.amazonaws.com",
12+
"eventName": "UserAuthentication",
13+
"awsRegion": "eu-west-1",
14+
"sourceIPAddress": "1.1.1.1",
15+
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
16+
"requestParameters": null,
17+
"responseElements": null,
18+
"additionalEventData": {
19+
"AuthWorkflowID": "00000000-0000-0000-0000-000000000000",
20+
"LoginTo": "https://tenant.awsapps.com/start/",
21+
"CredentialType": "EXTERNAL_IDP"
22+
},
23+
"requestID": "00000000-0000-0000-0000-000000000000",
24+
"eventID": "00000000-0000-0000-0000-000000000000",
25+
"readOnly": false,
26+
"eventType": "AwsServiceEvent",
27+
"managementEvent": true,
28+
"recipientAccountId": "123456789000",
29+
"serviceEventDetails": {
30+
"UserAuthentication": "Success"
31+
},
32+
"eventCategory": "Management"
33+
}

0 commit comments

Comments
 (0)