hierarchy_match ↗
Use the hierarchy_match() function to determine whether an asset belongs to a specified node in the organizational (org) asset hierarchy. You can match against the hierarchy path (the ordered list of container names from the org root down to a specific node), a specific hierarchy node ID (id_path), or both. Calling the function with no arguments matches every asset (equivalent to *).
The function is only available when the org asset hierarchy is enabled for your tenant, and it operates on the asset hierarchy fields xdm.asset.hierarchy.path (the chain of container names joined by /) and xdm.asset.hierarchy.id_path (the ID of the deepest node in that path). It is intended for asset datasets (for example, asset_inventory) and is not supported inside correlation rules.
Syntax
hierarchy_match(<path_segments>, <id_path>)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
path_segments |
array | No | An ordered list of the container names from the org root down to the target node (for example, ["Org", "ou1", "ou2"]). Segments are joined with / and matched as a path prefix, so the node and all of its descendants match. The path contains only container levels (organization, OUs, management groups, folders) — not the leaf account/project/subscription. If omitted (or an empty array), no path restriction is applied and all paths match. As a shorthand, passing a single string value is treated as the id_path argument. |
id_path |
string | No | The resource ID of a specific hierarchy node — the ID of the deepest container in the path (for example, an OU ID, management-group ID, or folder ID). Use it to unambiguously target a node even when names are duplicated. When provided, it must match the asset's id_path. If omitted, no ID restriction is applied. |
Returns
Type: boolean
Description: The hierarchy_match() function returns true if the asset belongs to the specified org hierarchy node (satisfying both the path and ID conditions that were supplied), and false otherwise.
Usage notes
- Path vs. id_path: The
pathandid_pathdescribe the same container node from two angles:pathis the chain of container names, andid_pathis the ID of the deepest node in that chain. Neither includes the account/project/subscription. - Disambiguating duplicate names: Use
id_pathwhen container names are ambiguous. For example, if two different OUs are both namedProduction, matching on the path name alone is ambiguous — supplying the OU'sid_pathpins the match to exactly the OU you mean. - Combinable, optional parameters: Both parameters are optional and can be combined:
hierarchy_match()— matches all assets (no restriction).hierarchy_match(arraycreate("Org", "ou1"))— path-only match (the node and all its descendants).hierarchy_match(null, "ou-a1b2-prod01")— ID-only match (match the node with this exact ID, on any path).hierarchy_match("ou-a1b2-prod01")— shorthand for an ID-only match.hierarchy_match(arraycreate("Org", "ou1"), "ou-a1b2-prod01")— matches only when both the path prefix and the ID condition are satisfied.
- Prefix, case-sensitive, literal matching: The path match is a prefix match: it matches the exact path as well as any child path beneath it. It is case-sensitive and matches literal characters (wildcard characters such as
%and_in path segments are treated literally, not as wildcards). - Ambiguous scalar + ID is rejected: Passing a single scalar/string value together with an explicit
id_pathis ambiguous and is rejected with a validation error. Use an array for the first argument whenever you also supply an ID. - Negation: To negate a match (find assets that do not belong to a node), compare the result to
false(for example,hierarchy_match(...) = false) or use!= true. - Typical use: This function is typically used within the
filterstage to scope results to an org hierarchy node, or within thealterstage to tag records with their hierarchy membership. -
Cloud hierarchy structure: The org hierarchy mirrors the native resource-organization model of each cloud provider. In every case the hierarchy stops at the container level — the leaf account, project, or subscription is not part of the path or the
id_path. Thepath_segmentsargument is the ordered list of the display names of the container levels (not their IDs, and not the leaf), andid_pathis the ID of the deepest container node in the path. Matching onpath_segmentsalone selects the target container node and all of its descendants, which is useful for scoping to an entire OU, management group, or folder subtree.Cloud Provider Container Levels (org root → node) Leaf (not part of hierarchy path/id_path) Example Path Example id_path(ID of deepest node)AWS Organization → Organizational Unit (OU) Account Acme Corp/ProductionOU ID: ou-a1b2-prod01Azure Management Group → (nested Management Groups) Subscription Tenant Root Group/PlatformManagement Group ID: mg-platformGCP Organization → Folder(s) Project acme.com/ProductionFolder ID: folders/574839201122
Examples
Example 1: Scope to an AWS organizational unit
Goal: Return only the assets that belong to the AWS Production OU under the Acme Corp organization, including every account nested beneath that OU.
XQL code:
config timeframe = 1d | dataset = asset_inventory | filter hierarchy_match(arraycreate("Acme Corp", "Production")) | fields asset_id, asset_name, cloud_provider, xdm.asset.hierarchy.path | limit 3
Explanation: You apply a path-only match in a filter stage. The path contains only the container levels (organization and OU), so matching on Acme Corp/Production returns every asset in any account under the Production OU (and its sub-OUs), because the match is a prefix match.
Output:
| ASSET_ID | ASSET_NAME | CLOUD_PROVIDER | XDM.ASSET.HIERARCHY.PATH |
|---|---|---|---|
| i-0a1b2c3d | payments-api-01 | AWS | Acme Corp/Production |
| i-0e4f5g6h | orders-worker-02 | AWS | Acme Corp/Production |
| i-0i7j8k9l | billing-db-01 | AWS | Acme Corp/Production/Billing |
Example 2: Disambiguate an OU by ID
Goal: Two OUs are both named Production under different parents. Return only the assets under the specific Production OU whose ID is ou-a1b2-prod01.
XQL code:
config timeframe = 1d | dataset = asset_inventory | filter hierarchy_match(arraycreate("Acme Corp", "Production"), "ou-a1b2-prod01") = true | fields asset_id, asset_name, xdm.asset.hierarchy.path, xdm.asset.hierarchy.id_path | limit 3
Explanation: Because the OU name alone is ambiguous, you combine the path prefix (Acme Corp/Production) with the OU's ID as id_path. An asset is returned only when its path starts with Acme Corp/Production and its id_path equals ou-a1b2-prod01, so only the intended OU is matched.
Output:
| ASSET_ID | ASSET_NAME | XDM.ASSET.HIERARCHY.PATH | XDM.ASSET.HIERARCHY.ID_PATH |
|---|---|---|---|
| i-0a1b2c3d | payments-api-01 | Acme Corp/Production | ou-a1b2-prod01 |
| i-0m1n2o3p | payments-cache-01 | Acme Corp/Production | ou-a1b2-prod01 |
| i-0q4r5s6t | payments-lb-01 | Acme Corp/Production | ou-a1b2-prod01 |
Example 3: Scope to an Azure management group
Goal: Tag assets that live under the Azure Platform management group (any subscription beneath it), starting from the Tenant Root Group.
XQL code:
config timeframe = 1d | dataset = asset_inventory | alter in_platform_mg = hierarchy_match(arraycreate("Tenant Root Group", "Platform")) | fields asset_id, cloud_provider, xdm.asset.hierarchy.path, in_platform_mg | limit 3
Explanation: You use a path-only match in an alter stage. In Azure the path contains the management-group chain (Management Group → nested Management Groups) and stops above the subscription, so matching on Tenant Root Group/Platform returns true for every asset in any subscription nested under the Platform management group, and false otherwise.
Output:
| ASSET_ID | CLOUD_PROVIDER | XDM.ASSET.HIERARCHY.PATH | IN_PLATFORM_MG |
|---|---|---|---|
| vm-web-01 | AZURE | Tenant Root Group/Platform | true |
| vm-api-02 | AZURE | Tenant Root Group/Platform/Prod | true |
| vm-sales-03 | AZURE | Tenant Root Group/Business | false |
Example 4: Pin to a specific Azure management group by ID
Goal: Return only the assets under the Platform management group whose ID is mg-platform.
XQL code:
config timeframe = 1d | dataset = asset_inventory | filter hierarchy_match(arraycreate("Tenant Root Group", "Platform"), "mg-platform") = true | fields asset_id, asset_name, xdm.asset.hierarchy.path, xdm.asset.hierarchy.id_path | limit 3
Explanation: You combine the management-group path prefix (Tenant Root Group/Platform) with the management group's ID as id_path. Only assets whose path starts with Tenant Root Group/Platform and whose id_path equals mg-platform are returned — the ID pins the match to the exact management group.
Output:
| ASSET_ID | ASSET_NAME | XDM.ASSET.HIERARCHY.PATH | XDM.ASSET.HIERARCHY.ID_PATH |
|---|---|---|---|
| vm-web-01 | payments-web-01 | Tenant Root Group/Platform | mg-platform |
| vm-web-02 | payments-web-02 | Tenant Root Group/Platform | mg-platform |
| st-blob-01 | payments-storage | Tenant Root Group/Platform | mg-platform |
Example 5: Scope to a GCP folder
Goal: Return only the assets that belong to the GCP Production folder under the acme.com organization, including every project nested inside that folder.
XQL code:
config timeframe = 1d | dataset = asset_inventory | filter hierarchy_match(arraycreate("acme.com", "Production")) | fields asset_id, asset_name, cloud_provider, xdm.asset.hierarchy.path | limit 3
Explanation: In GCP the path contains the organization and its folders and stops above the project. A path-only match on acme.com/Production returns every asset in any project inside the Production folder (and any sub-folders), because the match is a prefix match.
Output:
| ASSET_ID | ASSET_NAME | CLOUD_PROVIDER | XDM.ASSET.HIERARCHY.PATH |
|---|---|---|---|
| gce-inst-01 | payments-prod-vm | GCP | acme.com/Production |
| gce-inst-02 | orders-prod-vm | GCP | acme.com/Production |
| gcs-bucket-01 | billing-prod-data | GCP | acme.com/Production/Billing |
Example 6: Pin to a specific GCP folder by ID
Goal: Return only the assets under the Production folder whose ID is folders/574839201122.
XQL code:
config timeframe = 1d | dataset = asset_inventory | filter hierarchy_match(arraycreate("acme.com", "Production"), "folders/574839201122") = true | fields asset_id, asset_name, xdm.asset.hierarchy.path, xdm.asset.hierarchy.id_path | limit 3
Explanation: You combine the folder path prefix (acme.com/Production) with the folder's ID as id_path. Only assets whose path starts with acme.com/Production and whose id_path equals folders/574839201122 are returned, pinning the match to the exact folder even if another folder shares the same name.
Output:
| ASSET_ID | ASSET_NAME | XDM.ASSET.HIERARCHY.PATH | XDM.ASSET.HIERARCHY.ID_PATH |
|---|---|---|---|
| gce-inst-01 | payments-prod-vm | acme.com/Production | folders/574839201122 |
| gce-disk-01 | payments-prod-disk | acme.com/Production | folders/574839201122 |
| gcs-bucket-02 | payments-prod-bucket | acme.com/Production | folders/574839201122 |
Example 7: Exclude a hierarchy node (negation)
Goal: Return all assets except those in the Acme Corp/Sandbox OU.
XQL code:
config timeframe = 1d | dataset = asset_inventory | filter hierarchy_match(arraycreate("Acme Corp", "Sandbox")) = false | fields asset_id, cloud_provider, xdm.asset.hierarchy.path | limit 3
Explanation: Comparing the result of hierarchy_match() to false inverts the match, so every asset that does not live under the Acme Corp/Sandbox container is returned. This is useful for excluding non-production or sandbox scopes from a query.
Output:
| ASSET_ID | CLOUD_PROVIDER | XDM.ASSET.HIERARCHY.PATH |
|---|---|---|
| i-0a1b2c3d | AWS | Acme Corp/Production |
| vm-web-01 | AZURE | Tenant Root Group/Platform |
| gce-inst-01 | GCP | acme.com/Production |
Related articles
- Stages: filter, alter, fields
- Functions: arraycreate(), wildcard_match, coalesce()
- Datasets:
asset_inventory