CORS on Azure API Management — Complete Configuration
Azure API Management sits in front of your backend — and handles CORS before requests reach it. Your backend's CORS configuration is completely bypassed. You configure CORS in APIM using inbound policy XML.
Where CORS goes in APIM
APIM uses XML policy documents at four scopes (global, product, API, operation). Add CORS at the API scope to apply it to all operations in your API, or at the operation scope for per-endpoint control.
The CORS policy XML
<!-- Azure Portal → API Management → Your API → Inbound processing → Add policy --> <cors allow-credentials="true"> <allowed-origins> <origin>https://app.example.com</origin> <origin>https://staging.example.com</origin> </allowed-origins> <allowed-methods preflight-result-max-age="300"> <method>GET</method> <method>POST</method> <method>PUT</method> <method>DELETE</method> <method>OPTIONS</method> </allowed-methods> <allowed-headers> <header>Authorization</header> <header>Content-Type</header> <header>Ocp-Apim-Subscription-Key</header> </allowed-headers> <expose-headers> <header>X-Request-ID</header> </expose-headers> </cors>
Apply in Azure Portal
- Azure Portal → API Management → Your service → APIs → Your API
- Select "All operations" for API-level, or a specific operation
- Inbound processing → click the policy icon → add the cors element inside <inbound><base />
- Save and test
Wildcard origin in APIM
<!-- Public API — no credentials --> <cors allow-credentials="false"> <allowed-origins> <origin>*</origin> </allowed-origins> <allowed-methods> <method>GET</method> <method>OPTIONS</method> </allowed-methods> <allowed-headers> <header>*</header> </allowed-headers> </cors>
Bicep / ARM deployment
resource apiPolicy 'Microsoft.ApiManagement/service/apis/policies@2022-08-01' = { name: 'policy' parent: myApi properties: { format: 'rawxml' value: ''' <policies> <inbound> <base /> <cors allow-credentials="true"> <allowed-origins> <origin>https://app.example.com</origin> </allowed-origins> <allowed-methods><method>GET</method><method>POST</method></allowed-methods> <allowed-headers><header>Authorization</header><header>Content-Type</header></allowed-headers> </cors> </inbound> <backend><base /></backend> <outbound><base /></outbound> </policies> ''' }
}
After applying the policy, use CORSFixer to send a real OPTIONS preflight to your APIM endpoint and confirm the response headers are correct.
Test your APIM CORS config → CORSFixer