@knowttl/mg-axi 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +251 -77
  2. package/dist/api.js +253 -8
  3. package/dist/bin/mg-axi-hook.js +31 -0
  4. package/dist/catalogue.js +693 -2
  5. package/dist/cli.js +155 -17
  6. package/dist/docs.js +175 -46
  7. package/dist/doctor.js +2 -2
  8. package/dist/entra-access-reviews.js +11 -4
  9. package/dist/entra-apps.js +171 -14
  10. package/dist/entra-audit-logs.js +101 -16
  11. package/dist/entra-auth-methods.js +8 -4
  12. package/dist/entra-certificate-auth.js +12 -8
  13. package/dist/entra-conditional-access.js +425 -15
  14. package/dist/entra-contacts.js +19 -12
  15. package/dist/entra-contracts.js +7 -4
  16. package/dist/entra-custom-security-attributes.js +19 -12
  17. package/dist/entra-data-policy-operations.js +7 -4
  18. package/dist/entra-delegated-admin.js +55 -6
  19. package/dist/entra-deleted-items.js +6 -4
  20. package/dist/entra-directory-objects.js +6 -4
  21. package/dist/entra-directory.js +19 -12
  22. package/dist/entra-domains.js +13 -8
  23. package/dist/entra-entitlement-management.js +12 -4
  24. package/dist/entra-federation-configurations.js +7 -4
  25. package/dist/entra-grants.js +8 -4
  26. package/dist/entra-group-lifecycle.js +13 -8
  27. package/dist/entra-group-pim.js +431 -0
  28. package/dist/entra-groups.js +13 -8
  29. package/dist/entra-identity-providers.js +7 -4
  30. package/dist/entra-lifecycle-workflows.js +152 -13
  31. package/dist/entra-multi-tenant-organization.js +7 -4
  32. package/dist/entra-on-premises-synchronization.js +6 -4
  33. package/dist/entra-organization.js +13 -8
  34. package/dist/entra-risk-prevention.js +442 -0
  35. package/dist/entra-risk.js +224 -9
  36. package/dist/entra-roles.js +204 -12
  37. package/dist/entra-subscriptions.js +6 -4
  38. package/dist/entra-terms-of-use.js +13 -8
  39. package/dist/entra-users.js +7 -4
  40. package/dist/graph-session.js +30 -5
  41. package/dist/hook.js +84 -0
  42. package/dist/list-totals.js +52 -0
  43. package/dist/setup.js +9 -1
  44. package/docs/coverage.md +743 -610
  45. package/inventory/operations.json +2 -2
  46. package/inventory/schema.json +1 -1
  47. package/package.json +4 -3
  48. package/skills/mg-axi/SKILL.md +86 -1
package/README.md CHANGED
@@ -12,12 +12,12 @@ API-01 executes `mg-axi api get <path>`, serving the reviewed v1.0 raw surface t
12
12
  READ-01 executes Entra user list/show through that session in both delegated and application modes; current usage follows below.
13
13
  READ-02 adds group list/show and direct or transitive member and parent-membership reads through the same session.
14
14
  READ-04 adds targeted per-user authentication-method reads and the tenant registration report through the same session, with phone numbers redacted.
15
- READ-09 adds directory-role list/show, current role-assignment inventory and active/eligible PIM reads through the same session.
16
- READ-03 adds Conditional Access policy and named-location list/show as separate grammar through the same session; Conditional Access usage follows the device and administrative-unit usage below.
17
- READ-05 executes Entra sign-in and directory-audit list/show through that session; log usage follows the Conditional Access usage below.
18
- READ-07 adds application and service-principal list/show with credential expiry metadata and owner reads through the same session.
15
+ READ-09 adds directory-role list/show, directory-role-template list/show, directory-role member and scoped-member reads, scoped-role-membership reads, current role-assignment inventory and active/eligible PIM reads through the same session.
16
+ READ-03 adds Conditional Access policy, named-location, authentication-strength-policy, combination-configuration, authentication-method-mode, template, auth-context, deleted-policy and deleted-named-location list/show as separate grammar through the same session; Conditional Access usage follows the device and administrative-unit usage below.
17
+ READ-05 executes Entra sign-in, directory-audit and provisioning-log list/show through that session; log usage follows the Conditional Access usage below.
18
+ READ-07 adds application and service-principal list/show with credential expiry metadata, owner reads, federated-credential reads, and service-principal app-role-assigned-to reads through the same session.
19
19
  READ-10 adds directory-device and administrative-unit list/show and unit-member reads through the same session.
20
- READ-08 adds service-principal delegated-grant and app-role-assignment consent reads for a named client through the same session.
20
+ READ-08 adds service-principal delegated-grant list and app-role-assignment list/show consent reads for a named client through the same session.
21
21
  EXT-01 (domains) adds tenant-domain list/show, per-domain verification and service-configuration DNS record reads, and top-level domain DNS record reads through the same session.
22
22
  EXT-01 (certificate auth) adds PKI configuration and certificate-authority list/show/count reads with default certificate-blob omission through the same session.
23
23
  EXT-01 (directory subscriptions) adds commercial-subscription list/show/count reads with compact licence rows through the same session.
@@ -31,7 +31,8 @@ EXT-01n (contact membership) adds per-contact memberOf and transitiveMemberOf re
31
31
  EXT-03 (identity providers) adds workforce identity-provider list/show/count/available-types reads with secret scrubbing through the same session.
32
32
  EXT-01 (federation configurations) adds workforce directory federation-configuration list/show/count/available-types reads with default signing-certificate omission through the same session.
33
33
  EXT-03 (data policy operations) adds workforce data-policy-operation list/show/count reads with storage-location redaction through the same session.
34
- READ-06 executes Entra risky-user and risk-detection list/show through that session; risk usage follows the log usage below.
34
+ EXT-03 (risk prevention) adds workforce fraud-protection-provider, web-application-firewall-provider and web-application-firewall-verification list/show/count reads plus verification provider show with key-material scrubbing through the same delegated session.
35
+ READ-06 executes Entra risky-user, risk-detection, risky-service-principal (with per-principal history) and service-principal-risk-detection list/show through that session; risk usage follows the log usage below.
35
36
  EXT-01 (organization) adds tenant-organization list/show, default sign-in branding metadata and locale branding reads through the same session.
36
37
  EXT-04 (contracts) adds partner-tenant customer-contract list/show/count through the same session.
37
38
  EXT-04 (delegated-admin) adds partner-tenant delegated-admin customer and relationship list/show through the same session.
@@ -79,7 +80,7 @@ The home view reports unavailable tenant summaries explicitly.
79
80
  Text values longer than 500 characters are truncated, including strings in `businessPhones`; `--full` removes text truncation without lifting redaction or row caps.
80
81
  Explicit null values stay null, missing properties stay absent, and denied reads return structured errors rather than empty results.
81
82
  User lists accept `--filter` for an OData filter and default to a 100-row cap; `--limit` changes the cap, while the incompatible `--all` follows pages within request, byte and deadline budgets.
82
- Partial lists report `count.complete: false`, a reason and an opaque `cursor` preserving unreturned rows.
83
+ Partial lists report `complete: false` with a uniform `count` line (`1 users shown, more available`), a reason and an opaque `cursor` preserving unreturned rows.
83
84
  Resume with `--cursor <cursor-from-output>` using the same profile, authentication scopes and API version; original `--select` and `--filter` values may be repeated or omitted, and conflicting values fail validation.
84
85
  Repeat `--fields` and `--full` when the same local view is wanted; these are not saved in the cursor.
85
86
  Delegated user reads default to `https://graph.microsoft.com/User.Read.All` with `--scopes` available for least-privilege basics; application profiles use the configured Graph `.default` audience and reject delegated scopes.
@@ -150,6 +151,8 @@ mg-axi entra application owner list --profile soc --application <application-obj
150
151
  mg-axi entra service-principal list --profile soc --limit 10
151
152
  mg-axi entra service-principal show --profile soc --id <service-principal-object-id>
152
153
  mg-axi entra service-principal owner list --profile soc --service-principal <service-principal-object-id>
154
+ mg-axi entra application federated-credential list --profile soc --application <application-object-id>
155
+ mg-axi entra service-principal federated-credential list --profile soc --service-principal <service-principal-object-id>
153
156
  ```
154
157
 
155
158
  Read granted consent for one client service principal; delegated profiles first need explicit login with the read scopes:
@@ -158,14 +161,18 @@ Read granted consent for one client service principal; delegated profiles first
158
161
  mg-axi login --profile soc --scopes https://graph.microsoft.com/Directory.Read.All,https://graph.microsoft.com/Application.Read.All
159
162
  mg-axi entra service-principal oauth2-grant list --profile soc --service-principal <service-principal-object-id>
160
163
  mg-axi entra service-principal app-role-assignment list --profile soc --service-principal <service-principal-object-id> --filter "resourceId eq '<resource-id>'"
164
+ mg-axi entra service-principal app-role-assignment show --profile soc --service-principal <service-principal-object-id> --id <assignment-id>
165
+ mg-axi entra service-principal app-role-assigned-to list --profile soc --service-principal <service-principal-object-id>
161
166
  ```
162
167
 
163
168
  `entra service-principal oauth2-grant list` defaults to `id`, `consentType`, `principalId`, `resourceId` and `scope`: the delegated scopes granted to the client, with `consentType` AllPrincipals covering every user (and an explicit null `principalId`) versus Principal covering the one user named by `principalId`.
164
169
  `entra service-principal app-role-assignment list` defaults to `id`, `appRoleId`, `resourceDisplayName` and `resourceId`: the app-only roles granted to the client on each resource API.
165
- Both lists show actual granted consent records; the application's requested permissions (`requiredResourceAccess`) are declared on the application object and are never shown here, and grant creation, revocation and consent belong to later write slices, never to these reads.
170
+ `entra service-principal app-role-assignment show --service-principal <service-principal-object-id> --id <assignment-id>` returns one such grant with the full reviewed app-role set.
171
+ `entra service-principal app-role-assigned-to list` defaults to `id`, `appRoleId`, `principalDisplayName`, `principalId`, `principalType`, `resourceDisplayName` and `resourceId`: the reverse view, principals assigned to one resource service principal; `app-role-assigned-to show` returns one such record with the full reviewed set.
172
+ All these views show actual granted consent records; the application's requested permissions (`requiredResourceAccess`) are declared on the application object and are never shown here, and grant creation, revocation and consent belong to later write slices, never to these reads.
166
173
  `--select` requests properties from the [reviewed grant property sets](src/entra-grants.ts); `--fields` must be a subset of the fetched selection.
167
- `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; the named-list caps, `count`, cursor resume rules and 500-character text truncation described above also apply.
168
- Resume either list with the same `--service-principal` object ID.
174
+ `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; the named-list caps, uniform `count` totals, cursor resume rules and 500-character text truncation described above also apply.
175
+ Resume any of these lists with the same `--service-principal` object ID.
169
176
  Delegated oauth2-grant reads default to `https://graph.microsoft.com/Directory.Read.All` and app-role reads to `https://graph.microsoft.com/Application.Read.All`, while application profiles use the configured `.default` audience; reads never request a write-consent scope such as `DelegatedPermissionGrant.ReadWrite.All`, `Application.ReadWrite.All` or `Directory.ReadWrite.All`.
170
177
  Delegated callers additionally need a supported directory role per operation (for example Directory Readers, Global Reader or Application Administrator).
171
178
  Denied reads name that role and read-scope requirement instead of only the generic grant/role/licence cause.
@@ -186,7 +193,10 @@ Execution reserves a journaled intent before the fresh read and records its outc
186
193
  Relationship rows default to `id` and `displayName`; `--select` accepts only `id`, `displayName` and `mail`, and `--fields` must be a subset of that selection.
187
194
  Returned `@odata.type` stays visible alongside any `--fields` projection.
188
195
  Group lists return `groups`, member lists return `members`, parent-membership lists return `memberOf`, and single-group reads return `group`.
189
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to group and relationship reads.
196
+ Group and relationship lists report uniform totals through the shared list-totals helper: `total` holds the server-supplied `@odata.count` when the query carries `$count` (filtered reads) and `null` otherwise, beside a `count` line such as `3 of 10 groups`, `3 groups` or, when the total is unknown and more pages remain, `3 groups shown, more available`.
197
+ The same helper covers the other wired core-directory lists: users, applications, service principals, owners, devices, administrative units and unit members, contacts, direct reports and memberships, directory roles, directory-role templates, role members, scoped members, scoped role memberships, role assignments and PIM eligible/active assignments, group PIM assignment/eligibility schedules, instances and eligibility requests, directory objects, deleted items, domains and DNS records, contracts, organizations and branding localizations, subscriptions, access-review definitions, instances, decisions, contacted reviewers and stages, sign-ins and directory audits, authentication methods and registration reports, PKI configurations and certificate authorities, Conditional Access policies, named locations, authentication-strength policies, combination configurations, authentication method modes, templates, authentication contexts, deleted policies and deleted named locations, attribute sets, custom-security-attribute definitions and allowed values, data-policy operations, delegated-admin customers, relationships and navigation lists, entitlement catalogs, access packages, assignment policies, resource-role scopes, assignments and assignment requests, federation configurations, oauth2 grants, app-role assignments and app-role-assigned-to, federated credentials, group lifecycle policies and setting templates, identity providers, lifecycle workflows, workflow templates, task definitions, runs, processing results and task reports, multi-tenant-organization tenants, on-premises synchronizations, risky users, risk detections, risky service principals and their history and detections, fraud-protection, web-application-firewall and verification providers, and agreements and acceptances. Every entra list command now reports through the same helper; only the dedicated `count` and `available-types` commands keep their `count` aggregates.
198
+ `complete` names pagination state, with `reason` and an opaque `cursor` on partial reads.
199
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to group and relationship reads.
190
200
  Resume relationships with the same `--group` and direct or `--transitive` command, profile, scopes and API version; omit or repeat the original server query flags, and repeat local `--fields` and `--full` when wanted.
191
201
  Help warns that hidden members are omitted without `Member.Read.Hidden`; completion describes pagination, not visibility.
192
202
  Rows without non-null selected descriptive properties are preserved and reported as possibly limited by consent or unset properties; null properties stay null.
@@ -195,12 +205,19 @@ Direct member results always carry the [v1.0 service-principal limitation](docs/
195
205
  Delegated group reads default to `https://graph.microsoft.com/GroupMember.Read.All`; hidden members need `Member.Read.Hidden` and richer group properties may need `Group.Read.All`, while application profiles use the configured `.default` audience.
196
206
  When richer group access is needed, pass `--scopes https://graph.microsoft.com/Group.Read.All`; for hidden-member access, explicitly log in and read with `--scopes https://graph.microsoft.com/GroupMember.Read.All,https://graph.microsoft.com/Member.Read.Hidden` and satisfy the operation's delegated role requirements.
197
207
 
198
- Read directory roles, current assignments and PIM activity through four views; delegated profiles first need explicit login with the read scopes:
208
+ Read directory roles, templates, members, scoped memberships, current assignments and PIM activity through twelve views; delegated profiles first need explicit login with the read scopes:
199
209
 
200
210
  ```sh
201
211
  mg-axi login --profile soc --scopes https://graph.microsoft.com/RoleManagement.Read.Directory,https://graph.microsoft.com/RoleEligibilitySchedule.Read.Directory,https://graph.microsoft.com/RoleAssignmentSchedule.Read.Directory
202
212
  mg-axi entra directory-role list --profile soc --limit 10
203
213
  mg-axi entra directory-role show --profile soc --id <role-id>
214
+ mg-axi entra directory-role-template list --profile soc
215
+ mg-axi entra directory-role-template show --profile soc --id <template-id>
216
+ mg-axi entra directory-role member list --profile soc --role <role-id>
217
+ mg-axi entra directory-role scoped-member list --profile soc --role <role-id>
218
+ mg-axi entra directory-role scoped-member show --profile soc --role <role-id> --id <scoped-membership-id>
219
+ mg-axi entra scoped-role-membership list --profile soc
220
+ mg-axi entra scoped-role-membership show --profile soc --id <scoped-membership-id>
204
221
  mg-axi entra role-assignment list --profile soc --filter "principalId eq '<principal-id>'"
205
222
  mg-axi entra pim eligible list --profile soc
206
223
  mg-axi entra pim active list --profile soc --filter "assignmentType eq 'Activated'"
@@ -208,19 +225,52 @@ mg-axi entra pim active list --profile soc --filter "assignmentType eq 'Activate
208
225
 
209
226
  `entra directory-role list` defaults to `id`, `displayName`, `description` and `roleTemplateId`; `entra directory-role show --id <role-id>` defaults to the full reviewed role set.
210
227
  Directory roles are activated instances only: a role appears after activation, never before, so an empty result never proves the role does not exist.
228
+ `entra directory-role-template list` and `show` default to `id`, `displayName` and `description`; templates describe every role definition whether or not the role is activated.
229
+ `entra directory-role member list --role <role-id>` defaults to `id` and `displayName` and carries each member kind in `@odata.type` (user, group, device or service principal); request `mail` or `userPrincipalName` with `--select` for richer member rows.
230
+ `entra directory-role scoped-member list` and `show` and `entra scoped-role-membership list` and `show` default to `id`, `principalId`, `roleId` and `directoryScopeId` with the full reviewed set (`administrativeUnitId` included) on show; administrative-unit scopes need P1.
211
231
  `entra role-assignment list` defaults to `id`, `principalId`, `roleDefinitionId` and `directoryScopeId` and returns the current assignment inventory, including direct and PIM-activated assignments.
212
232
  Use `entra pim active list` to classify those assignments as described below.
213
233
  `entra pim eligible list` defaults to `id`, `principalId`, `roleDefinitionId` and `memberType`; it covers PIM-eligible assignments, which are not active, and eligible instances carry no `assignmentType`.
214
234
  `entra pim active list` defaults to those properties plus `assignmentType` and covers both directly assigned (`assignmentType` Assigned) and activated eligible (`assignmentType` Activated) assignments; `memberType` names how the instance reaches the principal.
215
235
  For built-in roles the unified `roleDefinitionId` matches the directory-role `roleTemplateId`.
216
236
  `--select` requests properties from the [reviewed role property sets](src/entra-roles.ts); `--fields` must be a subset of the fetched selection.
217
- `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; the named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply.
218
- Delegated directory-role and role-assignment reads default to `https://graph.microsoft.com/RoleManagement.Read.Directory`; eligible PIM reads default to `https://graph.microsoft.com/RoleEligibilitySchedule.Read.Directory` and active PIM reads to `https://graph.microsoft.com/RoleAssignmentSchedule.Read.Directory`, while application profiles use the configured `.default` audience.
237
+ `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; the named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply.
238
+ Delegated directory-role, template, member, scoped-member, scoped-membership and role-assignment reads default to `https://graph.microsoft.com/RoleManagement.Read.Directory`; eligible PIM reads default to `https://graph.microsoft.com/RoleEligibilitySchedule.Read.Directory` and active PIM reads to `https://graph.microsoft.com/RoleAssignmentSchedule.Read.Directory`, while application profiles use the configured `.default` audience.
219
239
  Delegated callers additionally need a supported directory role per operation (for example Privileged Role Administrator, Global Reader or Security Reader for role reads, Directory Readers for assignments, Security Operator for PIM reads).
220
240
  Denied reads name that role requirement instead of only the generic grant/role/licence cause.
221
- Built-in roles are base inventory and custom role assignments need P1; PIM reads need P2 or ID Governance.
241
+ Built-in roles are base inventory and custom role assignments need P1; administrative-unit-scoped memberships need P1; PIM reads need P2 or ID Governance.
222
242
  Role assignment, activation and every other PIM mutation belongs to later write slices, never to these reads.
223
243
 
244
+ Read PIM-for-Groups assignment and eligibility through ten views; delegated profiles first need explicit login with the read scopes:
245
+
246
+ ```sh
247
+ mg-axi login --profile soc --scopes https://graph.microsoft.com/PrivilegedAssignmentSchedule.Read.AzureADGroup,https://graph.microsoft.com/PrivilegedEligibilitySchedule.Read.AzureADGroup
248
+ mg-axi entra pim group-assignment-schedule list --profile soc --filter "groupId eq '<group-id>'"
249
+ mg-axi entra pim group-assignment-schedule show --profile soc --id <assignment-schedule-id>
250
+ mg-axi entra pim group-assignment-instance list --profile soc --filter "principalId eq '<principal-id>'"
251
+ mg-axi entra pim group-assignment-instance show --profile soc --id <assignment-instance-id>
252
+ mg-axi entra pim group-eligibility-schedule list --profile soc --filter "groupId eq '<group-id>'"
253
+ mg-axi entra pim group-eligibility-schedule show --profile soc --id <eligibility-schedule-id>
254
+ mg-axi entra pim group-eligibility-instance list --profile soc --filter "groupId eq '<group-id>'"
255
+ mg-axi entra pim group-eligibility-instance show --profile soc --id <eligibility-instance-id>
256
+ mg-axi entra pim group-eligibility-request list --profile soc --filter "groupId eq '<group-id>'"
257
+ mg-axi entra pim group-eligibility-request show --profile soc --id <eligibility-request-id>
258
+ ```
259
+
260
+ Assignment schedules govern group membership or ownership over time and instances are the provisioned windows, never the schedule itself.
261
+ Eligibility schedules govern who may activate and are not active grants, while eligibility instances are the provisioned eligibility windows and requests carry the ask plus its outcome.
262
+ Every list requires `--filter` with an `eq` clause on `groupId` or `principalId` scoping the list to one group or principal, and the requirement fails validation before credentials.
263
+ Assignment schedule and instance lists default to `id`, `principalId`, `groupId`, `accessId` and `assignmentType`; eligibility schedule and instance lists default to `id`, `principalId`, `groupId`, `accessId` and `memberType`; eligibility-request lists default to `id`, `action`, `status`, `principalId`, `groupId` and `accessId`.
264
+ Every show defaults to its full reviewed property set, except eligibility-request show omits `justification` unless an explicit `--select` names it.
265
+ `--select` requests properties from the [reviewed group PIM property sets](src/entra-group-pim.ts); `--fields` must be a subset of the fetched selection.
266
+ `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; these collections document no `$count`, so the uniform `count` totals name the returned rows with a `null` total unless a page carries a server total.
267
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply; resume a list with the same `--filter`, profile, scopes and API version.
268
+ Delegated assignment reads default to `https://graph.microsoft.com/PrivilegedAssignmentSchedule.Read.AzureADGroup` and eligibility reads to `https://graph.microsoft.com/PrivilegedEligibilitySchedule.Read.AzureADGroup`, while application profiles use the configured `.default` audience and reject `--scopes`.
269
+ Delegated callers additionally need owner or member of the group or a supported directory role scoped at directory level (Global Reader or Privileged Role Administrator for role-assignable groups; otherwise Global Reader, Directory Writer, Groups Administrator, Identity Governance Administrator or User Administrator).
270
+ Denied reads name that scope, role and licensing requirement instead of only the generic grant/role/licence cause.
271
+ PIM for Groups needs P2 or ID Governance, and delegated personal Microsoft accounts are not supported.
272
+ Assignment requests, approvals, `filterByCurrentUser` functions, group/principal navigation, resources, every count/ref/cast tail, beta and all mutations stay out; assignment requests stay out because their least privilege is the write scope `PrivilegedAssignmentSchedule.ReadWrite.AzureADGroup`.
273
+
224
274
  Read access reviews through ten views; delegated profiles first need explicit login with the read scope:
225
275
 
226
276
  ```sh
@@ -250,7 +300,7 @@ Contacted-reviewer and stage `show` commands take `--definition`, `--instance` a
250
300
  Decision reads are read-only: listing never approves, denies or applies anything, and submitting or stopping a review belongs to a later slice, never to these reads.
251
301
  `--select` requests properties from the [reviewed access-review property sets](src/entra-access-reviews.ts); `--fields` must be a subset of the fetched selection.
252
302
  `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; on definitions only `contains()` over the scope query and `eq` on status are documented, on stages only `eq` is documented.
253
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to access-review reads.
303
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to access-review reads.
254
304
  Resume any access-review list with `--cursor -` and supply the returned cursor on stdin, for example `mg-axi entra access-review definition list --profile soc --cursor - < cursor.txt`; small cursors can also use `--cursor <token>`.
255
305
  Resume instance, decision, contacted-reviewer and stage lists with the same `--definition` (and `--instance`), profile, scopes and API version; a cursor from another definition or instance fails validation instead of returning foreign rows.
256
306
  To replay a resumed result with `--full`, supply the original input cursor on stdin; the returned cursor continues after that result.
@@ -286,10 +336,10 @@ Access packages are the assignable bundles: `entra entitlement access-package li
286
336
  Approval and subject reads carry personal data and belong to later parts, never to these reads; questions, custom-extension stages and the linked role/scope detail need `$expand` and belong to later slices.
287
337
  `--select` requests properties from the [reviewed entitlement property sets](src/entra-entitlement-management.ts); `--fields` must be a subset of the fetched selection.
288
338
  `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract.
289
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to entitlement reads.
339
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to entitlement reads.
290
340
  Resume any entitlement list with `--cursor -` and supply the returned cursor on stdin; resume policy and role-scope lists with the same `--access-package`, profile, scopes and API version.
291
341
  Delegated reads default to `https://graph.microsoft.com/EntitlementManagement.Read.All`, while application profiles use the configured `.default` audience.
292
- See the [entitlement-management scope decisions](docs/coverage.md#ext-02-entitlement-management-scope-decisions) for the scheduled personal-data part and deferred beta reads.
342
+ See the [entitlement-management scope decisions](docs/coverage.md#ext-02-entitlement-management-scope-decisions) for the deferred personal-data part and scheduled beta reads.
293
343
  Delegated callers additionally need a supported Entra role with catalog visibility (Global Reader and Identity Governance Administrator are among the supported roles).
294
344
  Denied reads name that role requirement instead of only the generic grant/role/licence cause.
295
345
  Entitlement management needs P2 or ID Governance depending on capability, not one uniform licence, and delegated personal Microsoft accounts are not supported.
@@ -358,26 +408,46 @@ mg-axi entra lifecycle task-report task show --workflow <workflow-id> --report <
358
408
  mg-axi entra lifecycle task-report task-definition show --workflow <workflow-id> --report <report-id> --profile soc
359
409
  ```
360
410
 
411
+ Read one run's user, subject and task processing results through nine views; run-nested reads share the reports scope:
412
+
413
+ ```sh
414
+ mg-axi entra lifecycle run user-processing-result list --workflow <workflow-id> --run <run-id> --profile soc --limit 10
415
+ mg-axi entra lifecycle run user-processing-result list --workflow <workflow-id> --run <run-id> --profile soc --filter "processingStatus eq 'completed'"
416
+ mg-axi entra lifecycle run user-processing-result show --workflow <workflow-id> --run <run-id> --profile soc --id <result-id>
417
+ mg-axi entra lifecycle run user-processing-result count --workflow <workflow-id> --run <run-id> --profile soc
418
+ mg-axi entra lifecycle run subject-processing-result list --workflow <workflow-id> --run <run-id> --profile soc --limit 10
419
+ mg-axi entra lifecycle run subject-processing-result show --workflow <workflow-id> --run <run-id> --profile soc --id <result-id>
420
+ mg-axi entra lifecycle run subject-processing-result count --workflow <workflow-id> --run <run-id> --profile soc
421
+ mg-axi entra lifecycle run task-processing-result list --workflow <workflow-id> --run <run-id> --profile soc --limit 10
422
+ mg-axi entra lifecycle run task-processing-result show --workflow <workflow-id> --run <run-id> --profile soc --id <result-id>
423
+ mg-axi entra lifecycle run task-processing-result count --workflow <workflow-id> --run <run-id> --profile soc
424
+ ```
425
+
426
+ `entra lifecycle run task-processing-result list` defaults to `id`, `processingStatus` and `failureReason`, and `entra lifecycle run task-processing-result show` defaults to the full reviewed scalar set including failure detail; task rows never carry subject, task or workflowSubject detail.
427
+ Run user results share the top-level user query contract (`--select` reviewed, `--filter` plain), while run subject rows always arrive whole like their top-level counterparts (Graph documents no `$select` on the list and `$expand` only on the get) and the run task single has no operation-level page, so both arrive whole and `--fields` projects them locally; `--select` is refused before credentials.
428
+ User, subject and task processing results are personal data: user and subject rows default to status and counts only (subject rows add `subjectType`), and the subject link is never requested.
429
+ Third-level processing results, reprocessed runs, subject and task sub-reads and the time-windowed summary functions belong to later slices.
430
+
361
431
  `entra lifecycle task-report list` defaults to `id`, `runId`, `processingStatus`, `totalUsersCount`, `failedUsersCount` and `successfulUsersCount`, and `entra lifecycle task-report show` defaults to the full reviewed scalar set; report rows never carry task, task-definition or processing-result detail.
362
432
  The task-report get and the taskReport-nested task and taskDefinition singles document no query parameters, so those rows always arrive whole and `--fields` projects them locally; `--select` is refused before credentials.
363
- Run-nested and third-level processing results, reprocessed runs, subject sub-reads and the time-windowed summary functions belong to later slices.
433
+ Third-level processing results, reprocessed runs, subject sub-reads and the time-windowed summary functions belong to later slices.
364
434
 
365
435
  `entra lifecycle run list` defaults to `id`, `processingStatus`, `totalUsersCount`, `failedUsersCount` and `successfulUsersCount`, and `entra lifecycle run show` defaults to the full reviewed scalar set; run rows never carry processing results.
366
436
  User and subject processing results are personal data: lists and singles default to status and counts only (subject lists add `subjectType`), and the subject link is never requested.
367
437
  The subject list documents `$filter` but not `$select` and the subject get documents `$expand` only, so subject rows always arrive whole and `--fields` projects them locally; `--select` is refused before credentials.
368
- Run-nested and third-level processing results, taskProcessingResults sub-reads, reprocessed runs, subject sub-reads and the time-windowed summary functions belong to later slices.
438
+ Third-level processing results, taskProcessingResults sub-reads under a user or subject result, reprocessed runs, subject sub-reads and the time-windowed summary functions belong to later slices.
369
439
 
370
440
  `entra lifecycle workflow list` defaults to `id`, `displayName`, `category`, `isEnabled` and `isSchedulingEnabled`, and `entra lifecycle workflow show --id <workflow-id>` defaults to the full reviewed scalar set.
371
- Workflow rows never carry tasks, runs, processing results or task reports: tasks ride expanded by default on the get and are dropped in local projection, and run-nested processing results and summaries belong to later parts, never to these reads.
441
+ Workflow rows never carry tasks, runs, processing results or task reports: tasks ride expanded by default on the get and are dropped in local projection, and third-level processing results and summaries belong to later parts, never to these reads.
372
442
  `entra lifecycle workflow-template list` defaults to `id`, `displayName` and `category`; the template get documents no query parameters, so `entra lifecycle workflow-template show --id <template-id>` takes no `--select` and always returns whole rows.
373
443
  `entra lifecycle task-definition list` defaults to `id`, `displayName`, `category` and `version`, and `entra lifecycle task-definition show --id <task-definition-id>` defaults to the full reviewed parameter set.
374
444
  `entra lifecycle settings show` returns the tenant schedule interval with the email and quarantine configuration; updating settings belongs to no read slice.
375
445
  `--select` requests properties from the [reviewed lifecycle property sets](src/entra-lifecycle-workflows.ts); `--fields` must be a subset of the fetched selection, and navigation names (`tasks`, `createdBy`, `lastModifiedBy`, `previewScope`) fail as unknown properties.
376
446
  `--filter` passes through as plain `$filter` with no `$count` or `ConsistencyLevel` contract; `$search`, `$orderby` and `$expand` stay unreviewed.
377
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to lifecycle reads.
447
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to lifecycle reads.
378
448
  Resume any lifecycle list with `--cursor -` and supply the returned cursor on stdin.
379
449
  Delegated workflow reads default to `https://graph.microsoft.com/LifecycleWorkflows-Workflow.ReadBasic.All` (richer detail may need `LifecycleWorkflows-Workflow.Read.All` or `LifecycleWorkflows.Read.All`), template, task-definition and settings reads to `https://graph.microsoft.com/LifecycleWorkflows.Read.All`, and run, processing-result and task-report reads to `https://graph.microsoft.com/LifecycleWorkflows-Reports.Read.All` (richer detail may need `LifecycleWorkflows.Read.All` or `LifecycleWorkflows.ReadWrite.All`), while application profiles use the configured `.default` audience.
380
- See the [lifecycle-workflows scope decisions](docs/coverage.md#ext-02-lifecycle-workflows-scope-decisions) for the scheduled nested-result and summary parts.
450
+ See the [lifecycle-workflows scope decisions](docs/coverage.md#ext-02-lifecycle-workflows-scope-decisions) for the deferred nested-result and summary parts.
381
451
  Delegated callers additionally need Global Reader or Lifecycle Workflows Administrator.
382
452
  Denied reads name that scope, role and licensing requirement instead of only the generic grant/role/licence cause.
383
453
  Lifecycle workflows need Microsoft Entra ID Governance or Microsoft Entra Suite (every governed user, not only administrators), and delegated personal Microsoft accounts are not supported.
@@ -402,7 +472,7 @@ Unit show adds a licensing hint when the projected `membershipType` is `Dynamic`
402
472
  See the [licence matrix](docs/graph-coverage.md#licence-matrix-by-area) for device and administrative-unit licensing requirements.
403
473
  `entra administrative-unit member list --administrative-unit <administrative-unit-id>` lists member users, groups and devices with the same `id`/`displayName`/`mail` selection, `@odata.type` preservation, hidden-membership and limited-information behavior as group relationships.
404
474
  Device and unit lists return `devices` and `administrativeUnits`, member lists return `members`, and single-object reads return `device` and `administrativeUnit`.
405
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to device and administrative-unit reads.
475
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to device and administrative-unit reads.
406
476
  Resume unit-member lists with the same `--administrative-unit`, profile, scopes and API version; omit or repeat the original server query flags, and repeat local `--fields` and `--full` when wanted.
407
477
  Delegated device reads default to `https://graph.microsoft.com/Device.Read.All` and unit reads to `https://graph.microsoft.com/AdministrativeUnit.Read.All`, while application profiles use the configured `.default` audience; hidden unit memberships need `Member.Read.Hidden`.
408
478
  Denied directory reads return operation-specific permission, delegated-role and licensing guidance rather than empty results; HTTP 403 alone does not identify which prerequisite is missing.
@@ -431,7 +501,7 @@ A branding 404 may indicate unconfigured branding, a missing locale, or a missin
431
501
  Delegated callers additionally need a supported Entra role (Directory Readers or Global Reader for organizations; Global Reader or Organizational Branding Administrator for branding); personal Microsoft accounts are not supported.
432
502
  Organization and localization lists return `organizations` and `brandingLocalizations`, single-object reads return `organization`, `branding` and `brandingLocalization`.
433
503
  Localization lists default to `id`, `signInPageText`, `usernameHintText` and `backgroundColor`; branding and localization show commands default to the full reviewed non-Stream field set.
434
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to organization and branding reads.
504
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to organization and branding reads.
435
505
  All five named reads default to `--api-version v1.0`; explicit `--api-version beta` requires a preview-enabled profile, with no automatic fallback.
436
506
  Organization and localization lists offer no `--filter`: Graph documents `$select` only on these routes, so the flag is refused before credentials.
437
507
  Denied organization and branding reads name the scope, role and licensing guidance instead of only the generic cause.
@@ -462,7 +532,7 @@ Lifecycle-policy lists accept `--filter` as plain `$filter` without adding `$cou
462
532
  Each `count` returns one scalar (`groupLifecyclePolicyCount`, `groupSettingTemplateCount`) from its text/plain `$count` route and takes no `--filter`, `--select`, `--limit` or `--cursor`.
463
533
  Raw `api get` supports `/groupLifecyclePolicies`, `/groupLifecyclePolicies/<policy-id>`, `/groupSettingTemplates` and `/groupSettingTemplates/<template-id>`; the `$count` routes are available only through the named count commands.
464
534
  Lifecycle-policy lists return `groupLifecyclePolicies`, single-policy reads return `groupLifecyclePolicy`, template lists return `groupSettingTemplates` and single-template reads return `groupSettingTemplate`.
465
- The named-list caps, `count`, cursors and null/missing preservation described above also apply to these reads.
535
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to these reads.
466
536
  Named reads truncate top-level strings and strings in string arrays at 500 characters with a `--full` recovery hint; nested objects in template `values` pass through without text truncation.
467
537
  All six named reads support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
468
538
  Delegated lifecycle-policy reads default to `https://graph.microsoft.com/Directory.Read.All` and delegated template reads default to `https://graph.microsoft.com/GroupSettings.Read.All`, while application profiles use the configured `.default` audience.
@@ -492,7 +562,7 @@ Allowed-value lists and shows take `--definition <definition-id>`; definition li
492
562
  Each `count` returns `count: { returned: <total>, complete: true }` from its text/plain `$count` route; only the definition count accepts `--filter` to narrow the total server-side, and no count takes `--select`, `--limit` or `--cursor`.
493
563
  Raw `api get` supports `/directory/attributeSets`, `/directory/attributeSets/<set-id>`, `/directory/customSecurityAttributeDefinitions`, `/directory/customSecurityAttributeDefinitions/<definition-id>`, `/directory/customSecurityAttributeDefinitions/<definition-id>/allowedValues` and the single allowed-value route; the `$count` routes are available only through the named count commands.
494
564
  Attribute-set lists return `attributeSets` and single-set reads return `attributeSet`; definition lists return `customSecurityAttributeDefinitions` and single-definition reads return `customSecurityAttributeDefinition`; allowed-value lists return `allowedValues` and single-value reads return `allowedValue`.
495
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to these reads.
565
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to these reads.
496
566
  All nine named reads support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
497
567
  Delegated reads default to `https://graph.microsoft.com/CustomSecAttributeDefinition.Read.All`, while application profiles use the configured `.default` audience.
498
568
  Delegated callers additionally need a custom-security-attribute role even for Global Administrators (Attribute Definition Reader or Attribute Definition Administrator work for every read; some reads also accept Attribute Assignment Reader or Attribute Assignment Administrator); personal Microsoft accounts are not supported.
@@ -515,7 +585,7 @@ Contract lists accept `--filter` as plain `$filter` without adding `$count=true`
515
585
  `entra contract count` returns one scalar (`contractCount`) from the text/plain `$count` route and takes no `--filter`, `--select`, `--limit` or `--cursor`.
516
586
  Raw `api get` supports `/contracts` and `/contracts/<contract-id>`; `/contracts/$count` is available only through the named count command.
517
587
  Contract lists return `contracts` and single-contract reads return `contract`.
518
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to contract reads.
588
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to contract reads.
519
589
  All three named reads support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
520
590
  Delegated contract reads default to `https://graph.microsoft.com/Directory.Read.All`, while application profiles use the configured `.default` audience.
521
591
  Delegated callers additionally need a supported Entra role (Directory Readers is the least-privileged role); personal Microsoft accounts are not supported.
@@ -538,21 +608,28 @@ mg-axi entra delegated-admin-relationship list-requests --profile soc --id <rela
538
608
  mg-axi entra delegated-admin-relationship show-request --profile soc --id <relationship-id> --request-id <request-id>
539
609
  mg-axi entra delegated-admin-customer list-service-management-details --profile soc --id <customer-id>
540
610
  mg-axi entra delegated-admin-customer show-service-management-detail --profile soc --id <customer-id> --detail-id <detail-id>
611
+ mg-axi entra delegated-admin-customer count --profile soc
612
+ mg-axi entra delegated-admin-customer count-service-management-details --profile soc --id <customer-id>
613
+ mg-axi entra delegated-admin-relationship count --profile soc
614
+ mg-axi entra delegated-admin-relationship count-access-assignments --profile soc --id <relationship-id>
615
+ mg-axi entra delegated-admin-relationship count-operations --profile soc --id <relationship-id>
616
+ mg-axi entra delegated-admin-relationship count-requests --profile soc --id <relationship-id>
541
617
  ```
542
618
 
543
619
  Delegated-admin reads run in the partner tenant; customer objects are created by the system when a relationship exists and deleted when none remain, so a non-partner tenant lists zero customers, which is an answer rather than an error.
544
620
  `entra delegated-admin-customer list` defaults to compact properties (`id`, `displayName`, `tenantId`); `entra delegated-admin-relationship list` defaults to (`id`, `displayName`, `status`, `customer`, `endDateTime`); both top-level show commands default to the full reviewed property set.
545
621
  `--select` requests properties from the reviewed delegated-admin field sets; `--fields` projects locally and must be a subset of the fetched selection.
546
622
  Both top-level lists accept `--filter` as plain `$filter` without adding `$count=true` or `ConsistencyLevel`.
547
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to delegated-admin reads.
623
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to delegated-admin reads.
548
624
  The access-assignment, operation and request navigation lists bind their parent relationship through `--id` and take `--assignment-id`, `--operation-id` and `--request-id` on their shows; the service-management-detail reads bind their parent customer through `--id` and take `--detail-id` on the show.
549
625
  The navigation lists default to compact properties (`id`, `status`, `accessContainer`, `accessDetails` for assignments; `id`, `operationType`, `status`, `lastModifiedDateTime` for operations; `id`, `action`, `status`, `lastModifiedDateTime` for requests) while the service-management-detail reads always carry (`id`, `serviceName`, `serviceManagementUrl`); every show defaults to its full reviewed property set.
550
626
  The access-assignment, operation and request lists accept `--filter` as plain `$filter` without adding `$count=true` or `ConsistencyLevel`; Graph documents no query parameters for service-management details, so those two reads take no `--select` or `--filter` and project `--fields` locally.
551
- All twelve named reads support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
627
+ Each `count` returns one scalar (`delegatedAdminCustomerCount`, `delegatedAdminServiceManagementDetailCount`, `delegatedAdminRelationshipCount`, `delegatedAdminAccessAssignmentCount`, `delegatedAdminRelationshipOperationCount`, `delegatedAdminRelationshipRequestCount`) from its text/plain `$count` route and takes no `--filter`, `--select`, `--limit` or `--cursor`.
628
+ All eighteen named reads support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
552
629
  Delegated delegated-admin reads default to `https://graph.microsoft.com/DelegatedAdminRelationship.Read.All`, while application profiles use the configured `.default` audience.
553
630
  Personal Microsoft accounts are not supported.
554
631
  No P1/P2 prerequisite is stated for delegated-admin reads; denied reads name the scope, partner-tenant and licensing guidance instead of only the generic cause.
555
- No delegated-admin mutation lives here; the `$count` scalars and the container root belong to later pieces, while the multi-tenant-organization reads shipped in the next section and tenant-lookup functions ship as `entra tenant-information show` in the tenant-information usage below; see the [delegated-admin scope decisions](docs/coverage.md#ext-04-delegated-admin-scope-decisions) for deferred reads and later subfamilies.
632
+ No delegated-admin mutation lives here; the container root belongs to a later piece, while the multi-tenant-organization reads shipped in the next section and tenant-lookup functions ship as `entra tenant-information show` in the tenant-information usage below; see the [delegated-admin scope decisions](docs/coverage.md#ext-04-delegated-admin-scope-decisions) for deferred reads and later subfamilies.
556
633
 
557
634
  Log in with `https://graph.microsoft.com/MultiTenantOrganization.Read.All`, then inspect the tenant multitenant organization:
558
635
 
@@ -568,12 +645,12 @@ At most one multitenant organization exists per tenant; a tenant outside any mul
568
645
  `entra multi-tenant-organization tenant list` defaults to compact properties (`tenantId`, `displayName`, `role`, `state`); both show commands default to the full reviewed property set.
569
646
  `--select` requests properties from the reviewed multi-tenant-organization field sets; `--fields` projects locally and must be a subset of the fetched selection.
570
647
  The tenant list accepts `--filter` as plain `$filter` without adding `$count=true` or `ConsistencyLevel`.
571
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to multi-tenant-organization reads.
648
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to multi-tenant-organization reads.
572
649
  All four named reads support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
573
650
  Delegated multi-tenant-organization reads default to `https://graph.microsoft.com/MultiTenantOrganization.Read.All` (the lower-privileged delegated `MultiTenantOrganization.ReadBasic.All` returns displayName and tenantId only) and additionally need Security Reader or Global Reader, while application profiles use the configured `.default` audience.
574
651
  Personal Microsoft accounts are not supported, and these reads run in the commercial Global service only.
575
652
  Multi-tenant-organization participation needs Entra ID P1; denied reads name the scope, roles and licensing guidance instead of only the generic cause.
576
- No multi-tenant-organization mutation lives here; the single-member read stays scheduled because its documented least privilege is the write scope `MultiTenantOrganization.ReadWrite.All`, and tenant-lookup functions ship as `entra tenant-information show` in the tenant-information usage below; see the [multi-tenant-organization scope decisions](docs/coverage.md#ext-04-multi-tenant-organization-scope-decisions) for the deferred read.
653
+ No multi-tenant-organization mutation lives here; the single-member read stays deferred because its documented least privilege is the write scope `MultiTenantOrganization.ReadWrite.All`, and tenant-lookup functions ship as `entra tenant-information show` in the tenant-information usage below; see the [multi-tenant-organization scope decisions](docs/coverage.md#ext-04-multi-tenant-organization-scope-decisions) for the deferred read.
577
654
 
578
655
  Log in with `https://graph.microsoft.com/CrossTenantInformation.ReadBasic.All`, then look up tenant information by domain name or tenant ID:
579
656
 
@@ -615,7 +692,7 @@ DNS record lists accept `--filter` as plain `$filter`, without adding `$count=tr
615
692
  Record rows carry `@odata.type` naming the derived record kind; derived-type detail (`mailExchange`, `preference`, `canonicalName`, SRV fields, `text`) needs an explicit `--select` naming the derived property.
616
693
  Domain and record `--select` accept their [reviewed property sets](src/entra-domains.ts); `--fields` must be a subset of the fetched selection.
617
694
  Domain lists return `domains` and single-domain reads return `domain`; record lists return `verificationDnsRecords`, `serviceConfigurationRecords` and `domainDnsRecords`, with single-record reads returning the singular key.
618
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to domain and DNS record reads.
695
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to domain and DNS record reads.
619
696
  Resume record lists with the same `--domain` where applicable, profile, scopes and API version; omit or repeat the original server query flags, and repeat local `--fields` and `--full` when wanted.
620
697
  Delegated domain and DNS record reads default to `https://graph.microsoft.com/Domain.Read.All`, while application profiles use the configured `.default` audience.
621
698
  Delegated callers additionally need a supported Entra role (Domain Name Administrator or Global Reader are least-privileged); personal Microsoft accounts are not supported.
@@ -642,7 +719,7 @@ Authority show commands also take `--pki <pki-id>` and require `--id <authority-
642
719
  Authority entries carry public certificates only, but the base64 `certificate` blob (up to 8 KB per CA file) is omitted from every default select and needs an explicit `--select certificate`; explicitly selected blobs still truncate at 500 characters unless `--full` is passed.
643
720
  PKI lists return `certificateAuthPkis` and single-PKI reads return `certificateAuthPki`; authority lists return `certificateAuthorities` with single-authority reads returning `certificateAuthority`.
644
721
  Count commands return `count: { returned: <total>, complete: true }` and accept no `--select`, `--fields`, `--limit` or `--cursor`.
645
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to certificate-auth reads.
722
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to certificate-auth reads.
646
723
  Delegated certificate-auth reads default to `https://graph.microsoft.com/PublicKeyInfrastructure.Read.All`, while application profiles use the configured `.default` audience.
647
724
  Delegated callers additionally need Privileged Authentication Administrator or Authentication Administrator; personal Microsoft accounts are not supported.
648
725
  No P1/P2 prerequisite is stated for certificate-auth reads; denied reads name the scope, role and licensing guidance instead of only the generic cause.
@@ -663,7 +740,7 @@ All three subscription commands support only `--api-version v1.0`; `--api-versio
663
740
  Subscription lists accept `--filter` as plain `$filter`, without adding `$count=true` or `ConsistencyLevel`; the show command documents `$select` only and the count command takes no `--filter`, `--select`, `--limit` or `--cursor`.
664
741
  `entra subscription show --id <subscription-id>` defaults to the full reviewed companySubscription set; `entra subscription show --commerce-subscription-id <commerce-subscription-id>` serves the same object through the commerce-system alternate key, binding it only through the allowlisted session function-argument contract (validated, OData-quoted, encoded).
665
742
  Subscription lists return `subscriptions` and single-subscription reads return `subscription`; count commands return `count: { returned: <total>, complete: true }`.
666
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to subscription reads.
743
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to subscription reads.
667
744
  Delegated subscription reads default to `https://graph.microsoft.com/Organization.Read.All`, while application profiles use the configured `.default` audience.
668
745
  Delegated callers additionally need Global Reader, Directory Readers, or Dynamics 365 Business Central Administrator for read-only standard properties; personal Microsoft accounts are not supported.
669
746
  No P1/P2 prerequisite is stated for subscription reads; denied reads name the scope, role and licensing guidance instead of only the generic cause.
@@ -681,11 +758,11 @@ mg-axi entra on-premises-synchronization show --profile soc --id <synchronizatio
681
758
  Both commands support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
682
759
  Neither leaf offers `--filter`: Graph documents `$select` only here, so strict input validation refuses the flag before credentials.
683
760
  Synchronization lists return `synchronizations` and single reads return `synchronization`; secret-shaped values inside `configuration` and `features` stay redacted by the shared session.
684
- The named-list caps, cursors, null/missing preservation and 500-character text truncation described above also apply to on-premises-synchronization reads.
761
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to on-premises-synchronization reads.
685
762
  Delegated reads default to `https://graph.microsoft.com/OnPremDirectorySynchronization.Read.All`; application profiles are refused before credentials because Graph documents no supported application permission for this operation.
686
763
  Delegated callers additionally need Global Administrator, the only supported Entra role for this operation; personal Microsoft accounts are not supported.
687
764
  No P1/P2 prerequisite is stated for on-premises-synchronization reads; denied reads name the scope, role and licensing guidance instead of only the generic cause.
688
- No on-premises-synchronization mutation lives here; the `$count` scalar and beta operations stay scheduled; see the [on-premises-synchronization scope decisions](docs/coverage.md#ext-01-on-premises-synchronization-scope-decisions).
765
+ No on-premises-synchronization mutation lives here; the `$count` scalar stays deferred and beta operations stay scheduled; see the [on-premises-synchronization scope decisions](docs/coverage.md#ext-01-on-premises-synchronization-scope-decisions).
689
766
 
690
767
  Log in with `https://graph.microsoft.com/Agreement.Read.All`, then inspect terms-of-use agreements (delegated profiles only):
691
768
 
@@ -709,12 +786,12 @@ mg-axi entra agreement-acceptance show --id <acceptance-id> --profile soc
709
786
 
710
787
  Acceptance lists return `agreementAcceptances` and single reads return `agreementAcceptance`; default rows stay minimal (`id`, `agreementId`, `state`, `recordedDateTime`) because acceptance records are personal data, and identifying fields need an explicit `--select` naming them.
711
788
  All six commands support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
712
- The named-list caps, cursors, null/missing preservation and 500-character text truncation described above also apply to terms-of-use reads.
789
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to terms-of-use reads.
713
790
  Delegated agreement reads default to `https://graph.microsoft.com/Agreement.Read.All` and delegated acceptance reads default to `https://graph.microsoft.com/AgreementAcceptance.Read` (`AgreementAcceptance.Read.All` is the documented higher-privileged alternative); application profiles are refused before credentials because Graph documents no supported application permission for these operations.
714
791
  Delegated callers additionally need Security Reader, the least-privileged supported Entra role for these operations; personal Microsoft accounts are not supported.
715
792
  Terms of use needs Microsoft Entra ID P1; denied reads name the scope, role and licensing guidance instead of only the generic cause.
716
793
  Agreement file contents are never downloaded or printed; only agreement metadata is projected.
717
- No terms-of-use mutation lives here; the acceptances `$count` scalar, the agreement file/localization sub-reads and beta operations stay scheduled; see the [terms-of-use scope decisions](docs/coverage.md#ext-01-terms-of-use-scope-decisions).
794
+ No terms-of-use mutation lives here; the acceptances `$count` scalar and the agreement file/localization sub-reads stay deferred and beta operations stay scheduled; see the [terms-of-use scope decisions](docs/coverage.md#ext-01-terms-of-use-scope-decisions).
718
795
 
719
796
  Log in with `https://graph.microsoft.com/Directory.Read.All`, then inspect directory objects:
720
797
 
@@ -730,10 +807,10 @@ All three commands support only `--api-version v1.0`; `--api-version beta` fails
730
807
  Neither list nor show offers `--filter`: Graph documents no List operation page for the collection, so strict input validation refuses the flag before credentials.
731
808
  Lists return `directoryObjects`, single reads return `directoryObject`, and counts return `count` with the scalar total.
732
809
  Rows are polymorphic: only the base-type properties are ever requested or projected (`$expand` is not offered), the discriminator rides along automatically without being selectable, and subtype secrets or credentials can never appear; subtype detail needs the subtype's named reads.
733
- The named-list caps, cursors, null/missing preservation and 500-character text truncation described above also apply to directory-object reads.
810
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to directory-object reads.
734
811
  Reads default to `https://graph.microsoft.com/Directory.Read.All` for delegated access, while application profiles use the configured `.default` audience.
735
812
  No delegated role or P1/P2 prerequisite is stated for directory-object reads; personal Microsoft accounts are not supported, and denied reads name the scope, role and licensing guidance instead of only the generic cause.
736
- No directory-object mutation lives here; the delta sync, the POST lookup/validation actions and beta operations stay scheduled; see the [directory-objects scope decisions](docs/coverage.md#ext-01-directory-objects-scope-decisions).
813
+ No directory-object mutation lives here; the delta sync and the POST lookup/validation actions stay deferred and beta operations stay scheduled; see the [directory-objects scope decisions](docs/coverage.md#ext-01-directory-objects-scope-decisions).
737
814
 
738
815
  Log in with the scope matching the deleted type (`User.Read.All`, `Group.Read.All`, `Application.Read.All` or `AdministrativeUnit.Read.All`), then inspect the directory recycle bin:
739
816
 
@@ -754,10 +831,10 @@ Upstream requires the OData cast as part of the list URI, so untyped list/count
754
831
  Rows are polymorphic: only the reviewed per-type properties are ever requested or projected, the discriminator rides along automatically without being selectable, and credential collections (`keyCredentials`, `passwordCredentials`) are never selectable, so secret values can never appear.
755
832
  `appId` (client ID) is distinct from the object `id` on applications and service principals.
756
833
  Soft-deleted security groups report `securityEnabled` false through a known upstream limitation; read `groupTypes` to name the real kind.
757
- The named-list caps, cursors, null/missing preservation and 500-character text truncation described above also apply to deleted-item reads.
834
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to deleted-item reads.
758
835
  List and count reads default to the type's least-privileged scope for delegated access (`User.Read.All`, `Group.Read.All`, `Application.Read.All` or `AdministrativeUnit.Read.All`, all read scopes already allowlisted), while application profiles use the configured `.default` audience.
759
836
  No delegated role or P1/P2 prerequisite is stated for deleted-item reads; personal Microsoft accounts are not supported, and denied reads name the scope, role and licensing guidance instead of only the generic cause.
760
- No deleted-item mutation lives here; restore and permanent delete stay out entirely, and the POST lookup/validation actions and beta operations stay scheduled; see the [deleted-items scope decisions](docs/coverage.md#ext-01-deleted-items-scope-decisions).
837
+ No deleted-item mutation lives here; restore and permanent delete stay out entirely, and the POST lookup/validation actions stay deferred and beta operations stay scheduled; see the [deleted-items scope decisions](docs/coverage.md#ext-01-deleted-items-scope-decisions).
761
838
  Log in with `https://graph.microsoft.com/OrgContact.Read.All`, then inspect organizational contacts:
762
839
 
763
840
  ```sh
@@ -781,10 +858,10 @@ All ten contact commands support only `--api-version v1.0`; `--api-version beta`
781
858
  Direct-report reads take `$select` only; `$filter`, `$search` and `$top` stay unreviewed there.
782
859
  Top-level `list` returns `contacts` and `show` returns `contact`; `show-manager` returns `manager`, `list-direct-reports` returns `directReports` and `show-direct-report` returns `directReport`, `list-member-of` returns `memberOf` and `show-member-of` returns `memberOf`, and counts return `count` with the scalar total; each count sends `ConsistencyLevel eventual` like the documented `$count` example.
783
860
  Top-level list and show request and project only flat scalar properties (`$expand` is not offered, so navigation objects never appear there); navigation reads return directory objects through their own routes, and the nested phones/addresses collections need their own projection review.
784
- The named-list caps, cursors, null/missing preservation and 500-character text truncation described above also apply to contact reads.
861
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to contact reads.
785
862
  Reads default to `https://graph.microsoft.com/OrgContact.Read.All` for delegated access, while application profiles use the configured `.default` audience; transitive member-of reads additionally need `https://graph.microsoft.com/Group.Read.All`.
786
863
  Delegated callers additionally need a supported Entra role (Directory Readers reads basic properties; Global Reader, Directory Writers, Intune Administrator or User Administrator also work); personal Microsoft accounts are not supported, and denied reads name the scope, role and licensing guidance instead of only the generic cause.
787
- No contact mutation lives here; the delta sync, the POST lookup actions and beta operations stay scheduled, and the error/sync navigation reads stay unavailable with no documented permission contract; see the [contacts scope decisions](docs/coverage.md#ext-01-contacts-scope-decisions).
864
+ No contact mutation lives here; the delta sync and the POST lookup actions stay deferred and beta operations stay scheduled, and the error/sync navigation reads stay unavailable with no documented permission contract; see the [contacts scope decisions](docs/coverage.md#ext-01-contacts-scope-decisions).
788
865
 
789
866
  Log in with `https://graph.microsoft.com/IdentityProvider.Read.All`, then read workforce identity providers:
790
867
 
@@ -806,7 +883,7 @@ Provider lists accept `--filter` as plain `$filter`; counts accept `--filter` to
806
883
  Rows carry `@odata.type` naming the provider kind (social or built-in).
807
884
  The reviewed workforce fields are `id`, `displayName`, `identityProviderType`, and `clientId`.
808
885
  `clientSecret` and `certificateData` are never selectable and any row carrying them is scrubbed before output, so key material can never reach stdout, errors or logs.
809
- Provider lists use the named-list caps, `count` aggregate and cursors described above.
886
+ Provider lists use the named-list caps, uniform `count` totals and cursors described above.
810
887
  List and show preserve null/missing properties and truncate text longer than 500 characters; `--full` restores complete text without lifting redaction or row caps.
811
888
  Delegated provider reads default to `https://graph.microsoft.com/IdentityProvider.Read.All`, while application profiles use the configured `.default` audience.
812
889
  Delegated callers additionally need a directory role that can read federation configuration (Global Reader is the least-privileged read-only directory role); personal Microsoft accounts are not supported.
@@ -831,7 +908,7 @@ Configuration lists return `federationConfigurations`, single-configuration read
831
908
  `signingCertificate` carries the public token-signing key only and is omitted from every default select; request it explicitly when rotation evidence is needed. No private key material exists on these resources.
832
909
  Configuration lists accept `--filter` as plain `$filter`; counts accept `--filter` to narrow the total server-side.
833
910
  Rows carry `@odata.type` naming the configuration kind.
834
- Configuration lists use the named-list caps, `count` aggregate and cursors described above.
911
+ Configuration lists use the named-list caps, uniform `count` totals and cursors described above.
835
912
  List and show preserve null/missing properties and truncate text longer than 500 characters; `--full` restores complete text without lifting row caps.
836
913
  Delegated callers additionally need External Identity Provider Administrator, the least-privileged supported Entra role for these reads; personal Microsoft accounts are not supported.
837
914
  No per-operation licence prerequisite is stated for these reads; denied reads name the scope, role and licensing guidance instead of only the generic cause.
@@ -852,14 +929,46 @@ List and show accept `--select` from the [reviewed operation property set](src/e
852
929
  The list documents `$select` only, so no `--filter`; the `$count` route takes no `--filter`, `--select`, `--limit` or `--cursor`.
853
930
  Operation lists return `dataPolicyOperations`, single-operation reads return `dataPolicyOperation`, and counts return `count` with the scalar total.
854
931
  `storageLocation` always renders as `***redacted***`: export blob URLs and signed links never reach output, errors or logs.
855
- Operation lists use the named-list caps, `count` aggregate and cursors described above.
932
+ Operation lists use the named-list caps, uniform `count` totals and cursors described above.
856
933
  List and show preserve null/missing properties and truncate text longer than 500 characters; `--full` restores complete text without lifting redaction or row caps.
857
934
  Delegated operation reads default to `https://graph.microsoft.com/User.Export.All,https://graph.microsoft.com/User.Read.All`, while application profiles use the configured `.default` audience.
858
935
  Delegated callers additionally need Company Administrator, the privileged role documented for export reads; personal Microsoft accounts are not supported.
859
936
  No P1/P2 prerequisite is stated for these reads; denied reads name the scopes, role and licensing guidance instead of only the generic cause.
860
937
  No export submission lives here; the `$count` scalar aside, beta operations stay scheduled (see the [data-policy-operations scope decisions](docs/coverage.md#ext-03-data-policy-operations-scope-decisions)).
861
938
 
862
- Log in with `https://graph.microsoft.com/Policy.Read.All`, then read Conditional Access policies and named locations as separate grammar:
939
+ Log in with `https://graph.microsoft.com/RiskPreventionProviders.Read.All`, then read workforce risk-prevention providers and verifications (delegated profiles only):
940
+
941
+ ```sh
942
+ mg-axi login --profile soc --scopes https://graph.microsoft.com/RiskPreventionProviders.Read.All
943
+ mg-axi entra fraud-protection-provider list --profile soc
944
+ mg-axi entra fraud-protection-provider show --profile soc --id <provider-id>
945
+ mg-axi entra fraud-protection-provider count --profile soc
946
+ mg-axi entra web-application-firewall-provider list --profile soc
947
+ mg-axi entra web-application-firewall-provider show --profile soc --id <provider-id>
948
+ mg-axi entra web-application-firewall-provider count --profile soc
949
+ mg-axi entra web-application-firewall-verification list --profile soc
950
+ mg-axi entra web-application-firewall-verification show --profile soc --id <verification-id>
951
+ mg-axi entra web-application-firewall-verification count --profile soc
952
+ mg-axi entra web-application-firewall-verification provider show --profile soc --id <verification-id>
953
+ ```
954
+
955
+ `entra fraud-protection-provider list` and `entra web-application-firewall-provider list` default to compact properties (`id`, `displayName`); `entra web-application-firewall-verification list` defaults to (`id`, `verifiedHost`, `providerType`); every `show` defaults to its full reviewed set.
956
+ All ten risk-prevention commands support only `--api-version v1.0`; `--api-version beta` fails validation before credentials, including on preview-enabled profiles.
957
+ List and show accept `--select` from the [reviewed risk-prevention property sets](src/entra-risk-prevention.ts); `--fields` must be a subset of the fetched selection.
958
+ The fraud list documents `$select` only, so no `--filter`; the WAF and verification lists accept `--filter` as plain `$filter`; every `$count` route takes no `--filter`, `--select`, `--limit` or `--cursor`.
959
+ Fraud lists return `fraudProtectionProviders`, WAF lists return `webApplicationFirewallProviders`, verification lists return `webApplicationFirewallVerifications`; single reads return `fraudProtectionProvider`, `webApplicationFirewallProvider` or `webApplicationFirewallVerification`; counts return `count` with the scalar total.
960
+ Verification rows never carry provider detail; `provider show --id <verification-id>` returns the owning `webApplicationFirewallProvider`.
961
+ Fraud and WAF rows carry `@odata.type` naming the provider kind (Arkose or HUMAN; Akamai or Cloudflare).
962
+ The reviewed fraud fields are `id`, `displayName`, `clientSubDomain`, `verifySubDomain` and `appId`; the reviewed WAF fields are `id`, `displayName`, `hostPrefix` and `zoneId`; the reviewed verification fields are `id`, `verifiedHost`, `providerType`, `verificationResult` and `verifiedDetails`.
963
+ Arkose `privateKey`/`publicKey`, HUMAN `serverToken`, Akamai `clientSecret`/`clientToken`/`accessToken` and Cloudflare `apiToken` are never selectable and any row carrying them is scrubbed before output, so key material can never reach stdout, errors or logs.
964
+ Risk-prevention lists use the named-list caps, uniform `count` totals and cursors described above.
965
+ List and show preserve null/missing properties and truncate text longer than 500 characters; `--full` restores complete text without lifting redaction or row caps.
966
+ Delegated risk-prevention reads default to `https://graph.microsoft.com/RiskPreventionProviders.Read.All`; Graph documents no supported application permission, so application profiles are refused before credentials.
967
+ Delegated callers additionally need a directory role that can read risk-prevention configuration (Security Reader is the least-privileged read-only role); personal Microsoft accounts are not supported.
968
+ No per-operation licence prerequisite is stated for these reads; denied reads name the scope, role and licensing guidance instead of only the generic cause.
969
+ No provider create/update/delete and no verification submission live here; beta operations stay scheduled (see the [risk-prevention scope decisions](docs/coverage.md#ext-03-risk-prevention-scope-decisions)).
970
+
971
+ Log in with `https://graph.microsoft.com/Policy.Read.All`, then read Conditional Access policies, named locations and templates as separate grammar:
863
972
 
864
973
  ```sh
865
974
  mg-axi login --profile soc --scopes https://graph.microsoft.com/Policy.Read.All
@@ -868,21 +977,59 @@ mg-axi entra conditional-access policy list --profile soc --filter "state eq 'en
868
977
  mg-axi entra conditional-access policy show --profile soc --id <policy-id>
869
978
  mg-axi entra conditional-access named-location list --profile soc
870
979
  mg-axi entra conditional-access named-location show --profile soc --id <named-location-id>
980
+ mg-axi entra conditional-access template list --profile soc --limit 10
981
+ mg-axi entra conditional-access template show --profile soc --id <template-id>
982
+ mg-axi entra conditional-access deleted-policy list --profile soc --limit 10
983
+ mg-axi entra conditional-access deleted-policy show --profile soc --id <deleted-policy-id>
984
+ mg-axi entra conditional-access deleted-named-location list --profile soc
985
+ mg-axi entra conditional-access deleted-named-location show --profile soc --id <deleted-named-location-id>
986
+ ```
987
+
988
+ Log in with `https://graph.microsoft.com/AuthenticationContext.Read.All`, then read authentication context class references through the same session:
989
+
990
+ ```sh
991
+ mg-axi login --profile soc --scopes https://graph.microsoft.com/AuthenticationContext.Read.All
992
+ mg-axi entra conditional-access auth-context list --profile soc --limit 10
993
+ mg-axi entra conditional-access auth-context show --profile soc --id <auth-context-id>
994
+ ```
995
+
996
+ Log in with `https://graph.microsoft.com/Policy.Read.AuthenticationMethod`, then read the authentication-strength family through the same session:
997
+
998
+ ```sh
999
+ mg-axi login --profile soc --scopes https://graph.microsoft.com/Policy.Read.AuthenticationMethod
1000
+ mg-axi entra conditional-access auth-strength-policy list --profile soc --limit 10
1001
+ mg-axi entra conditional-access auth-strength-policy show --profile soc --id <auth-strength-policy-id>
1002
+ mg-axi entra conditional-access combination-configuration list --policy <auth-strength-policy-id> --profile soc
1003
+ mg-axi entra conditional-access combination-configuration show --policy <auth-strength-policy-id> --id <combination-configuration-id> --profile soc
1004
+ mg-axi entra conditional-access auth-method-mode list --profile soc --limit 10
1005
+ mg-axi entra conditional-access auth-method-mode show --profile soc --id <auth-method-mode-id>
871
1006
  ```
872
1007
 
873
1008
  `entra conditional-access policy list` defaults to compact properties (`id`, `displayName`, `state`); `policy show --id <policy-id>` defaults to the full reviewed condition and control property set.
874
1009
  `entra conditional-access named-location list` defaults to `id` and `displayName`; `named-location show --id <named-location-id>` defaults to the full reviewed location set.
875
- Policy `--select` accepts the [reviewed policy property set](src/entra-conditional-access.ts) and location `--select` accepts the [reviewed location property set](src/entra-conditional-access.ts); `--fields` must be a subset of the fetched selection in each family.
1010
+ `entra conditional-access auth-strength-policy list` defaults to compact properties (`id`, `displayName`, `policyType`); `auth-strength-policy show --id <auth-strength-policy-id>` defaults to the full reviewed strength set.
1011
+ `entra conditional-access combination-configuration list --policy <auth-strength-policy-id>` defaults to `id`; `combination-configuration show` takes `--policy` plus `--id` and defaults to the full reviewed base set.
1012
+ `entra conditional-access auth-method-mode list` defaults to `id` and `displayName`; `auth-method-mode show --id <auth-method-mode-id>` defaults to the full reviewed mode set.
1013
+ `entra conditional-access template list` defaults to `id` and `name`; `template show --id <template-id>` defaults to the full reviewed template set.
1014
+ `entra conditional-access auth-context list` defaults to `id` and `displayName`; `auth-context show --id <auth-context-id>` defaults to the full reviewed authentication-context set.
1015
+ `entra conditional-access deleted-policy list` defaults to compact properties (`id`, `displayName`, `state`, `deletedDateTime`); `deleted-policy show --id <deleted-policy-id>` defaults to the full reviewed deleted-policy set. Deleted-policy reads never restore; restore is a beta-only mutation outside mg-axi scope.
1016
+ `entra conditional-access deleted-named-location list` defaults to `id`, `displayName` and `deletedDateTime`; `deleted-named-location show --id <deleted-named-location-id>` defaults to the full reviewed deleted-location set. Deleted named-location reads never restore; restore is a beta-only mutation outside mg-axi scope.
1017
+ Policy `--select` accepts the [reviewed policy property set](src/entra-conditional-access.ts) and location `--select` accepts the [reviewed location property set](src/entra-conditional-access.ts); strength, combination-configuration, method-mode, template, authentication-context, deleted-policy and deleted-named-location `--select` accept their own [reviewed property sets](src/entra-conditional-access.ts); `--fields` must be a subset of the fetched selection in each family.
876
1018
  Returned `@odata.type` stays visible on named-location rows so IP and country locations stay distinguishable alongside any `--fields` projection.
1019
+ Returned `@odata.type` also stays visible on combination-configuration rows so configuration kinds stay distinguishable alongside any `--fields` projection.
1020
+ Returned `@odata.type` also stays visible on deleted-named-location rows so IP and country locations stay distinguishable alongside any `--fields` projection.
877
1021
  Policy lists return `policies`, location lists return `namedLocations`, single-policy reads return `policy` and single-location reads return `namedLocation`.
878
- Successful empty collections return an empty list with `count.returned: 0`, `count.complete: true` and absence guidance.
879
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply to Conditional Access reads, including nested condition values; every truncated value carries a `--full` hint.
880
- Resume either Conditional Access list with `--cursor -` and supply the returned cursor on stdin, for example `mg-axi entra conditional-access policy list --profile soc --cursor - < cursor.txt`.
1022
+ Strength lists return `authStrengthPolicies`, combination lists return `combinationConfigurations`, mode lists return `authMethodModes`, template lists return `templates`, authentication-context lists return `authContexts`, deleted-policy lists return `deletedPolicies` and deleted-named-location lists return `deletedNamedLocations`; single reads return `authStrengthPolicy`, `combinationConfiguration`, `authMethodMode`, `template`, `authContext`, `deletedPolicy` and `deletedNamedLocation`.
1023
+ Successful empty collections return an empty list with a uniform `count` line (`0 policies` or `0 named locations`, `total: null`) and absence guidance.
1024
+ The authentication-strength, combination-configuration, authentication-method-mode, template, authentication-context, deleted-policy and deleted-named-location lists report uniform totals through the shared list-totals helper beside a `count` line such as `2 auth-strength policies` or `2 templates` (`0 ...` with absence guidance on empty results).
1025
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply to Conditional Access reads, including nested condition values; every truncated value carries a `--full` hint.
1026
+ Resume any Conditional Access list with `--cursor -` and supply the returned cursor on stdin, for example `mg-axi entra conditional-access policy list --profile soc --cursor - < cursor.txt`.
1027
+ Resume combination-configuration lists with the same `--policy`, profile, scopes and API version.
881
1028
  Small cursors can also use `--cursor <token>`; both forms enforce a 16 MB size ceiling.
882
1029
  Use `--full` when reasoning from complete condition or control text; `--select` and `--fields` still determine which properties are visible, and missing properties remain unknown.
883
1030
  To replay a resumed result with `--full`, reuse the original input cursor; the returned cursor continues after that result.
884
- Delegated policy and location reads default to `https://graph.microsoft.com/Policy.Read.All`; application profiles require admin-consented `Policy.Read.All`, use the configured Graph `.default` audience and reject `--scopes`.
885
- HTTP 403 policy and location errors name the operation's supported directory roles (Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access) and include guidance from the [licensing contract](docs/graph-coverage.md#licence-matrix-by-area); the response alone does not identify the missing prerequisite.
1031
+ Delegated policy, named-location, template, deleted-policy and deleted-named-location reads default to `https://graph.microsoft.com/Policy.Read.All`; delegated authentication-strength-policy, combination-configuration and authentication-method-mode reads default to `https://graph.microsoft.com/Policy.Read.AuthenticationMethod`; delegated authentication-context reads default to `https://graph.microsoft.com/AuthenticationContext.Read.All`; application profiles require the admin-consented scope for the family, use the configured Graph `.default` audience and reject `--scopes`.
1032
+ HTTP 403 policy, location, template, deleted-policy and deleted-named-location errors name the operation's supported directory roles (Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access); HTTP 403 authentication-context errors name the same broad role set with `AuthenticationContext.Read.All`; HTTP 403 authentication-strength errors name the narrower role set (Conditional Access Administrator, Security Administrator or Security Reader) with `Policy.Read.AuthenticationMethod`; all include guidance from the [licensing contract](docs/graph-coverage.md#licence-matrix-by-area), and Conditional Access reads need P1; the response alone does not identify the missing prerequisite.
886
1033
  WRITE-04 adds a named write: `mg-axi entra conditional-access policy update --id <policy-id>` PATCHes one policy with only the reviewed fields `--display-name`, `--state`, `--conditions`, `--grant-controls` and `--session-controls` (JSON objects for the last three); any other property has no flag and is refused before credentials.
887
1034
  At least one reviewed field flag is required.
888
1035
  The command supports only `--api-version v1.0`; `--state` accepts `enabled`, `enabledForReportingButNotEnforced` or `disabled`, and each JSON flag supplies the full corresponding block.
@@ -923,13 +1070,13 @@ Method registration and deletion belong to no read slice and are never construct
923
1070
  For methods, `--select` selects output properties locally from the [reviewed authentication property sets](src/entra-auth-methods.ts); no `$select` is sent to Graph.
924
1071
  For the registration report, `--select` requests server properties; `--fields` must be a subset of the default or explicit selection for either command.
925
1072
  Only the registration report supports `--filter`, passed through as plain `$filter` with no `$count` or `ConsistencyLevel` contract.
926
- The named-list caps, `count`, cursors, null/missing preservation and 500-character text truncation described above also apply.
1073
+ The named-list caps, uniform `count` totals, cursors, null/missing preservation and 500-character text truncation described above also apply.
927
1074
  Resume method lists with the same `--user` ID or UPN, profile, scopes and API version; omit or repeat the original `--select`, and repeat local `--fields` and `--full` when wanted.
928
1075
  Delegated method reads default to `https://graph.microsoft.com/UserAuthenticationMethod.Read.All` (delegated self-reads may use `UserAuthenticationMethod.Read`) and registration reads default to `https://graph.microsoft.com/AuditLog.Read.All`, while application profiles use the configured `.default` audience.
929
1076
  Delegated callers acting on another user additionally need Global Reader, Authentication Administrator or Privileged Authentication Administrator for methods, and Reports Reader, Security Reader, Security Administrator or Global Reader for the report.
930
1077
  Denied reads name that role requirement instead of only the generic grant/role/licence cause.
931
1078
 
932
- Log in with `https://graph.microsoft.com/AuditLog.Read.All`, then query sign-ins and directory audits in bounded time windows:
1079
+ Log in with `https://graph.microsoft.com/AuditLog.Read.All`, then query sign-ins, directory audits and provisioning logs in bounded time windows (provisioning needs the extra scope below):
933
1080
 
934
1081
  ```sh
935
1082
  mg-axi login --profile soc --scopes https://graph.microsoft.com/AuditLog.Read.All
@@ -938,14 +1085,22 @@ mg-axi entra sign-in list --profile soc --since 2026-09-01T00:00:00Z --filter "s
938
1085
  mg-axi entra sign-in show --profile soc --id <sign-in-id>
939
1086
  mg-axi entra directory-audit list --profile soc --since 2026-09-01T00:00:00Z
940
1087
  mg-axi entra directory-audit show --profile soc --id <directory-audit-id>
1088
+ mg-axi entra provisioning list --profile soc --since 2026-09-01T00:00:00Z
1089
+ mg-axi entra provisioning show --profile soc --id <provisioning-id>
1090
+ ```
1091
+
1092
+ Provisioning logs additionally need `https://graph.microsoft.com/Directory.Read.All` alongside `AuditLog.Read.All`, plus a Microsoft Entra ID P1 or P2 licence on the tenant:
1093
+
1094
+ ```sh
1095
+ mg-axi login --profile soc --scopes https://graph.microsoft.com/AuditLog.Read.All,https://graph.microsoft.com/Directory.Read.All
941
1096
  ```
942
1097
 
943
1098
  Log lists always carry an explicit time bound: `--since` is required for a new query (with optional `--until` and `--filter` refinements), and resume reuses `--cursor` instead.
944
1099
  Resume validates the saved time bounds; a cursor from an unbounded raw query is rejected, so start a new query with `--since`.
945
- Resume sign-in and directory-audit lists with `--cursor -` and supply the returned cursor on stdin, for example `mg-axi entra sign-in list --profile soc --cursor - < cursor.txt`.
1100
+ Resume sign-in, directory-audit and provisioning lists with `--cursor -` and supply the returned cursor on stdin, for example `mg-axi entra sign-in list --profile soc --cursor - < cursor.txt`.
946
1101
  Small cursors can also use `--cursor <token>`; both forms enforce a 16 MB size ceiling.
947
- `entra sign-in list` defaults to `id`, `createdDateTime`, `userPrincipalName` and `appDisplayName`; `entra directory-audit list` defaults to `id`, `activityDateTime`, `activityDisplayName` and `result`.
948
- Both log show commands default to the full reviewed property set.
1102
+ `entra sign-in list` defaults to `id`, `createdDateTime`, `userPrincipalName` and `appDisplayName`; `entra directory-audit list` defaults to `id`, `activityDateTime`, `activityDisplayName` and `result`; `entra provisioning list` defaults to `id`, `activityDateTime`, `action` and `provisioningStatusInfo`.
1103
+ All three log show commands default to the full reviewed property set.
949
1104
  `--select` requests properties from the [supported log property sets](src/entra-audit-logs.ts); `--fields` projects locally and must be a subset of the fetched selection.
950
1105
  Log reads truncate text longer than 500 characters, including nested values; `--full` restores complete text without lifting redaction, row caps or time bounds.
951
1106
  To replay a resumed result with `--full`, supply the original input cursor on stdin; the returned cursor continues after that result.
@@ -961,35 +1116,46 @@ Credential collections expose only expiry metadata (`keyId`, `displayName`, `sta
961
1116
  Non-array credential collections become empty arrays, and non-object entries are dropped; other properties retain the null/missing behavior described above.
962
1117
  Secret-minting routes are never constructed.
963
1118
  `entra application owner list --application <application-object-id>` and `entra service-principal owner list --service-principal <service-principal-object-id>` list owners; rows carry `@odata.type` naming the owner kind.
1119
+ `entra application federated-credential list` and `entra service-principal federated-credential list` default to `id`, `name`, `issuer` and `subject`: workload-identity trust metadata only, never secret material; each `show` defaults to the full reviewed set (`id`, `name`, `issuer`, `subject`, `description`, `audiences`).
1120
+ There is no named command for the parenthesised `(appId='...')` or `(name='...')` lookups; filter the list instead. Those rows stay deferred (see the [READ-07 scope decisions](docs/coverage.md#read-07-application-lookups-scope-decisions)).
964
1121
  For consent grants, use the service-principal grant commands described above.
965
- Application lists return `applications`, service-principal lists return `servicePrincipals`, owner lists return `owners`, and single-object reads return `application` or `servicePrincipal`.
1122
+ Application lists return `applications`, service-principal lists return `servicePrincipals`, owner lists return `owners`, federated lists return `federatedCredentials`, and single-object reads return `application`, `servicePrincipal` or `federatedCredential`.
966
1123
  App and service-principal `--select` accepts the [reviewed property sets](src/entra-apps.ts); `--fields` must be a subset of the fetched selection.
967
1124
  Owner rows default to `id`, `displayName` and `mail`, the only selectable owner properties; rows without non-null descriptive properties are preserved with a hint about limited consent or unset properties.
968
- The named-list caps, `count`, cursor resume rules and 500-character text truncation described above also apply to these reads; resume owner lists with the same `--application` or `--service-principal` object ID.
969
- Delegated application reads default to `https://graph.microsoft.com/Application.Read.All`, while application profiles use the configured `.default` audience.
1125
+ The named-list caps, uniform `count` totals, cursor resume rules and 500-character text truncation described above also apply to these reads; resume owner lists with the same `--application` or `--service-principal` object ID.
1126
+ Delegated application reads, including federated-credential reads, default to `https://graph.microsoft.com/Application.Read.All`, while application profiles use the configured `.default` audience.
970
1127
 
971
- Log in with `https://graph.microsoft.com/IdentityRiskyUser.Read.All` and `https://graph.microsoft.com/IdentityRiskEvent.Read.All`, then triage risky users and risk detections:
1128
+ Log in with `https://graph.microsoft.com/IdentityRiskyUser.Read.All`, `https://graph.microsoft.com/IdentityRiskEvent.Read.All` and `https://graph.microsoft.com/IdentityRiskyServicePrincipal.Read.All`, then triage risky users, risk detections, risky service principals and service-principal risk detections:
972
1129
 
973
1130
  ```sh
974
- mg-axi login --profile soc --scopes https://graph.microsoft.com/IdentityRiskyUser.Read.All,https://graph.microsoft.com/IdentityRiskEvent.Read.All
1131
+ mg-axi login --profile soc --scopes https://graph.microsoft.com/IdentityRiskyUser.Read.All,https://graph.microsoft.com/IdentityRiskEvent.Read.All,https://graph.microsoft.com/IdentityRiskyServicePrincipal.Read.All
975
1132
  mg-axi entra risky-user list --profile soc --limit 10
976
1133
  mg-axi entra risky-user show --profile soc --id <risky-user-id>
977
1134
  mg-axi entra risk-detection list --profile soc --since 2026-09-01T00:00:00Z --limit 10
978
1135
  mg-axi entra risk-detection show --profile soc --id <risk-detection-id>
1136
+ mg-axi entra risky-service-principal list --profile soc --limit 10
1137
+ mg-axi entra risky-service-principal show --profile soc --id <risky-service-principal-id>
1138
+ mg-axi entra risky-service-principal history list --profile soc --service-principal <risky-service-principal-id>
1139
+ mg-axi entra risky-service-principal history show --profile soc --service-principal <risky-service-principal-id> --id <history-item-id>
1140
+ mg-axi entra service-principal-risk-detection list --profile soc --since 2026-09-01T00:00:00Z --limit 10
1141
+ mg-axi entra service-principal-risk-detection show --profile soc --id <service-principal-risk-detection-id>
979
1142
  ```
980
1143
 
981
- Delegated risky-user reads default to `https://graph.microsoft.com/IdentityRiskyUser.Read.All`; risk-detection reads default to `https://graph.microsoft.com/IdentityRiskEvent.Read.All`.
1144
+ Delegated risky-user reads default to `https://graph.microsoft.com/IdentityRiskyUser.Read.All`; user and service-principal risk-detection reads default to `https://graph.microsoft.com/IdentityRiskEvent.Read.All`; risky-service-principal and history reads default to `https://graph.microsoft.com/IdentityRiskyServicePrincipal.Read.All`.
982
1145
  `--scopes` overrides those defaults; application profiles use the configured Graph `.default` audience and reject delegated scopes.
983
- `entra risky-user list` is a state collection with an optional `--filter`; `entra risk-detection list` always carries an explicit time bound, so `--since` is required for a new query (with optional `--until` and `--filter` refinements) and resume reuses `--cursor` instead.
1146
+ `entra risky-user list` and `entra risky-service-principal list` are state collections with an optional `--filter`; `entra risk-detection list` and `entra service-principal-risk-detection list` always carry an explicit time bound, so `--since` is required for a new query (with optional `--until` and `--filter` refinements) and resume reuses `--cursor` instead.
1147
+ `entra risky-service-principal history list` and `history show` always carry `--service-principal` naming the owning risky-service-principal object ID.
984
1148
  Resume validates the saved detectedDateTime bounds; a cursor from an unbounded raw query is rejected, so start a new query with `--since`.
985
1149
  Resume risk lists with `--cursor -` and supply the returned cursor on stdin, for example `mg-axi entra risk-detection list --profile soc --cursor - < cursor.txt`.
986
1150
  `entra risky-user list` defaults to `id`, `userPrincipalName`, `riskLevel` and `riskState`; `entra risk-detection list` defaults to `id`, `detectedDateTime`, `userPrincipalName` and `riskLevel`.
987
- Both risk show commands default to the full reviewed property set.
1151
+ `entra risky-service-principal list` and `history list` default to `id`, `displayName`, `riskLevel` and `riskState`; `entra service-principal-risk-detection list` defaults to `id`, `detectedDateTime`, `servicePrincipalDisplayName` and `riskLevel`.
1152
+ All risk show commands default to the full reviewed property set.
988
1153
  `--select` requests properties from the [supported risk property sets](src/entra-risk.ts); `--fields` projects locally and must be a subset of the fetched selection.
989
1154
  Risk reads truncate text longer than 500 characters, including nested values such as `location` and the `additionalInfo` JSON string; `--full` restores complete text without lifting redaction, row caps or time bounds.
990
- See the [access and licence contract](docs/graph-coverage.md#licence-matrix-by-area) for the riskyUsers P2 requirement and risk-detection P1/P2 detail boundaries.
991
- Limited views stay limited: a premium detection without P2 detail reports `riskEventType` generic, hidden risk levels report the licence boundary instead of the level, and a null detection `correlationId` means no sign-in is associated.
1155
+ See the [access and licence contract](docs/graph-coverage.md#licence-matrix-by-area) for the riskyUsers P2 requirement, risk-detection P1/P2 detail boundaries and the Workload Identities Premium requirement behind the workload-identity reads.
1156
+ Limited views stay limited: a premium detection without P2 detail reports `riskEventType` generic, hidden risk levels report the licence boundary instead of the level, service-principal detections report `riskDetail` and `riskLevel` hidden without Workload Identities Premium, and a null detection `correlationId` means no sign-in is associated.
992
1157
  To correlate a detection to sign-ins, use `risk-detection show` or select `activityDateTime`, then filter the sign-in list above on the detection's `userPrincipalName` in that activity window; sign-in reads require the separate `AuditLog.Read.All` login above, and there is no riskySignIns endpoint.
1158
+ To correlate a workload detection, filter `service-principal-risk-detection list` on the principal's `servicePrincipalId` in the detection window, or list that principal's risk history with `risky-service-principal history list --service-principal <risky-service-principal-id>`; workload reads never confirm, dismiss or remediate risk.
993
1159
  WRITE-05 adds a named write: `mg-axi entra risky-user dismiss --user <risky-user-id>` dismisses one user's risk through `POST /identityProtection/riskyUsers/dismiss` with a single-element `{ "userIds": [...] }` body.
994
1160
  There is no bulk form: `--user` takes exactly one ID and a comma-separated list is a usage error.
995
1161
  The command supports only `--api-version v1.0`; beta writes are rejected before credentials or HTTP.
@@ -1058,7 +1224,7 @@ Delegated raw reads require explicit `--scopes` from the supported read choices
1058
1224
  Collections return `returned`, `complete` and `value`, default to 100 rows, and follow pages within budget under `--all`.
1059
1225
  `--limit` and `--all` cannot be combined.
1060
1226
  Completion describes pagination, not visibility of every directory object; group-member results include a warning for the [v1.0 service-principal limitation](docs/graph-coverage.md#licensing-and-completeness-findings), even when `complete` is true.
1061
- Strings longer than 4000 characters are truncated; `--full` removes string truncation without disabling redaction, reviewed-field filtering or row caps.
1227
+ Strings longer than 500 characters are truncated; `--full` removes string truncation without disabling redaction, reviewed-field filtering or row caps.
1062
1228
  Partial results include a `cursor` preserving buffered rows and the next page.
1063
1229
  Resume with `--cursor -` and supply the cursor token on stdin under the same collection path, profile and scopes, optionally with `--all` or a new `--limit`.
1064
1230
  For example, `mg-axi api get /users --cursor - --all --scopes https://graph.microsoft.com/User.Read.All < cursor.txt` reads a saved token through stdin.
@@ -1104,8 +1270,7 @@ The service requests only `https://graph.microsoft.com/.default`, representing t
1104
1270
  Ask an administrator to grant those permissions on the configured app registration; per-command delegated scopes cannot narrow the application token.
1105
1271
  Acquisition failures return `AUTH_REQUIRED` with consent and certificate/federation guidance, without user or device-code fallback.
1106
1272
 
1107
- Run `corepack pnpm build`, `corepack pnpm test` and `corepack pnpm lint` for shell validation.
1108
- The [CI workflow](.github/workflows/ci.yml) defines the platform/runtime matrix for shell build, test and lint checks, validates the Python inventory tooling separately, and rejects stale generated docs.
1273
+ Run `corepack pnpm build`, `corepack pnpm test` (test files run at most 4 at a time via `--test-concurrency=4` in the `test` script) and `corepack pnpm lint` for shell validation.
1109
1274
  The [implementation plan](PLAN.md) remains the design authority.
1110
1275
 
1111
1276
  The pinned [Entra operation inventory](docs/inventory.md) defines the INV-01 discovery boundary and schema for later build slices.
@@ -1131,8 +1296,17 @@ Missing profiles, an unknown selected profile or invalid configuration fail befo
1131
1296
  Read failures report per profile with rerun guidance and a nonzero exit.
1132
1297
 
1133
1298
  The installable skill lives at [skills/mg-axi/SKILL.md](skills/mg-axi/SKILL.md).
1134
- Install it explicitly with `npx skills add knowttl/mg-axi --skill mg-axi`; the setup command only shows guidance and does not install skills.
1135
- mg-axi ships no session hook, so the skill is the integration path.
1299
+ Agent discovery has two install paths, and either suffices alone.
1300
+ Install the skill explicitly with `npx skills add knowttl/mg-axi --skill mg-axi`; the setup command only shows guidance and does not install skills.
1301
+ For ambient context at every agent session start instead, install the CLI globally and opt into the session hook:
1302
+ ```sh
1303
+ npm install --global @knowttl/mg-axi
1304
+ mg-axi setup hooks
1305
+ ```
1306
+ This installs a `SessionStart` hook for Claude Code, Codex and OpenCode that prints a short local-only summary (configured profile names with tenant labels, auth-cache presence, write posture and version).
1307
+ The hook makes no network, Graph or sign-in call, and prints a short `not configured` record with exit 0 when unconfigured.
1308
+ Restart the agent session after running the installer.
1309
+ No other ordinary command installs hooks, plugins or configuration.
1136
1310
  The skill file is generated in full from the template in [src/docs.ts](src/docs.ts) and the command catalogue; [docs/coverage.md](docs/coverage.md) also uses the discovery inventory.
1137
- After building, regenerate both with `corepack pnpm run docs:generate` and verify freshness with `corepack pnpm run docs:check`; CI runs the freshness check.
1311
+ After building, regenerate both with `corepack pnpm run docs:generate` and verify freshness with `corepack pnpm run docs:check`; the release publish job runs the freshness check.
1138
1312
  Critical journeys stay packaged offline: `test/pack.test.mjs` drives setup, doctor and the user, group, Conditional Access and sign-in reads through the packaged executable with fixture credentials and blocked networking.