Understanding the Results
Each discovered asset is one JSON record. The type field tells you what it is:
| What it is |
|---|---|
| An AI Foundry / Cognitive Services account, AI Search service, or AML hub |
| A Foundry project (workspace) inside an account |
| A deployed model (name, version, SKU, provisioning state) |
| A Foundry agent — its identity ( |
| A project connection to a tool or Model Context Protocol server. An Agent2Agent connection to a peer agent is a |
| An MCP server published on an API Management gateway (APIM → APIs → MCP Servers); has |
| Either a Responsible AI content-filter policy / custom blocklist ( |
| An Azure AI Search index (metadata only — no document content) |
| Presence of an account key slot ( |
| A customer-managed encryption key reference (public/symmetric) |
| An API Management AI gateway and its AI backend endpoints; the gateway carries |
| An agent manually registered via Foundry's "Register asset" flow (HTTP/REST or A2A), detected through its API Management gateway rather than the native agent list; A2A registrations carry the peer's |
Across these, service and project records also carry ownership metadata (created_by, created_at, last_modified_*, tags), and service/project/agent records carry role_assignments — the Azure roles held by that resource's own identity within the scanned subscription (including roles inherited from management groups, but not roles held in other subscriptions). A native agent normally has none, so a missing role_assignments on an agent is expected, not a permissions problem.
Every non-service record parented to a Cognitive Services/AI Foundry account includes extra.account (the parent resource that owns it) and, for project-scoped assets, extra.project — so you can always trace the ownership chain. The exception is anything parented to an API Management gateway instead (gateway, endpoint, and registered agent records) — those use extra.gateway in place of extra.account.
Troubleshooting
test fails with an authentication/authorization error
- Verify the tenant ID, client ID, and client secret are correct and the secret hasn't expired
- Confirm the app has at least Reader on the target subscription(s)
Scan succeeds but finds nothing
- Usually a role-scoping issue — Reader must be assigned at a scope that covers the resource groups holding your resources. A Reader grant on one resource group won't reveal a sibling group.
Services are found, but no project-level agent / tool / mcp_server / secret records
- The app is missing the Cognitive Services User role (the data-plane grant). This is separate from Reader — add it and re-scan. (Agents and MCP servers discovered through an API Management gateway only need Reader — see the gateway entries below.)
A gateway record has no policy_summary
- Two possible causes:
- Permission gap — the scan log contains
ARM request to .../policies/policy... returned status 403 Forbidden. With a custom role, addMicrosoft.ApiManagement/service/policies/read. - Nothing to summarise — no such log line. The field is produced only from the gateway's service-level (global) policy, and only when that policy contains a rate-limit, quota, IP-filter, CORS, JWT or client-certificate element. Policies attached to individual APIs, operations or products are not read. To confirm, view the global policy XML however you manage APIM (e.g. portal APIs → All APIs → policies,
az apim, or ARMGET .../policies/policy?format=rawxml).
- Permission gap — the scan log contains
role_assignments never appears on service / project records
- With a custom role, add
Microsoft.Authorization/roleAssignments/read(androleDefinitions/readfor role names). Azure returns an empty list, not an error, when it's missing. Anagentwithoutrole_assignmentsis not by itself a permission problem — its Entra Agent Identity only holds roles someone has explicitly granted it.
diagnostic_logging_enabled and related fields are missing on service records
- With a custom role, add
Microsoft.Insights/diagnosticSettings/read. Degrades silently.
Search services are found, but no index records
- The app is missing the Search Service Contributor role.
An API Management gateway with an AI backend isn't discovered
- If you used a custom/narrower role instead of built-in Reader, add
Microsoft.ApiManagement/service/readandMicrosoft.ApiManagement/service/backends/readexplicitly — Azure returns an empty list (not an error) when these are missing, so it looks like "no gateways exist." Also confirmMicrosoft.ApiManagementis a registered resource provider on the subscription.
A manually registered agent isn't discovered as its own agent record
- It may be a duplicate on purpose: if the registered agent points back at a native agent already found via
/agentsin the same subscription, the plugin recognizes it as the same agent and doesn't emit it twice — the native record instead showsdiscovered_via: ["agents_api", "apim_api"]and lists the gateway underapim_registrations. - The gateway itself may be skipped: only API Management instances with at least one backend pointing at a recognised AI provider are inspected, so registrations on a gateway without such a backend are not discovered.
- Otherwise, the same custom-role gap as above applies — add
Microsoft.ApiManagement/service/apis/read(this also covers gateway-publishedmcp_serverrecords).
guardrail_policy_assignments never appears
- The app is missing
Microsoft.PolicyInsights/policyStates/queryResults/read(logged as a non-fatal403 AuthorizationFailed, unlike most gaps in this list).
guardrail_policy_assignments appears but enforcement_mode is always missing
- The app is missing
Microsoft.Authorization/policyAssignments/read. This one degrades silently.
Scan rejected with STATE_ERROR
- This plugin only does full scans (no incremental). Clear the state (
{"state": {}}) and retry.