← Back to Guides

Securing APIs with API Management

AdvancedAPI Management2026-03-14

Security Layers

A robust API security strategy involves multiple layers:

  1. Network Security — VNET integration, Private Endpoints
  2. Authentication — Who is calling the API?
  3. Authorisation — What are they allowed to do?
  4. Encryption — TLS for data in transit
  5. Throttling — Prevent abuse

Subscription Keys

The simplest authentication method. Every APIM product can require a subscription key:

  • Passed via Ocp-Apim-Subscription-Key header or subscription-key query parameter
  • Generated per subscription (primary and secondary for rotation)
  • Can be scoped to All APIs, a single Product, or a single API

Important: Subscription keys alone are not sufficient for production APIs. Combine with OAuth 2.0 or client certificates.

OAuth 2.0 / OpenID Connect

Validating JWT Tokens

<validate-jwt header-name="Authorization" require-scheme="Bearer"
              failed-validation-httpcode="401" failure-message="Unauthorised">
    <openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
    <audiences>
        <audience>{api-app-id}</audience>
    </audiences>
    <issuers>
        <issuer>https://login.microsoftonline.com/{tenant}/v2.0</issuer>
    </issuers>
    <required-claims>
        <claim name="roles" match="any">
            <value>API.Read</value>
            <value>API.Write</value>
        </claim>
    </required-claims>
</validate-jwt>

Extracting Claims for Backend

<set-header name="X-User-Id" exists-action="override">
    <value>@(context.Request.Headers.GetValueOrDefault("Authorization","")
        .AsJwt()?.Claims.GetValueOrDefault("oid", "unknown"))</value>
</set-header>

Client Certificates (mTLS)

For service-to-service authentication:

<choose>
    <when condition="@(context.Request.Certificate == null ||
        context.Request.Certificate.Thumbprint != "expected-thumbprint")">
        <return-response>
            <set-status code="403" reason="Forbidden" />
        </return-response>
    </when>
</choose>

Managed Identity

Use APIM's managed identity to authenticate to backend services:

<authentication-managed-identity resource="https://management.azure.com/" />

This eliminates the need to store credentials in APIM configuration.

Network Security

VNET Integration (Premium Tier)

  • External mode — Gateway accessible from internet, backend in VNET
  • Internal mode — Gateway only accessible within VNET

Private Endpoints

Available on Premium tier for fully private API access.

API Scopes and Permissions

Configure API Permissions in Azure AD

1. Register API application in Azure AD
2. Define App Roles or OAuth 2.0 scopes:
   - API.Read  — Read access to API resources
   - API.Write — Write access to API resources
   - API.Admin — Administrative operations
3. Configure client application permissions
4. Validate in APIM using validate-jwt policy

Role-Based Access in Policies

<validate-jwt header-name="Authorization" require-scheme="Bearer">
    <openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
    <required-claims>
        <claim name="roles" match="any">
            <value>API.Read</value>
        </claim>
    </required-claims>
</validate-jwt>

<!-- Check for write permission on POST/PUT/DELETE -->
<choose>
    <when condition="@(new [] {"POST","PUT","DELETE"}.Contains(context.Request.Method))">
        <validate-jwt header-name="Authorization" require-scheme="Bearer">
            <openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
            <required-claims>
                <claim name="roles" match="any">
                    <value>API.Write</value>
                </claim>
            </required-claims>
        </validate-jwt>
    </when>
</choose>

Microsoft Reference: Protect APIs with Azure AD

IP Allowlisting and Geo-Filtering

IP Allowlisting

<ip-filter action="allow">
    <address>203.0.113.10</address>
    <address-range from="10.0.0.0" to="10.0.0.255" />
</ip-filter>

Geo-Filtering

<choose>
    <when condition="@(new [] {"CN","RU","KP"}.Contains(context.Request.Headers.GetValueOrDefault("X-Forwarded-For-Country","")))">
        <return-response>
            <set-status code="403" reason="Forbidden" />
            <set-body>Access denied from this region</set-body>
        </return-response>
    </when>
</choose>

WAF Integration

Deploy Azure Application Gateway with Web Application Firewall (WAF) in front of APIM:

Client → Application Gateway (WAF) → APIM → Backend APIs

WAF protects against:

  • SQL injection
  • Cross-site scripting (XSS)
  • Command injection
  • HTTP protocol violations
  • OWASP Top 10 threats

Microsoft Reference: APIM with Application Gateway

Best Practices

  1. Never rely solely on subscription keys — add OAuth 2.0 or mTLS
  2. Rotate keys regularly — use primary/secondary key pattern
  3. Use Managed Identity for backend authentication
  4. Enable TLS 1.2+ and disable older protocols
  5. Implement rate limiting to prevent abuse
  6. Use VNET integration for internal APIs in production
  7. Validate all input — use <validate-content> policy for request body validation
  8. Log security events to Application Insights and Log Analytics
  9. Use Application Gateway WAF for external-facing APIs
  10. Implement CORS policies restrictively — only allow known origins
  11. Use certificate pinning for critical service-to-service communication
  12. Regular security audits — review policies and access controls quarterly

Official Microsoft Resources