AWS Security Blog

How to Easily Identify Your Federated Users by Using AWS CloudTrail

Starting today, you can use AWS CloudTrail to track the activity of your federated users (web identity federation and Security Assertion Markup Language [SAML]). For example, you can now use CloudTrail to identify a SAML federated user who terminated an Amazon EC2 instance in your AWS account, or to identify a mobile application user who has signed in using her Facebook account and has deleted a photo (an Amazon S3 object) from an Amazon S3 bucket. The ability to track federated users can help make it easier for you to conduct audits of their activity, which in turn can help you with your compliance and security efforts.

To capture the activity of these federated users, CloudTrail now records two additional AWS Security Token Service (AWS STS) API calls: AssumeRoleWithWebIdentity and AssumeRoleWithSAML. If you already have CloudTrail logging enabled, capturing these AWS STS API calls is enabled by default and requires no additional action from you. If you have not enabled CloudTrail already, see the CloudTrail documentation and AWS CloudTrail FAQs for more information.

In this blog post, I will show how you can identify a SAML federated user who terminated an EC2 instance in your AWS account.

Using CloudTrail to identify a SAML federated user who terminated an EC2 instance

Let’s say that the organization, example.com, has an IAM administrator named Alice and an employee named Bob. Example.com has configured its SAML 2.0–compliant identity provider and AWS to permit federated users such as Bob (email address: b@example.com) to access the AWS Management Console. Bob signs in to the AWS Management Console via SSO using SAML 2.0, and then he terminates an EC2 instance. Alice learns that a user has terminated the EC2 instance, and she needs to identify which federated user terminated the instance. To do this, she has decided to use CloudTrail.

To identify the federated user that terminated the EC2 instance, Alice signs in to the AWS Management Console and performs the following steps:

  1. Alice searches the CloudTrail event logs for the eventName called TerminateInstances.
  2. In the userIdentity section of the event log found in Step 1, Alice determines the Amazon Resource Name (ARN), including the role session name, of the IAM role assumed by the federated user.
  3. Alice searches the CloudTrail event logs for the eventName called AssumeRoleWithSAML that includes the IAM role’s ARN identified in Step 2.
  4. Finally, Alice identifies the federated user in the username attribute in the CloudTrail event log she found in Step 3.

In detail, I will now walk through the steps Alice took in CloudTrail to identify the SAML federated user who terminated the EC2 instance. Before we start, it is important to note that the solution described in this post requires that each federated user making an AssumeRoleWithSAML API call have a unique role session name (such as b@example.com). See Integrating Third-Party SAML Solution Providers with AWS to learn how to configure the RoleSessionName SAML attribute in your identity provider in order to get a unique role session name for every SAML federated user.

Step 1: Alice searches the CloudTrail event logs for the eventName called TerminateInstances.

To begin, Alice needs to find the CloudTrail event that was logged when the SAML federated user terminated the EC2 instance. To find the event log for the eventName called TerminateInstances, she searches the CloudTrail log file in the S3 bucket that was specified when she created the trail. As an alternative, she could have used the CloudTrail API Activity History feature on the CloudTrail console. To learn more about how to find and interpret your CloudTrail log files, see Getting and Viewing Your CloudTrail Log Files.

The following code shows the event log entry Alice found when she searched the CloudTrail logs for the eventName called TerminateInstances. The eventName is highlighted in line 24.

1 "eventVersion": "1.04", 
2 "userIdentity": {
3     "type": "AssumedRole",
4     "principalId": "AROAIDPPEZS35WEXAMPLE:b@example.com",
5     "arn": "arn:aws:sts::123456789012:assumed-role/RoleToBeAssumed/b@example.com",
6     "accountId": "123456789012",
7     "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
8     "sessionContext": {
9       "attributes": {
10         "creationDate": "20131102T010628Z",
11         "mfaAuthenticated": "false"
12       },
13       "sessionIssuer": {
14         "type": "Role",
15         "principalId": "AROAIDPPEZS35WEXAMPLE",
16         "arn": "arn:aws:iam::123456789012:role/RoleToBeAssumed",
17         "accountId": "123456789012",
18         "userName": "RoleToBeAssumed"
19       }
20     }
21 },
22 "eventTime": "2016-03-09T21:50:16Z",
23 "eventSource": "ec2.amazonaws.com",
24 "eventName": "TerminateInstances",
25 "awsRegion": "us-east-1",
26 "sourceIPAddress": "127.0.0.1",
27 "userAgent": "signin.amazonaws.com",
28 "requestParameters": {
29         "instancesSet": {
30             "items": [
31              { "instanceId": "i-a6900d00" } ]
32       }
33 },
34 "responseElements": {
35         "instancesSet": {
36             "items": [ {
37                     "instanceId": "i-a6900d00",
38                     "currentState": {
39                         "code": 32,
40                         "name": "shutting-down" },
41                     "previousState": {
42                         "code": 16,
43                         "name": "running" }
44                     }
45             ]
46       }
47 },
48 "requestID": "59dbff89-35bd-4eac-99ed-be587EXAMPLE",
49 "eventID": "395a28e0Example",
50 "eventType": "AwsApiCall",
51 "recipientAccountId": "123456789012"

Step 2: In the userIdentity section of the event log found in Step 1, Alice determines the ARN, including the role session name, of the IAM role assumed by the federated user.

After Alice found the TerminateInstances event log entry in Step 1, she determined the associated ARN, including the role session name, of the IAM role assumed by SAML federated user, Bob. As you might have noticed in the log entry shown in Step 1, Line 5 includes the IAM role’s ARN, which is arn:aws:sts::123456789012:assumed-role/RoleToBeAssumed/b@example.com, and the ARN includes the role session name, b@example.com.

With the role session name identified, the next step for Alice is to find the AssumeRoleWithSAML event that includes the role session name, b@example.com.

Step 3: Alice searches the CloudTrail event logs for the eventName called AssumeRoleWithSAML that includes the IAM role’s ARN identified in Step 2.

In order to find the event log entry with the eventName called AssumeRoleWithSAML and the IAM role’s ARN (arn:aws:sts::123456789012:assumed-role/RoleToBeAssumed/b@example.com) identified in Step 2, Alice uses the CloudTrail log file in the S3 bucket with the same or closest timestamp to the timestamp of the CloudTrail log file she found in Step 1.

On searching for the eventName called AssumRoleWithSAML that includes the IAM role ARN, arn:aws:sts::123456789012:assumed-role/RoleToBeAssumed/b@example.com, Alice finds the following event log. The matched ARN of the IAM role is highlighted in line 33.

1 {
2     "eventVersion": "1.04",
3     "userIdentity": {
4         "type": "SAMLUser",
5         "principalId": "71ECIxd9HdqExample:Bob",
6         "userName": "Bob",
7         "identityProvider": "71ECIxd9HdqExample"
8     },
9     "eventTime": "2016-03-09T01:22:27Z",
10     "eventSource": "sts.amazonaws.com",
11     "eventName": "AssumeRoleWithSAML",
12     "awsRegion": "us-east-1",
13     "sourceIPAddress": "127.0.0.1",
14     "userAgent": "signin.amazonaws.com",
15     "requestParameters": {
16         "sAMLAssertionID": "_c0046ce598b94b9d4b8e45027Example",
17         "roleSessionName": "b@example.com",
18         "durationSeconds": 3600,
19         "roleArn": "arn:aws:iam::123456789012:role/RoleToBeAssumed",
20         "principalArn": "arn:aws:iam::123456789012:saml-provider/Shibboleth"
21     },
22     "responseElements": {
23         "subjectType": "transient",
24         "issuer": "https://sts-integ.amazon.com/idp/shibboleth",
25         "credentials": {
26             "accessKeyId": "ASIADMUEK63ZEXAMPLE",
27             "expiration": "Mar 9, 2016 2:22:27 AM",
28             "sessionToken": encoded session token blob
29         },
30         "nameQualifier": "71ECIxd9HdqExample",
31         "assumedRoleUser": {
32             "assumedRoleId": "AROAIDPPEZS35WEXAMPLE:RoleToBeAssumed",
33             "arn": "arn:aws:sts::123456789012:assumed-role/RoleToBeAssumed/b@example.com"
34         },
35         "subject": "Bob",
36         "audience": "https://signin.aws.amazon.com/saml"
37     },
38     "requestID": "6Example-e595-11e5-b2c7-c9Example",
39     "eventID": "d8ba460c-265a-41e0-9352-4401bEXAMPLE",
40     "eventType": "AwsApiCall",
41     "recipientAccountId": "123456789012"
42 }

Step 4: Alice Identifies the SAML federated user identity in the username attribute in the CloudTrail event log she found in Step 3.

Now that Alice has found the event log in Step 3, she searches for the userName in the UserIdentity section (line 6 of the event log in Step 3) to identify the SAML federated user, Bob. This identity is the same value Alice set in the subject of the SAML claim and uniquely identifies the individual user in her organization who terminated the EC2 instance.

Conclusion

By following the steps in this blog post, Alice was able to determine that a SAML federated user, Bob, was responsible for terminating the EC2 instance in the example AWS account. You can use the same steps to identify any web identity federation or SAML federated user by using CloudTrail events.

We look forward to hearing how you are using this functionality and the ways we can improve it. You can post comments in the “Comments” section below, or visit the CloudTrail forum to ask questions about usage and implementation.

– Akshat