Required Permissions
The service principal's Azure AD role assignments must cover all of the following. Each is verified against Microsoft's published built-in role definitions (AI + machine learning built-in roles).
# | What the plugin needs | Why | Recommended built-in role | Grant command |
|---|---|---|---|---|
1 | List subscriptions, resource groups, accounts, deployments, RAI policies/blocklists, search services, AML workspaces, and API Management services/backends (all read-only ARM calls) | Core resource and guardrail enumeration | Reader |
|
2 | Call | Detect which account key slots ( | Cognitive Services User |
|
3 | Call | Authenticate the transient index-listing data-plane call | Search Service Contributor |
|
Notes:
- Reader alone is not enough for roles 2/3.
listKeys/listAdminKeys, and the Foundry data-plane calls, require actions/DataActionsthat are not included in the Reader role (Reader'sdataActionslist is empty). Without roles 2 and 3, key-slot detection,agent/tool/mcp_server/project-scopedindexdiscovery, and AI Search index listing silently return nothing (the plugin degrades gracefully rather than erroring — see Troubleshooting). - API Management gateway/backend discovery needs
Microsoft.ApiManagement/service/readandMicrosoft.ApiManagement/service/backends/read. The built-in Reader role includes these automatically (Reader is a wildcard*/readgrant covering every resource type). Registered-agent detection additionally readsMicrosoft.ApiManagement/service/apis/read, and the gateway'spolicy_summaryfield additionally readsMicrosoft.ApiManagement/service/policies/read— both also covered automatically by Reader. If you use a custom/narrower role instead of built-in Reader, all four actions must be added explicitly — it's easy to overlook since API Management shares no resource type with the rest of Foundry/Cognitive Services scanning. Missingservice/read,backends/read, orapis/readcauses no visible error (ARM's list API silently returns200 OKwith an empty array), sogateway/endpoint/registered-agentrecords simply never appear; missingpolicies/readreturns an explicit403(logged, non-fatal) andpolicy_summaryis simply omitted from thegatewayrecord (see Troubleshooting). - Cognitive Services User is the least-privileged built-in role that grants
listkeys/action; it also grants full Cognitive Services data-plane access (Microsoft.CognitiveServices/*as aDataAction) as a side effect — there's no more granular built-in role that isolates just the key-listing action. That sameDataActionis what authorizes theagent/tool/mcp_server/project-scopedindexdata-plane probes, so this role (or an equivalent customDataActiongrant) is required for those asset types too, not just for key-slot detection. If this is too broad for your security posture, define a custom role with onlyMicrosoft.CognitiveServices/*/read,Microsoft.CognitiveServices/accounts/listkeys/action, and theMicrosoft.CognitiveServices/*DataAction. - Search Service Contributor grants full search-service management (
Microsoft.Search/searchServices/*, which includeslistAdminKeys/action) but no index data access (queries/documents) — appropriate here since the plugin only lists index metadata, never document content. guardrail_policy_assignmentsneedsMicrosoft.PolicyInsights/policyStates/queryResults/readandMicrosoft.Authorization/policyAssignments/read. Built-in Reader includes both automatically (Reader is*/read); a custom/narrower role must add them explicitly. WithoutpolicyStates/queryResults/read, the whole field is silently absent (ARM returns403, logged but non-fatal). WithoutpolicyAssignments/read, the field still populates butenforcement_modeis silently omitted —NewListForResourcePager(used for the per-deployment classic-ARM assignments) doesn't require this action, butGetByID(used to resolveenforcement_modefor account-level Resource-Provider-mode/Guardrail assignments) does. The per-assignmentexemptionsub-field additionally needsMicrosoft.Authorization/policyExemptions/read(also covered automatically by Reader) — without it, assignments still populate but never carry anexemption.project.compute_count/compute_typesneedsMicrosoft.MachineLearningServices/workspaces/computes/read(covered automatically by Reader). Without it, the field is silently omitted rather than erroring.service.diagnostic_logging_enabled/diagnostic_log_categories/diagnostic_log_destinationsneedMicrosoft.Insights/diagnosticSettings/read(covered automatically by Reader). Without it, all three fields are silently omitted rather than erroring.role_assignmentsonservice/project/agentneedsMicrosoft.Authorization/roleAssignments/read, plusMicrosoft.Authorization/roleDefinitions/readto resolverole_name/role_type(both covered automatically by Reader). This is optional accountability metadata: withoutroleAssignments/readARM returns200 OKwith an empty list (or403, logged once, non-fatal) and the field is simply omitted; withoutroleDefinitions/readthe field still populates but carries onlyrole_definition_id/scope.- Project-level fields (
arm_id,endpoints,managed_identity_*,agent_identity_*, ownership) needMicrosoft.CognitiveServices/accounts/projects/read— covered by Reader and by theMicrosoft.CognitiveServices/*/readcustom-role grant above. Without it theprojectrecord still appears (from the AML workspace listing) with only the base fields. - All three roles can be scoped to a subscription, resource group, or individual resource — narrower scoping is recommended over subscription-wide assignment where feasible.
- If you don't need AI Search or account-key discovery for your use case, roles 2/3 can be omitted; the corresponding fields will simply be absent from scan output for those resources.
Permissions by Discovered Asset Type
For teams building a custom RBAC role instead of assigning the built-in roles above, here is the exact permission each emitted type depends on:
Emitted type | Permission required | Kind | Covered by |
|---|---|---|---|
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Cognitive Services User |
| Parent | Action + Data-plane | Reader (reference only) — the Key Vault |
CMK rotation-policy fields ( | Key Vault data-plane | Data-plane | Not covered by |
|
| DataAction | Cognitive Services User |
|
| Action | Search Service Contributor |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
|
| Action | Reader |
Without the Key Vault Get Key grant, the CMK reference is still emitted, but the key's type can't be resolved from the vault, so it silently falls back to a generic secret record instead of pubkey/symkey. Without the Key Vault rotation-policy grant (Microsoft.KeyVault/vaults/keyrotationpolicies/read), the CMK record is unaffected but the three rotation fields are simply omitted.