elastic / elastic/integrations
[AWS]: Map userIdentity.onBehalfOf for IAM Identity Center events
- Dominant language
- Handlebars
- Stars
- 333
- Forks
- 647
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 209
Description
### Integration Name
AWS [packages/aws]
### Dataset Name
aws.cloudtrail
### Integration Version
8.1.0
### Agent Version
9.6.0
### OS Version and Architecture
Not host specific
### User Goal
When writing detection rules for AWS IAM Identity Center (AWS SSO). Several high-value detections need to identify, group, and baseline the specific Identity Center user that acted in or was the subject of an event: administrator password resets, portal sign-ins, forced first-login password changes, and directory user or group changes.
For every event whose `userIdentity.type` is `IdentityCenterUser`, the acting Identity Center user is present in the raw record only as `userIdentity.onBehalfOf.userId` (a directory UUID) and `userIdentity.onBehalfOf.identityStoreArn`. I need those two values mapped to queryable fields so a rule can:
- group or run a New Terms baseline on the acting Identity Center user
- name the affected user in the alert
- build aggregation detections such as one principal forcing password changes across many distinct users
### Existing Features
The integration maps `userIdentity.type` but, for `IdentityCenterUser` events, leaves `userIdentity.arn` empty and `user.name` null, and does not map `userIdentity.onBehalfOf` at all. There is no `aws.cloudtrail.user_identity.onBehalfOf.*` field. The only surviving copy of the acting user is inside `event.original`.
Because of that:
- KQL detection rules can only wildcard-match `event.original` to test the *presence* of `onBehalfOf`; they cannot extract the value into a field, so New Terms and grouping on the Identity Center user are impossible.
- The value can be recovered with an ES|QL `GROK` over `event.original`, but that forces the rule to be an ES|QL rule, scans the full raw event on every run, and is fragile to JSON key ordering. It is a workaround, not a stable field.
### What did you see?
Ingested `UpdatePassword` document (forced first-login change). The mapped identity fields are empty and the acting user is only inside `event.original`:
```json
{
"userIdentity": {
"type": "IdentityCenterUser",
"arn": "",
"accountId": "x",
"accessKeyId": "",
"onBehalfOf": {
"userId": "y",
"identityStoreArn": "arn:aws:identitystore::x:identitystore/d-9067e0196b"
},
"credentialId": "z"
},
"eventTime": "2026-09-01T14:33:25Z",
"eventSource": "sso-directory.amazonaws.com",
"eventName": "UpdatePassword",
"awsRegion": "us-east-1",
"sourceIPAddress": "",
"requestParameters": null,
"responseElements": null
}
```
Mapped-field view of the same document, showing the value is not queryable:
```
aws.cloudtrail.user_identity.type = "IdentityCenterUser"
aws.cloudtrail.user_identity.arn = null
user.name = null
aws.cloudtrail.user_identity.onBehalfOf.* = (field does not exist)
```
Confirmation that the value exists and is recoverable only from `event.original`, via ES|QL `GROK`:
```esql
FROM logs-aws.cloudtrail-*
| WHERE event.provider == "sso-directory.amazonaws.com" AND event.action == "UpdatePassword"
AND event.original LIKE "*onBehalfOf*"
| GROK event.original """"onBehalfOf":\{"userId":"%{DATA:obo_user_id}","identityStoreArn":"%{DATA:obo_identity_store}"\}"""
| KEEP @timestamp, aws.cloudtrail.user_identity.type, obo_user_id, obo_identity_store
```
Result:
```
@timestamp user_identity.type obo_user_id obo_identity_store
2026-09-01T14:33:25Z IdentityCenterUser y arn:aws:identitystore::x:identitystore/d-9067e0196b
```
### Anything else?
Requested mapping:
| Source (CloudTrail) | Requested field | Type |
| --- | --- | --- |
| `userIdentity.onBehalfOf.userId` | `aws.cloudtrail.user_identity.on_behalf_of.user_id` | keyword |
| `userIdentity.onBehalfOf.identityStoreArn` | `aws.cloudtrail.user_identity.on_behalf_of.identity_store_arn` | keyword |
Note: 7.4.0 (PR #20403) added previously-dropped CloudTrail fields and populated `related.*`, but `userIdentity.onBehalfOf` was not among them. It remains unmapped through 8.1.0, `aws.cloudtrail.user_identity.on_behalf_of.*` and `.onBehalfOf.*` both return `Unknown column` at query time.
Suggested ECS alignment, so the acting Identity Center user is usable by generic rules and entity analytics:
- populate `user.id` with `onBehalfOf.userId` for `IdentityCenterUser` events;
- add it to `related.user` as well, consistent with how 7.1.0 (PR #20318) already uses `related.user` for assumed-role session names for cross-source correlation.
Reference: AWS CloudTrail `userIdentity` element, `onBehalfOf` object — https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html
Contributor guide
Assessment
This issue has not been assessed yet.