Query Details
let _MonitoredRoles =
_GetWatchlist("AccountId-AuditAWSAccounts")
| where Notes has "[RoleActivity]"
| project RequestedRole = Auxiliar, Auditors = Auditor, AlertSeverity = Severity
;
let _AWSAccounts =
_GetWatchlist("AccountId-AuditAWSAccounts")
| project AccountId, AccountName
;
union
(
AWSCloudTrail
| where EventName in ("Federate", "GetRoleCredentials")
| extend DynamicServiceEventDetails = todynamic(ServiceEventDetails)
| extend
RequestedRole = tostring(DynamicServiceEventDetails["role_name"]),
RequestedRoleAccountId = tostring(DynamicServiceEventDetails["account_id"])
),
(
AWSCloudTrail
| where EventName in ("AssumeRole")
| extend RoleArn = tostring(todynamic(RequestParameters)["roleArn"])
| extend
RequestedRole = tostring(split(RoleArn, "/")[-1]),
RequestedRoleAccountId = tostring(split(RoleArn, ":")[4])
)
| lookup kind=inner _MonitoredRoles on RequestedRole
| lookup kind=leftouter (
_AWSAccounts
| project RequestedRoleAccountName = AccountName, AccountId
) on $left.RequestedRoleAccountId == $right.AccountId
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
SourceIpAddresses = array_sort_asc(make_set_if(SourceIpAddress, isnotempty(SourceIpAddress), 100)),
EventNames = array_sort_asc(make_set(EventName)),
ReadOnly = make_set_if(ReadOnly, isnotempty(ReadOnly)),
RequestedRoleAccounts = array_sort_asc(make_set(coalesce(RequestedRoleAccountName, RequestedRoleAccountId))),
take_any(*)
by RequestedRole, UserIdentityType, UserIdentityAccountId, SessionIssuerArn, UserIdentityPrincipalid, RecipientAccountId, EventSource, EventTypeName
| extend Identity = coalesce(UserIdentityUserName, UserIdentityPrincipalid)
| mv-apply SourceIpAddress = SourceIpAddresses to typeof(string) on (
summarize AddressesList = strcat_array(array_sort_asc(make_set_if(SourceIpAddress, not(SourceIpAddress has ".amazonaws.com"))), '\n\n- ')
)
| extend AlertDescription = strcat(
'This rule detects operations of specified roles in AWS accounts.\n\nThe role "',
RequestedRole,
'" was used by "',
Identity,
'" in the AWS accounts:\n\n- ',
strcat_array(RequestedRoleAccounts, '\n\n- '),
'\n\nThe operations were made from the addresses:\n\n- ',
AddressesList,
'\n'
)
| project
StartTime,
EndTime,
UserIdentityType,
UserIdentityAccountId,
SessionCreationDate,
SessionIssuerUserName,
SessionIssuerPrincipalId,
SessionIssuerArn,
UserIdentityUserName,
UserIdentityPrincipalid,
UserIdentityArn,
UserIdentityAccessKeyId,
RecipientAccountId,
Identity,
SourceIpAddresses,
EventSource,
EventTypeName,
EventNames,
RequestedRole,
RequestedRoleAccounts,
ManagementEvent,
ReadOnly,
ErrorCode,
ErrorMessage,
RequestParameters,
ResponseElements,
Resources,
ServiceEventDetails,
SessionMfaAuthenticated,
UserAgent,
AwsEventId,
AlertSeverity,
AlertDescription,
Auditors
This query is designed to monitor specific roles in AWS accounts. It first retrieves a list of monitored roles and AWS accounts from a watchlist. Then it checks AWS CloudTrail logs for events where these roles were used.
The query looks for two types of events: "Federate" and "GetRoleCredentials", which are related to role delegation and credential retrieval, and "AssumeRole", which is related to role assumption.
For each event, it extracts the role name and account ID. It then matches these with the monitored roles and AWS accounts.
The query then summarizes the data, providing the start and end times of the events, the source IP addresses, the event names, and the accounts where the roles were used.
It also creates a description of the alert, detailing the role used, the identity of the user, the AWS accounts involved, and the source IP addresses.
Finally, it projects a list of fields, including user identity details, event details, role details, and alert details.
In simple terms, this query is used to monitor and report on the usage of specific roles in AWS accounts.

Jose Sebastián Canós
Released: August 3, 2023
Tables
Keywords
Operators