Discrepancy Between CloudTrail and S3 Access Logs for GetObject Events with External User ARNs

0

Summary of the Issue:

I'm experiencing a discrepancy between CloudTrail logs and S3 Access Logs when tracking GetObject requests for a specific S3 bucket. While the Access Logs correctly show the User ARN from external accounts, CloudTrail does not capture the external User ARN, and instead logs the event with userIdentity.type as AWSAccount and no userIdentity.arn details.


Detailed Problem Description:

I have configured CloudTrail to track GetObject events for files in a shared S3 bucket that has external account access permisioned via a bucket policy. My goal is to capture all GetObject requests, especially those made by external accounts that are allowed access via User ARNs.

However, in the CloudTrail logs, for requests made by an external account, the userIdentity.arn field is missing, and userIdentity.type is showing as AWSAccount instead of IAMUser or AssumedRole. This behavior is inconsistent with what I'm seeing in the S3 Access Logs, where the correct User ARN is captured.

This issue makes it difficult to correctly audit and track external user activities via CloudTrail.


CloudTrail Configuration:

Here is the configuration of the CloudTrail event selector that I have set up to capture GetObject events for the bucket:

[
  {
    "Name": "Log GetObject data events for S3 with external User ARN permissions",
    "FieldSelectors": [
      {
        "Field": "eventCategory",
        "Equals": ["Data"]
      },
      {
        "Field": "resources.type",
        "Equals": ["AWS::S3::Object"]
      },
      {
        "Field": "resources.ARN",
        "StartsWith": ["arn:aws:s3:::shared-bucket/"]
      },
      {
        "Field": "eventName",
        "Equals": ["GetObject"]
      },
      {
        "Field": "readOnly",
        "Equals": ["true"]
      }
    ]
  }
]

S3 Bucket Policy:

Here is the S3 bucket policy that allows the external user access to GetObject:

{
    "Sid": "external user arn permissioned get object",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::555555555555:user/external"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::shared-bucket/*"
}

This policy gives GetObject permissions to the external user ARN (arn:aws:iam::555555555555:user/external) on all objects within the shared-bucket.


Examples of Log Data:

  1. S3 Access Log Entry:

bucket_name: shared-bucket user_identity_arn: arn:aws:iam::555555555555:user/external operation: REST.GET.OBJECT object_key: shared--data/file.csv

  • This log correctly shows the User ARN (arn:aws:iam::555555555555:user/external) of the external user accessing the file shared--data/file.csv in the bucket shared-bucket.
  1. CloudTrail Log Entry:
{
    "eventVersion": "1.10",
    "eventTime": "2024-10-24T16:18:04Z",
    "eventSource": "s3.amazonaws.com",
    "eventName": "GetObject",
    "awsRegion": "us-east-1",
    "userAgent": "[Boto3/1.26.64 Python/3.10.8 Darwin/22.1.0 Botocore/1.29.64]",
    "resources": [
        {
            "type": "AWS::S3::Object",
            "ARN": "arn:aws:s3:::shared-bucket/shared--data/file.csv"
        },
        {
            "type": "AWS::S3::Bucket",
            "ARN": "arn:aws:s3:::shared-bucket"
        }
    ],
    "eventType": "AwsApiCall",
    "eventCategory": "Data",
    "userIdentity.type": "AWSAccount",
    "userIdentity.accountId": "555555555555",
    "userIdentity.arn": null,
    "requestParameters": {
        "bucketName": "shared-bucket",
        "key": "shared--data/file.csv"
    }
}
  • In this CloudTrail log entry, the GetObject request for the same file (shared--data/file.csv) is recorded, but the userIdentity.arn field is null, and the userIdentity.type is set to AWSAccount instead of providing the correct User ARN (arn:aws:iam::555555555555:user/external).

Expected Behavior:

I expect that CloudTrail should correctly capture the User ARN for external accounts accessing the bucket, similar to how the S3 Access Logs do. Specifically:

  • The userIdentity.arn field should show the external User ARN (arn:aws:iam::555555555555:user/external).
  • The userIdentity.type should reflect IAMUser or AssumedRole instead of AWSAccount.

Request for Support:

Could you please assist in identifying why CloudTrail is not capturing the external User ARN as expected for GetObject events, even though the S3 Access Logs are correctly capturing this information?

Additionally, is there any specific configuration I need to change in CloudTrail or IAM policies to ensure that CloudTrail logs the correct external User ARN?

1 Answer
0

The discrepancy you're experiencing between CloudTrail logs and S3 Access Logs for GetObject events with external User ARNs is a known behavior in AWS CloudTrail. This is not an error or misconfiguration on your part, but rather a limitation of how CloudTrail logs cross-account access to S3 buckets.

When an IAM user or role from an external AWS account accesses an S3 bucket in your account, CloudTrail logs this as an "AWSAccount" type event rather than an "IAMUser" or "AssumedRole" event. This is because CloudTrail in your account doesn't have direct visibility into the identity details of users in other AWS accounts.

In these cross-account scenarios, CloudTrail will log:

  • The userIdentity.type as "AWSAccount"
  • The userIdentity.accountId as the external AWS account ID
  • The userIdentity.arn as null

This behavior is by design and is intended to protect the privacy and security of users in other AWS accounts.

S3 Access Logs, on the other hand, are able to capture more detailed information about the requester, including the full ARN of external users. This is because S3 has direct access to this information at the time of the request.

Unfortunately, there isn't a configuration change you can make in CloudTrail or IAM policies to capture the external User ARN in CloudTrail logs for cross-account access. This limitation is inherent to how CloudTrail works across account boundaries.

To get the level of detail you're looking for, you have a few options:

  1. Continue using S3 Access Logs alongside CloudTrail for the most comprehensive logging solution. While this requires managing two log sources, it provides the most complete picture of access to your S3 bucket.

  2. If possible, use AWS Organizations and enable all features. This allows CloudTrail to capture user identity information across accounts within your organization.

  3. Consider implementing custom logging solutions or using AWS Lambda in conjunction with CloudTrail to enrich the logs with additional information from other sources.

  4. Use AWS CloudTrail Lake, which allows you to aggregate and analyze CloudTrail logs from multiple accounts in a centralized location. While it won't change how the events are logged, it can make it easier to correlate events across accounts.

Remember, while CloudTrail may not provide the exact User ARN for cross-account access, it still provides valuable information such as the source account ID, which can be used for auditing and security analysis.
Sources
Secure and Standardized Logging - AWS CloudTrail Resources - Amazon Web Services
Monitoring S3 on Outposts with AWS CloudTrail logs - Amazon S3 on Outposts
Identifying Amazon S3 requests using CloudTrail - Amazon Simple Storage Service

profile picture
answered 2 months ago
EXPERT
reviewed 2 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions