Microsoft Defender for Cloud · Azure API Management
API endpoints that are unused should be disabled and removed from the Azure API Management service
Written and reviewed by Emnode · Last reviewed
What does the recommendation "API endpoints that are unused should be disabled and removed from the Azure API Management service" check?
A Microsoft Defender for APIs assessment that lists API endpoints in an API Management instance that have received no inbound call traffic in the last 30 days, marking them as Inactive and recommending they be disabled and removed. It only sees APIs already onboarded to the Defender for APIs plan, so it relies on observed runtime traffic, not on a static read of the API definition. It does not judge whether an endpoint is authenticated, vulnerable or sensitive, and it does not cover APIs hosted outside API Management or APIs that are defined but never onboarded to Defender. A genuinely live endpoint that simply had a quiet 30-day window will still be flagged, because the signal is absence of traffic rather than absence of purpose.
Why does "API endpoints that are unused should be disabled and removed from the Azure API Management service" matter?
Every published endpoint is reachable attack surface that has to be patched, monitored and reasoned about, whether or not anyone still calls it. Forgotten APIs are the ones that quietly fall out of the release cycle: an old version left in place after a migration, a test API promoted to production by mistake, a partner integration that ended months ago. These endpoints rarely get the latest authentication policy, rate limit or schema validation, so they become the soft entry point an attacker probes once the obvious routes are hardened. Removing what nobody uses shrinks the surface you must defend and cuts the chance that a stale, under-maintained route leaks data or relays a request into your backend.
How do I fix "API endpoints that are unused should be disabled and removed from the Azure API Management service"?
- Open the flagged endpoint in API Management, confirm with the owning team that no live consumer depends on it, then check the analytics and Defender for APIs traffic view to verify the 30-day inactivity rather than trusting the flag alone.
- Disable it first as a safe staging step by removing the API from its products or stripping its subscriptions so callers get a 401, leave it parked for a deprecation window, then delete it with 'az apim api delete --resource-group <rg> --service-name <apim> --api-id <api-id> --delete-revisions true'.
- Stop the backlog returning by codifying only the APIs you intend to publish in your Bicep or Terraform 'Microsoft.ApiManagement/service/apis' resources, so any endpoint not in source control is removed on the next deployment, and keep the Defender for APIs plan enabled so newly idle endpoints keep surfacing.
Remediation script · bash
# 1. Enable the Defender for APIs plan on the subscription so onboarded APIs are inspected.
az security pricing create --name Api --tier Standard
# 2. Disable the deprecated direct management endpoint (retired 15 March 2025).
# 'customProperties' on the service controls this gateway behaviour.
az apim update --name apim-prod --resource-group rg-platform \
--set 'properties.customProperties."Microsoft.WindowsAzure.ApiManagement.Gateway.ManagementEndpoint"=false'
# 3. Re-enable backend certificate chain and name validation on a backend that
# had it switched off. There is no native 'az apim backend' TLS flag, so PUT
# the documented 'tls' block via the management API (api-version 2024-05-01).
sub=$(az account show --query id -o tsv)
az rest --method put \
--uri "https://management.azure.com/subscriptions/$sub/resourceGroups/rg-platform/providers/Microsoft.ApiManagement/service/apim-prod/backends/payments-backend?api-version=2024-05-01" \
--body '{"properties":{"url":"https://payments.internal/","protocol":"http","tls":{"validateCertificateChain":true,"validateCertificateName":true}}}'
# 4. Ratchet it shut: audit any instance whose management endpoint stays enabled.
# Look the built-in policy up by display name; never hardcode a definition GUID.
pid=$(az policy definition list \
--query "[?displayName=='API Management direct management endpoint should not be enabled'].name" -o tsv)
az policy assignment create \
--name audit-apim-mgmt-endpoint \
--policy "$pid" \
--scope "/subscriptions/$sub" Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure API Management.
Is "API endpoints that are unused should be disabled and removed from the Azure API Management service" a false positive?
A seasonal or disaster-recovery API that is intentionally kept warm but rarely invoked, for example a quarterly billing reconciliation endpoint or a failover route exercised only during an incident, will be marked Inactive after 30 quiet days even though removing it would be wrong. Document the business reason, exempt that resource in Defender for Cloud rather than deleting the endpoint, and review the exemption on a fixed schedule so it does not become the stale route nobody remembers.
More Azure API Management controls
- API endpoints in Azure API Management should be authenticated
- API Management APIs should use only encrypted protocols
- API Management calls to API backends shouldn't bypass certificate thumbprint or name validation
- API Management direct management endpoint shouldn't be enabled
- API Management secret named values should be stored in Azure Key Vault
- API Management subscriptions shouldn't be scoped to all APIs
- Azure API Management APIs should be onboarded to Defender for APIs