Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡️ filtered resources: microsoft.users & microsoft.roles #5168

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

afiune
Copy link
Contributor

@afiune afiune commented Feb 5, 2025

When writing policies that require fetching huge amount of data only to search or filter for specific resources, we fetch all resources and then we apply the filters using the builtin functions where() any() and more.

An example of a policy check that uses these patterns is:

// search for emergency accounts
microsoft.users.any(displayName == /emergency/)

// emrgIds holds the ids which match the above criteria
emrgID = microsoft.users.where(displayName == /emergency/).map(id)

// check if at least one of the accounts identified as such is attached to the "Global Administrator" role
microsoft.rolemanagement.roleDefinitions.where(displayName == "Global Administrator").all(assignments.any(principalId == emrgID))

To improve these resources, I am proposing a new pattern, similar to the one used at #5156, but with the difference that it doesn't override builtin functions, instead it leverages list resources which are natively supported in MQL with additional query parameters filter and search.

These query parameters will be used directly when executing API requests against Microsoft Graph API. These query parameters are documented at:

https://learn.microsoft.com/en-us/graph/filter-query-parameter?tabs=http#filter-using-lambda-operators

The above example can be rewritten using these two new filtered resources like:

// search for emergency accounts
microsoft.users(search: "displayName:emergency").any()

// emrgIds holds the ids which match the above criteria
emrgID = microsoft.users(search: "displayName:emergency").map(id)

// check if at least one of the accounts identified as such is attached to the "Global Administrator" role
microsoft.roles(filter: "displayName eq 'Global Administrator'").all(assignments.any(principalId == emrgID))

Additionally, since these query parameters are directly passed to Microsoft API's, we can write very complex filters for these two new resources.

A couple examples are:

microsoft.roles(filter: "isBuiltIn eq true and startswith(displayName, 'Global')")
microsoft.users(filter: "accountEnabled eq true AND userType eq 'Member'", search: "officeLocation:berlin")

Closes #5110

When writing policies that require fetching huge amount of data only to
search or filter for specific resources, we fetch all resources and then
we apply the filters using the builtin functions `where()` `any()` and
more.

An example of a policy check that uses these patterns is:
```
// search for emergency accounts
microsoft.users.any(displayName == /emergency/)

// emrgIds holds the ids which match the above criteria
emrgID = microsoft.users.where(displayName == /emergency/).map(id)

// check if at least one of the accounts identified as such is attached to the "Global Administrator" role
microsoft.rolemanagement.roleDefinitions.where(displayName == "Global Administrator").all(assignments.any(principalId == emrgID))
```

To improve these resources, I am proposing a new pattern, similar to the
one used at #5156, but with the
difference that it doesn't override builtin functions, instead it
leverages list resources which are natively supported in MQL with
additional query parameters `filter` and `search`.

These query parameters will be used directly when executing API requests
against Microsoft Graph API. These query parameters are documented at:

https://learn.microsoft.com/en-us/graph/filter-query-parameter?tabs=http#filter-using-lambda-operators

The above example can be rewritten using these two new filtered
resources like:

```
// search for emergency accounts
microsoft.users(search: "displayName:emergency").any()

// emrgIds holds the ids which match the above criteria
emrgID = microsoft.users(search: "displayName:emergency").map(id)

// check if at least one of the accounts identified as such is attached to the "Global Administrator" role
microsoft.roles(filter: "displayName eq 'Global Administrator'").all(assignments.any(principalId == emrgID))
```

Additionally, since these query parameters are directly passed to
Microsoft API's, we can write very complex filters for these two new
resources.

A couple examples are:
```
microsoft.roles(filter: "isBuiltIn eq true and startswith(displayName, 'Global')")
microsoft.users(filter: "accountEnabled eq true AND userType eq 'Member'", search: "officeLocation:berlin")
```

Closes #5110

Signed-off-by: Salim Afiune Maya <[email protected]>
@afiune afiune requested review from chris-rock and arlimus February 5, 2025 11:50
Copy link
Contributor

github-actions bot commented Feb 5, 2025

Test Results

3 212 tests  ±0   3 208 ✅ ±0   1m 52s ⏱️ +12s
  385 suites ±0       4 💤 ±0 
   29 files   ±0       0 ❌ ±0 

Results for commit f6dc25c. ± Comparison against base commit 3799ad0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

improve slow microsoft query
1 participant