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

az role assignment create --assignee <clientId> --role Reader --scope /subscriptions/<subscriptionId>

2

Call Microsoft.CognitiveServices/accounts/listkeys/action, plus the Microsoft.CognitiveServices/* DataAction

Detect which account key slots (key1/key2) are populated, and authorize the Foundry project data-plane calls used for agent, tool/mcp_server, and project-scoped indexdiscovery

Cognitive Services User

az role assignment create --assignee <clientId> --role "Cognitive Services User" --scope /subscriptions/<subscriptionId>

3

Call Microsoft.Search/searchServices/listAdminKeys/action

Authenticate the transient index-listing data-plane call

Search Service Contributor

az role assignment create --assignee <clientId> --role "Search Service Contributor" --scope /subscriptions/<subscriptionId>

Notes:

  • Reader alone is not enough for roles 2/3. listKeys/listAdminKeys, and the Foundry data-plane calls, require actions/DataActions that are not included in the Reader role (Reader's dataActions list is empty). Without roles 2 and 3, key-slot detection, agent/tool/mcp_server/project-scoped index discovery, 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/read and Microsoft.ApiManagement/service/backends/read. The built-in Reader role includes these automatically (Reader is a wildcard */read grant covering every resource type). Registered-agent detection additionally reads Microsoft.ApiManagement/service/apis/read, and the gateway's policy_summary field additionally reads Microsoft.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. Missing service/read, backends/read, or apis/read causes no visible error (ARM's list API silently returns 200 OK with an empty array), so gateway/endpoint/registered-agent records simply never appear; missing policies/read returns an explicit 403(logged, non-fatal) and policy_summary is simply omitted from the gateway record (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 a DataAction) as a side effect — there's no more granular built-in role that isolates just the key-listing action. That same DataAction is what authorizes the agent/tool/mcp_server/project-scoped index data-plane probes, so this role (or an equivalent custom DataAction grant) 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 only Microsoft.CognitiveServices/*/read, Microsoft.CognitiveServices/accounts/listkeys/action, and the Microsoft.CognitiveServices/* DataAction.
  • Search Service Contributor grants full search-service management (Microsoft.Search/searchServices/*, which includes listAdminKeys/action) but no index data access (queries/documents) — appropriate here since the plugin only lists index metadata, never document content.
  • guardrail_policy_assignments needs Microsoft.PolicyInsights/policyStates/queryResults/read and Microsoft.Authorization/policyAssignments/read. Built-in Reader includes both automatically (Reader is */read); a custom/narrower role must add them explicitly. Without policyStates/queryResults/read, the whole field is silently absent (ARM returns 403, logged but non-fatal). Without policyAssignments/read, the field still populates but enforcement_modeis silently omitted — NewListForResourcePager (used for the per-deployment classic-ARM assignments) doesn't require this action, but GetByID (used to resolve enforcement_mode for account-level Resource-Provider-mode/Guardrail assignments) does. The per-assignment exemption sub-field additionally needs Microsoft.Authorization/policyExemptions/read(also covered automatically by Reader) — without it, assignments still populate but never carry an exemption.
  • project.compute_count/compute_types needs Microsoft.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_destinations need Microsoft.Insights/diagnosticSettings/read (covered automatically by Reader). Without it, all three fields are silently omitted rather than erroring.
  • role_assignments on service/project/agent needs Microsoft.Authorization/roleAssignments/read, plus Microsoft.Authorization/roleDefinitions/read to resolve role_name/role_type (both covered automatically by Reader). This is optional accountability metadata: without roleAssignments/read ARM returns 200 OK with an empty list (or 403, logged once, non-fatal) and the field is simply omitted; without roleDefinitions/read the field still populates but carries only role_definition_id/scope.
  • Project-level fields (arm_id, endpoints, managed_identity_*, agent_identity_*, ownership) need Microsoft.CognitiveServices/accounts/projects/read — covered by Reader and by the Microsoft.CognitiveServices/*/read custom-role grant above. Without it the project record 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

service (Cognitive Services/AI Foundry account, AI Search service, AML workspace)

Microsoft.CognitiveServices/accounts/read, Microsoft.Search/searchServices/read, Microsoft.MachineLearningServices/workspaces/read

Action

Reader

model (deployment)

Microsoft.CognitiveServices/accounts/deployments/read

Action

Reader

ai_asset (RAI policy)

Microsoft.CognitiveServices/accounts/raiPolicies/read

Action

Reader

ai_asset (RAI blocklist)

Microsoft.CognitiveServices/accounts/raiBlocklists/read

Action

Reader

project (Foundry project / Project-kind AML workspace)

Microsoft.MachineLearningServices/workspaces/read

Action

Reader

secret (account key slots)

Microsoft.CognitiveServices/accounts/listkeys/action

Action

Cognitive Services User

pubkey / symkey / secret (CMK reference)

Parent service read for the KeyVaultURI/KeyIdentifier reference (sourced from the same ARM payload), plus the Key Vault data-plane Get Key permission on the referenced vault to resolve the key's actual type/size

Action + Data-plane

Reader (reference only) — the Key Vault Get Keypermission is notcovered by any role above and must be granted separately on the vault (e.g. the Key Vault Crypto Service Encryption User role or an access policy)

CMK rotation-policy fields (key_rotation_enabled, key_rotation_time_after_create, key_notify_before_expiry)

Key Vault data-plane Microsoft.KeyVault/vaults/keyrotationpolicies/read, on the same vault as Get Key above

Data-plane

Not covered by Get Key— a separate data action, must be granted explicitly (e.g. the Key Vault Crypto User role includes it)

agent, tool / mcp_server, project-scoped index

Microsoft.CognitiveServices/*

DataAction

Cognitive Services User

index (AI Search service indexes)

Microsoft.Search/searchServices/listAdminKeys/action

Action

Search Service Contributor

gateway (API Management instance)

Microsoft.ApiManagement/service/read

Action

Reader

gateway.policy_summary (safe, non-secret policy signals)

Microsoft.ApiManagement/service/policies/read

Action

Reader

endpoint (API Management AI backend)

Microsoft.ApiManagement/service/backends/read

Action

Reader

agent (registered via Register asset, detected via APIM)

Microsoft.ApiManagement/service/apis/read

Action

Reader

project.compute_count/compute_types(attached AML compute)

Microsoft.MachineLearningServices/workspaces/computes/read

Action

Reader

guardrail_policy_assignments on model(classic ARM-mode)

Microsoft.PolicyInsights/policyStates/queryResults/read(compliance state); assignment listing itself needs no extra action beyond Reader

Action

Reader

guardrail_policy_assignments on service(Resource-Provider-mode/Guardrail policies)

Microsoft.PolicyInsights/policyStates/queryResults/read(required), plus Microsoft.Authorization/policyAssignments/read (optional, only for enforcement_mode)

Action

Reader

guardrail_policy_assignments[].exemption

Microsoft.Authorization/policyExemptions/read

Action

Reader

service.diagnostic_logging_enabled/diagnostic_log_categories/diagnostic_log_destinations

Microsoft.Insights/diagnosticSettings/read

Action

Reader

project ARM/ownership fields (arm_id, endpoints, managed_identity_*, agent_identity_*, created_by…)

Microsoft.CognitiveServices/accounts/projects/read

Action

Reader

role_assignments on service / project / agent

Microsoft.Authorization/roleAssignments/read (required), Microsoft.Authorization/roleDefinitions/read (optional, for role_name/role_type)

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.