Intro
The need for an API Management (APIM) layer and a well-structured segmentation architecture within an organization is something most architects agree on. However, having the luxury of building a fully greenfield APIM environment from scratch is rare. In reality, most enterprises already operate legacy web services or APIs built years ago, which makes introducing a modern APIM platform a challenging process.
One of the first hurdles often faced is integration with existing Identity Providers (IdPs). Establishing a secure token exchange mechanism that the API Gateway can trust is essential, but it is not always straightforward.
A modern APIM solution should therefore offer a flexible architecture that supports horizontal scaling, fine-grained access control, and seamless identity integration using the organization’s existing IdP ecosystem.
WSO2 API Manager 4.6 addresses this challenge by natively supporting external identity providers such as Auth0, Azure AD, Keycloak, Okta, Ping Identity, and, of course, WSO2 Identity Server, along with any other IdP that supports OAuth2/OIDC.
This article examines the technical aspects and configuration details for integrating Azure AD as a Key Manager with the WSO2 API Manager Gateway, aiming to make the setup process as seamless as possible.
Requests
My client already had Azure AD B2C in place and wanted to use it as a Key Manager for the WSO2 API Manager Gateway (APIM GW). In addition, they preferred to leverage a preconfigured application instead of creating a new one from scratch.
Solution
WSO2 provides comprehensive documentation to help you get started with this setup Configure AzureAD as Key Manager.
Note 1
You’ll need an application in Azure that acts as a connector between WSO2 API Manager and Azure AD. This application must have the following permissions assigned:
Application.Read.All
Application.ReadWrite.All
Application.ReadWrite.OwnedBy
Although these permissions are mentioned in the official documentation, it’s worth emphasizing that missing any of them will prevent APIM from creating or locating applications within your Azure environment, causing the configuration to fail.
Note 2
Setting up a new Key Manager in the WSO2 Admin Portal is the first challenge you’ll need to overcome.
From the dropdown list of available Key Manager Types, select Azure AD, and ensure that at least the Direct Token Issuance method is enabled.
You can find the relevant endpoint information under the Endpoints section in your Azure AD application.

However, keep in mind that while many fields in the WSO2 configuration are mandatory, Azure AD does not utilize all of them. As a result, some fields may appear redundant and can remain unused. Your configuration fields should look similar to the following:
Well-known URL , mandatory
(Paste the OpenID Connect metadata document (v2.0) URL collected from the endpoints and click on Import)
In my case :
https://login.microsoftonline.com/{tenantID}/v2.0/.well-known/openid-configuration
Issuer , mandatory
(in documentation example is https://login.microsoftonline.com/{tenent-id}/v2.0). If you leave it like that will fail becouse token issuer in reality looks like 'https://sts.windows.net/{tenent-id}/'
In my case,
https://sts.windows.net/{tenent-id}/
Client Registration Endpoint , mandatory
In my case:
https://graph.microsoft.com
Introspection Endpoint, marked as mandatory, but AzureAd does not use it
I put:
https://login.microsoftonline.com/{tenent-id}/oauth2/v2.0/token
Token Endpoint, mandatory
In my case:
https://login.microsoftonline.com/{tenent-id}/oauth2/v2.0/token
Revoke Endpoint, marked as mandatory, but AzureAd does not use it
I put (again):
https://login.microsoftonline.com/{tenent-id}/oauth2/v2.0/token
Userinfo Endpoint, mandatory
In my case:
https://graph.microsoft.com/oidc/userinfo
Authorize Endpoint, not mandatory
In my case:
https://login.microsoftonline.com/{tenent-id}/oauth2/v2.0/authorize
Scope Management Endpoint, in the form, it is marked as mandatory, even though the documentation doesn’t clearly explain its purpose, and in practice, it doesn’t seem to be used. I entered the scope required when requesting a token, but in reality, any value will work without affecting functionality.
In my case:
https://graph.microsoft.com/.default
Also, for clarity: wherever you see {tenantID} in the endpoint URLs mentioned above, make sure to replace it with your actual Azure tenant ID.
The rest of the steps you can follow from the documentation
Fill the Consumer Key Claim URI: appid in the Claim URIs section.
Set the Grant Types: client_credentials (Only use this grant type).
Microsoft Graph API Endpoint:
https://graph.microsoft.com
Microsoft Graph API Endpoint Version, select the checkbox for v1.0
Client ID : Paste the Application (client) ID
Client Secret : Paste the client secret value that is generated
Key Manager Permission: Permission type for role-based Key Manager restriction.
e.g., PUBLIC, ALLOW, DENY
Note 3
After completing these steps, you can navigate to the WSO2 Developer Portal to create an application, generate keys (Client ID and Secret), subscribe to an API, and obtain an access token. Once you invoke the API, the call should return a 200 OK response confirming that everything is working as expected.
Congratulations, you’re on the right track and officially halfway there!
Note 4
To enable the option for out-of-band keys, allowing you to use an existing application previously created in Azure, open the /repository/conf/deployment.toml file in a text editor.
Add the following configuration under the [apim.devportal] section:
[apim.devportal]
enable_key_provisioning = true
After restarting the server, you’ll be able to register applications in the Developer Portal using the Client ID and Client Secret that were previously created in Azure.
Note 5
When you create an application in Azure, the Application ID URI field is empty by default. This causes a problem, tokens generated from such an application will fail, returning an error indicating that the application cannot be found under the specified tenant.
To fix this, make sure to define the Application ID URI in the following format:
api://<Application (client) ID>
Although this step is briefly mentioned in the post-check section of the documentation, it isn’t clearly explained where to find or configure it. So, take a moment to verify this setting before proceeding — it will save you unnecessary troubleshooting later.
Happy coding!
If you run into any issues or discover new challenges along the way, feel free to share them in the comments — I’d love to hear your experiences and help if I can.

Top comments (0)