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:

  1. Tenant ID — identifies your organisation in Entra ID
  2. Client ID — identifies the app registration the plugin signs in as
  3. 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

  1. Sign in to the Azure Portal
  2. Go to Microsoft Entra ID → App registrations → New registration
  3. Give it a name (e.g. Entrust-Discovery-AzureAIFoundry) and click Register
  4. Copy the Directory (tenant) ID and Application (client) ID from the Overview page — these are your tenantId and clientId

Step 2 — Create a Client Secret

  1. In your new app registration, go to Certificates & secrets → New client secret
  2. Set a description and expiry, then click Add
  3. 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 secret (key slot), agent, tool/mcp_server, or project index records.

Search Service Contributor(optional)

Authorizes the Azure AI Search index-listing call.

No index records from standalone AI Search services.

# 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_enabled and 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 for enforcement_mode), andMicrosoft.Authorization/policyExemptions/read (optional, only for the per-assignment exemption field).
  • API Management gateway policy_summary: built-in Reader already covers it. A custom role must add Microsoft.ApiManagement/service/policies/read — without it the gateway record is still emitted, just without policy_summary (a non-fatal 403 is 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 add Microsoft.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 add Microsoft.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 those agent/mcp_server records 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 add Microsoft.CognitiveServices/accounts/projects/read — without it the projectrecord 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 add Microsoft.Authorization/roleAssignments/read and Microsoft.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 addMicrosoft.CognitiveServices/accounts/raiPolicies/read and .../raiBlocklists/read.