Sigma Arrays
Overview
Standard Sigma does not natively support matching values within arrays in log events. This limitation affects many common log sources including CloudTrail, GCP Audit Logs, Okta, and Kubernetes audit logs, all of which use arrays extensively in their event structures. AlphaSOC extends Sigma with array matching capabilities as a custom feature, enabling detection rules that evaluate conditions against individual array elements.
Array support is currently available for raw event processing only. OCSF-normalized events do not support array matching at this time.
Array Matching Syntax
Array matching in Sigma uses nested detection blocks. When a field references an
array, you define a nested condition and selection structure that specifies
how array elements should be matched. This approach allows for multiple
selectors on a single array object, including NOT conditions.
Match any (default)
By default, array matching returns true if any element in the array matches the condition:
detection:
condition: selection
selection:
arrayField:
condition: selection
selection:
fieldInArrayObject: "value"
Match all
Use the |arrayAll modifier to require that all elements in the array match
the condition:
detection:
condition: selection
selection:
arrayField|arrayAll:
condition: selection
selection:
fieldInArrayObject: "value"
Nested arrays
For log sources with deeply nested array structures, you can chain array matching across multiple levels:
detection:
condition: selection
selection:
authorizationInfo|arrayAll:
condition: selection
selection:
resourceAttributes:
condition: selection
selection:
values|arrayAll:
condition: selection
selection:
key: "request.auth.claims.groups"
value|contains: "system:authenticated"
Dot pseudo-field
Use the . pseudo-field to match simple values (strings or numbers) directly
within an array:
detection:
condition: selection
selection:
eventType: "AwsApiCall"
resourceTypeFilters:
condition: selection
selection:
.|startswith: "prefix:"
Real-World Examples
AWS RDS snapshot sharing
Consider the following AWS CloudTrail event, generated when an IAM user shares a database snapshot with an external AWS account:
{
"eventVersion": "1.08",
"userIdentity": {
"type": "IAMUser",
"arn": "arn:aws:iam::111122223333:user/db-admin"
},
"eventTime": "2026-04-07T16:22:11Z",
"eventSource": "rds.amazonaws.com",
"eventName": "ModifyDBSnapshotAttribute",
"awsRegion": "us-east-1",
"sourceIPAddress": "203.0.113.50",
"userAgent": "aws-cli/2.15.0",
"requestParameters": {
"dBSnapshotIdentifier": "prod-finance-snapshot-2026-04-07",
"attributeName": "restore",
"valuesToAdd": ["999900001111"]
},
"responseElements": null
}
The key field here is requestParameters.valuesToAdd—an array of AWS account
IDs being granted restore access to this snapshot. AWS also accepts the special
string all to make a snapshot publicly restorable.
A detection rule needs to flag two threats:
- The snapshot is made public (the array contains
all). - The snapshot is shared with an unknown external account (an account ID that doesn't belong to the organization).
Using our array extensions, both conditions can be expressed in one rule:
detection:
condition:
selection_event and (selection_public or selection_allowed_accounts)
selection_event:
eventSource: rds.amazonaws.com
eventName:
- ModifyDBSnapshotAttribute
- ModifyDBClusterSnapshotAttribute
requestParameters.attributeName: restore
selection_public:
requestParameters.valuesToAdd:
condition: sel
sel:
.: all
selection_allowed_accounts:
requestParameters.valuesToAdd|arrayAll:
condition: not sel
sel:
.:
- 111122223333
- 444455556666
- 777788889999
- 123456789012
selection_public: uses the.pseudo-field to iterate the array and checks whether any element equalsall.selection_allowed_accounts: uses the.pseudo-field to check whether any element matches a known internal account ID. Thenotin the condition inverts this—so the rule fires when at least one account ID in the array is not in the allowlist, i.e. it belongs to an unknown external party.
In the example event above, 999900001111 is not in the internal account list,
so not sel is true, and the alert fires.
GitHub repository ruleset bypass
Consider the following GitHub audit log event, generated when an administrator modifies a repository ruleset to exclude the main branch from protection:
{
"@timestamp": 1775557901285,
"action": "repository_ruleset.update",
"actor": "octo-admin",
"actor_id": 1234567,
"org": "octo-org",
"repo": "octo-org/payments-api",
"operation_type": "modify",
"ruleset_id": 9876543,
"ruleset_name": "Protect default branch",
"ruleset_enforcement": "enabled",
"ruleset_source_type": "Repository",
"ruleset_conditions_updated": [
{
"target": "ref_name",
"old_parameters": {
"include": ["refs/heads/main"],
"exclude": []
},
"parameters": {
"include": [],
"exclude": ["refs/heads/main"]
}
}
]
}
The key field here is ruleset_conditions_updated—an array of condition changes
applied to the ruleset. Each element contains a target field identifying what
the condition applies to, along with old_parameters and parameters objects
indicating the before and after state of the update.
We want to detect if the main branch was excluded in the updated parameters. To
do that, the detection needs to flag when refs/heads/main appears in the
parameters.exclude array:
detection:
condition: selection
selection:
action: repository_ruleset.update
ruleset_conditions_updated:
condition: selection
selection:
target: ref_name
parameters.exclude:
condition: selection
selection:
.: refs/heads/main
ruleset_conditions_updated: iterates the array of condition changes.target: ref_name: matches only changes affecting branch name conditions.parameters.exclude/.: refs/heads/main: uses nested array matching with the.pseudo-field to check ifrefs/heads/mainappears in the exclusion list.
In the example event above, the main branch was excluded in the updated parameters, so the detection fires.
Slack login from new ASN
Consider the following Slack audit log event, generated when a user logs in from an IP address associated with a previously unseen ASN:
{
"id": "Ev04ABCDEF",
"date_create": 1717430400,
"action": "user_login",
"actor": {
"type": "user",
"user": {
"id": "U01234567",
"email": "alice@example.com"
}
},
"context": {
"ip_address": "203.0.113.42",
"ua": "Mozilla/5.0"
},
"details": {
"ip_address_details": ["new-asn", "vpn"]
}
}
The key field here is details.ip_address_details—an array of tags describing
characteristics of the source IP address. Tags like new-asn or vpn provide
context about the network origin.
A detection rule needs to flag logins from networks not previously seen for this workspace, which could indicate account compromise or credential theft:
detection:
condition: selection
selection:
details.ip_address_details:
condition: selection
selection:
.: new-asn
details.ip_address_details: targets the array of IP characteristics..: new-asn: uses the.pseudo-field to check whether any element in the array equalsnew-asn.
In the example event above, the array contains new-asn, so the detection
fires. The presence of vpn is noted but doesn't affect this particular rule.
Limitations
- OCSF not supported: Array matching is currently available only for raw event processing. OCSF-normalized events do not support this feature.
Further Reading
- Sigma Supported Attributes - Full list of supported Sigma modifiers and conditions
- Sigma Correlations - Aggregate multiple events for complex detection patterns