Overview
This plugin connects to Microsoft Azure to discover and inventory AI resources across Azure AI Foundry, Azure AI Search, Azure Machine Learning, and Azure API Management AI gateways. For each accessible subscription, it identifies AI services, projects, deployed models, agents and their dependencies, tool and MCP server connections, Responsible AI policies and blocklists, Azure Policy guardrails, search indexes, key slots, customer-managed encryption keys, and AI gateways. It also records account and project creators and the Azure roles assigned to their identities.
Note: The plugin records metadata only. It never retrieves or emits account key values, credential secrets, or private key material — only enough to detect presence (e.g. whether a key slot is populated), which is then discarded.
A few terms you'll see
Term | Meaning |
|---|---|
Entra ID | Microsoft's identity service (formerly Azure Active Directory), where you register the app the plugin signs in as. |
Service principal | The identity an application uses to sign in to Azure — created from an app registration. This plugin authenticates as one. |
ARM (Azure Resource Manager) | The control-plane layer/API used to list and read Azure resources. |
RBAC (Role-Based Access Control) | How Azure grants permissions — you assign roles (e.g. Reader) to the service principal at a scope(subscription, resource group, or resource). |
AML / APIM | Azure Machine Learning / Azure API Management. |
Before You Start
You need three pieces of information from Microsoft Entra ID:
- Tenant ID — identifies your organisation in Entra ID
- Client ID — identifies the app registration the plugin signs in as
- Client Secret — the password for that app registration
You will create these in the steps below, then assign the app the Azure roles it needs to read your resources.
Step 1 — Register an Application
- Sign in to the Azure Portal
- Go to Microsoft Entra ID → App registrations → New registration
- Give it a name (e.g.
Entrust-Discovery-AzureAIFoundry) and click Register - Copy the Directory (tenant) ID and Application (client) ID from the Overview page — these are your
tenantIdandclientId
Step 2 — Create a Client Secret
- In your new app registration, go to Certificates & secrets → New client secret
- Set a description and expiry, then click Add
- Copy the Value immediately — it is only shown once. This is your
clientSecret
Step 3 — Assign the Azure Roles
Unlike some Microsoft APIs, this plugin needs Azure RBAC role assignments (not Entra API permissions with admin consent). Assign these to the app you just created, scoped to the subscription(s) you want to scan.
You can do this in the Portal (Subscription → Access control (IAM) → Add role assignment → select your app as the member) or with the Azure CLI commands below. Replace <clientId> with your Application (client) ID and <subscriptionId> with the target subscription.
Role | Why you need it | What's missing without it |
|---|---|---|
Reader (required) | Lists and reads all core resources: AI services, projects, model deployments, AML workspaces, and API Management gateways/backends. | Nothing is discovered at all. |
Cognitive Services User(recommended) | Authorizes account key-slot detection and the Foundry data-plane calls that discover agents, tool/MCP-server connections, and project-scoped indexes. | No |
Search Service Contributor(optional) | Authorizes the Azure AI Search index-listing call. | No |
# Required — core discovery
az role assignment create --assignee <clientId> --role Reader \
--scope /subscriptions/<subscriptionId>
# Recommended — agents, tools/MCP servers, key slots, project indexes
az role assignment create --assignee <clientId> --role "Cognitive Services User" \
--scope /subscriptions/<subscriptionId>
# Optional — Azure AI Search indexes
az role assignment create --assignee <clientId> --role "Search Service Contributor" \
--scope /subscriptions/<subscriptionId>
Notes:
- Reader alone is not enough for the agent/tool/key data — those need the Cognitive Services User role, because Reader has no data-plane (
DataAction) permissions. This is by design in Azure, not a plugin limitation. - The plugin degrades gracefully: if a role is missing, only the asset types that depend on it are absent — the scan still succeeds and returns everything else.
- Roles can be scoped narrower than a whole subscription (to a resource group or single resource) if you prefer least-privilege. Apply the same role to each subscription you want scanned.
- Customer-managed encryption keys (CMK): to classify a CMK as a public/symmetric key rather than a generic secret, the app also needs Key Vault Get Key access on the referenced vault (e.g. the Key Vault Crypto Service Encryption User role). Without it the key is still reported, just as a generic
secret. The key's rotation-policy fields (key_rotation_enabledand related) need a separate Key Vault data action,Microsoft.KeyVault/vaults/keyrotationpolicies/read(included in the Key Vault Crypto User role) — without it those three fields are simply omitted, the rest of the CMK record is unaffected. - Guardrail policy assignments: built-in Reader already covers everything needed. A custom role must add
Microsoft.PolicyInsights/policyStates/queryResults/read(required),Microsoft.Authorization/policyAssignments/read(optional, only forenforcement_mode), andMicrosoft.Authorization/policyExemptions/read(optional, only for the per-assignmentexemptionfield). - API Management gateway
policy_summary: built-in Reader already covers it. A custom role must addMicrosoft.ApiManagement/service/policies/read— without it thegatewayrecord is still emitted, just withoutpolicy_summary(a non-fatal403is logged). Only the gateway's global ("All APIs") policy is summarised, never per-API policies, and only as presence flags and numbers (rate limit, quota, IP filter, CORS, JWT / client-certificate validation) — the raw policy XML is never emitted. - Diagnostic log fields (
diagnostic_logging_enabled,diagnostic_log_categories,diagnostic_log_destinations): built-in Reader already covers it. A custom role must addMicrosoft.Insights/diagnosticSettings/read— without it all three fields are omitted. project.compute_count/compute_types: built-in Reader already covers it. A custom role must addMicrosoft.MachineLearningServices/workspaces/computes/read— without it the field is omitted.- Registered agents and MCP servers on an API Management gateway: built-in Reader already covers it. A custom role must add
Microsoft.ApiManagement/service/apis/read— without it thoseagent/mcp_serverrecords silently never appear. - Project details (
arm_id, endpoints, managed identity, agent-identity blueprint,created_by…): built-in Reader already covers it. A custom role must addMicrosoft.CognitiveServices/accounts/projects/read— without it theprojectrecord still appears, with only its base fields. role_assignments(Azure roles held by an account, project or agent identity): built-in Reader already covers it. A custom role must addMicrosoft.Authorization/roleAssignments/readandMicrosoft.Authorization/roleDefinitions/read— without the first the field is omitted; without the second it appears but with role IDs only, no role names.- Responsible AI policies/blocklists: built-in Reader already covers it. A custom role must add
Microsoft.CognitiveServices/accounts/raiPolicies/readand.../raiBlocklists/read.