Apache APISIX OpenID Connect with Microsoft Entra ID

Apache APISIX can validate Microsoft Entra ID access tokens at the gateway using the openid-connect plugin. This page explains the supported method, the configuration sequence and where integrations usually fail.

On this page

How APISIX validates Microsoft Entra ID tokens for APIs

APIs behind APISIX must accept Entra ID tokens from users and from services, and the supported method is the openid-connect plugin in bearer mode. In that mode the plugin reads the access token from the Authorization header and validates it on each request. By default it sends the token to the provider's introspection endpoint. Setting public_key or use_jwks switches the plugin to verifying the JWT signature locally against the signing keys, which skips introspection and keeps token checks off the request path.

Browser sign-in and API token validation are separate jobs. Browser login uses the authorization code flow with PKCE, where the gateway or application redirects a user to Entra ID, exchanges the code and maintains a session. A bearer-mode API route has no login redirect: a client, such as a single-page app, a mobile app or a backend service, already holds a token and the gateway only decides whether to forward the request. This page covers the API side. The browser login configuration, session handling and cookie settings belong to the browser sign-in work, and the service-to-service token acquisition is covered in the client credentials section.

Confirm with your team which validation path you need before you write route configuration. Introspection gives the provider's current view of a token but adds a dependency on the provider for every call, while local JWKS verification gives throughput and keeps working when the provider's endpoints are slow, at the cost of accepting a token until it expires unless you add revocation controls. Check the APISIX release you plan to run, since the openid-connect plugin's bearer validation behavior changed in recent releases, and read the openid-connect plugin documentation for the current option names and defaults.

What you need in place before configuring Entra ID with APISIX

Most delays in an Entra ID integration come from decisions made before anyone edits a route. Confirm the APISIX release, the Entra ID tenant rights, the network paths and the TLS and deployment mode first, because each one changes how the openid-connect plugin behaves at the gateway.

APISIX release to run

Confirm the APISIX version before writing plugin configuration. The 3.18.0 release made bearer introspection fail closed when the discovery document is unavailable and began enforcing audience, issuer and required scopes, and 3.19.0 rejects introspection responses whose iss does not match valid_issuers. Configuration that worked on an older release can fail closed after an upgrade, so test against the release you will run in production.

Entra ID tenant and admin rights

Confirm who can create app registrations, expose API scopes and grant admin consent in the tenant that issues your tokens. Ask your Entra ID administrators whether API and client registrations need a separate approval path, and whether the tenant is a single tenant or spans several directories, since the issuer value in the token depends on that choice.

Network paths to Microsoft endpoints

APISIX must reach the Microsoft discovery document and JWKS endpoints if you verify signatures locally, or the introspection endpoint if you do not. Check egress rules, proxy settings and DNS from every gateway node, including air-gapped or restricted zones. If the discovery document cannot be fetched, the 3.18.0 fail-closed behavior will reject bearer requests, so test this path before go-live.

TLS certificates and trust

Plan certificates for the public gateway hostname that clients call and the trust chain APISIX uses for outbound calls to the identity provider. Confirm who issues and rotates the certificates, where the private keys live, and whether an internal certificate authority must be added to the gateway trust store.

Deployment mode and etcd decision

Choose between traditional mode with etcd and standalone mode, which reads conf/apisix.yaml or conf/apisix.json and reloads on change. The choice determines how plugin configuration is versioned, promoted and rolled back, and whether the Admin API on port 9180 is available for the OIDC settings. Ask the platform team which path matches your change control process.

Configuring the openid-connect plugin for Entra ID in order

This sequence takes an API and its clients from Entra ID app registrations to a route in APISIX that accepts only tokens meant for that API. Each step closes with a check you can run before the next one starts.

  1. Register the API and client applications

    Your identity team creates two app registrations in Microsoft Entra ID: one for the API that the gateway protects, and one for each client application or service that calls it. Record the directory (tenant) ID, the API application (client) ID and the client secret or certificate for each client. The API registration defines the audience your tokens will carry, so name it clearly and keep it separate from client registrations. Done means both registrations appear in the tenant with their IDs recorded and no client secret is stored in a shared document. Confirm the exact portal navigation with Microsoft's current documentation, since menus change over time.

  2. Expose scopes on the API registration

    On the API registration, the identity team defines one or more delegated scopes or application roles that represent the permissions the API accepts, such as a read scope for orders. Grant the client registrations permission to request those scopes, and grant admin consent where your design requires it. Scopes are what the gateway later checks, so their names must match the values you will place in the required scopes setting. Check this step by requesting a token for a client and confirming the scope value appears in the token. If the scope is missing, the client registration was not granted the permission, so fix that before moving on.

  3. Set the discovery URL, issuer and audience values

    Using the tenant ID, the platform team builds the OpenID Connect discovery URL for the Entra ID tenant and reads the issuer value from that document. Decide on the audience value that your API will accept, usually the API application ID or its identifier URI as your tokens actually carry it, and write it down exactly. Confirm the issuer and audience formats by decoding a sample token rather than assuming them, because Entra ID v1 and v2 tokens differ in the iss and aud values they carry. Done means you have one discovery URL, one issuer and one audience value that all match a real token from the tenant. Confirm the plugin's expected settings in the openid-connect plugin documentation.

  4. Choose introspection or local JWKS verification

    Decide how APISIX validates bearer tokens. By default the openid-connect plugin calls the provider's introspection endpoint on each request, which adds a network round trip to Entra ID. Setting use_jwks (or public_key) makes APISIX verify the JWT signature locally, which avoids that call and suits high request volumes, but it depends on the gateway reaching the JWKS endpoint and refreshing keys. Record the decision and the reason, for example, whether the gateway can reach Microsoft's endpoints from your network zone. Done means one validation mode is chosen for each route group, and the team can explain what happens if the discovery document or key set is unavailable.

  5. Configure required scopes and valid issuers

    On the route's openid-connect configuration, set the audience check, the required scopes from step two, and valid_issuers containing the tenant issuer from step three. Recent APISIX releases enforce audience, issuer and required scopes, and reject introspection responses whose iss does not match valid_issuers, so check the release notes for the version you run. The gateway should refuse to start serving a route that has no issuer restriction in your design. Done means the configuration file or Admin API payload contains each value explicitly, and a review confirms that no value was copied from an unverified example.

  6. Attach the plugin to a route

    Apply the configured openid-connect plugin to the route that exposes the API, and keep the client credentials and secret out of the route document by referencing a secret store if your APISIX secrets design calls for it. Apply the change through the deployment method your team uses, whether the Admin API, standalone configuration file or ingress resources. Confirm the route is active and that requests without a token are rejected at the gateway, not forwarded to the upstream. Done means an unauthenticated call returns an authentication error and the upstream logs show no request.

  7. Test with decoded tokens and negative cases

    Acquire a token for a client using the client credentials flow, then decode it to confirm the aud, iss and scp (or roles) claims match the values configured in the previous steps. Call the route with that token and expect success. Then send a token issued for a different audience, a token from another tenant and a token missing a required scope, and confirm APISIX rejects each one. Record the results as your acceptance evidence. Done means the valid token passes and each invalid token is refused with a logged reason, so a failing test points to a specific setting.

Designing app registrations for APIs and clients

The API should have its own app registration in Microsoft Entra ID, separate from the registrations used by browsers, services and daemons that call it. The API registration defines the exposed scopes or app roles that clients must request, and those values become the authorization vocabulary APISIX checks through the scope or roles claims. Browser single-page apps, server-side web apps and background services each get their own client registration with permission to request the API's scopes. Keeping these roles apart lets you grant a service account application permissions without giving a browser user the same reach, and it lets you revoke one client without touching the others. Confirm in your tenant which of the two models (delegated scopes or application roles) each client type will use before you write the APISIX route configuration.

The audience value in each issued access token must match what APISIX checks. For an API registration, the aud claim is normally the application ID URI or the client ID, depending on how the API was registered and which token version is issued. Set the audience (or equivalent) setting in the openid-connect plugin to exactly the value Entra ID puts in the token, and set valid_issuers to the tenant issuer your tokens carry. A client that requests a token for the wrong resource gets a token whose audience names a different API. If APISIX validates audience and issuer strictly, the gateway rejects that token with an authorization error, which looks like a client bug but is a configuration mismatch. Test each client against a staging route before go-live, and record the expected aud and iss values in your runbook so a later tenant or registration change is easy to diagnose.

Mapping Entra ID claims to APISIX checks and consumer identity

This table maps each Microsoft Entra ID token claim to the APISIX check it drives, what that check protects against, and the identity signal the gateway can pass upstream. Read it as a checklist: every claim you rely on should have a matching check in your route configuration, and every forwarded header should be confirmed against the plugin documentation for your APISIX version before upstream services depend on it.

Entra ID claimAPISIX check or useWhat it protects against
iss (issuer)Match against valid_issuers using your tenant's issuer valueTokens minted by another tenant or a look-alike issuer being accepted at your gateway
aud (audience)Match against the API app registration identifier the route expectsA token issued for a different API being replayed against this one
scp or rolesRequired scopes or app roles checked against delegated or application permissionsAuthenticated callers reaching operations they were never granted
sub (subject)Identifies the signed-in user for delegated flows; record it for auditUnattributed requests and weak traceability in upstream logs
azp or appidIdentifies the calling client application; use to allow only approved clientsAny app in the tenant calling an API it was not built for
oid (object ID)Stable identifier for a user or service principal across apps; useful for consumer mappingRenamed or reused display names being mistaken for the same identity
Forwarded identity headersClaims passed upstream as headers; confirm exact header names in the openid-connect plugin docsUpstream services trusting client-supplied identity headers instead of verified claims

Choosing introspection or local JWKS verification

By default, the openid-connect plugin sends each bearer token to the identity provider's introspection endpoint and accepts the request only if the provider reports the token as active. When you set public_key or use_jwks, APISIX instead checks the JWT signature locally against the key material, and the introspection call is skipped. The two modes therefore differ in where the trust decision is made: at Microsoft's endpoint on every request, or inside the gateway using keys it fetched earlier.

  • Introspection by default: every protected request depends on a live call to the provider's introspection endpoint.
  • Local verification with `use_jwks`: the gateway fetches the signing keys and checks signatures itself, so the request path does not call Microsoft.
  • Local verification with `public_key`: a fixed key is pinned in configuration, which removes key discovery but makes key rotation a configuration change.
  • Claim checks apply in both modes: issuer, audience and required scope checks still run, so the choice affects signature and status checks, not claim validation.
  • Skipped introspection: a revoked token that still has a valid signature and lifetime will be accepted in local mode until it expires.

Before you choose, confirm the exact option names and supported token types for your APISIX version in the plugin documentation.

Handling client credentials for service-to-service calls

Service clients obtain tokens through the client credentials flow, where the calling application authenticates as itself with a client ID and a secret or certificate, and no user is involved. The APISIX openid-connect plugin supports the client credentials flow, so the gateway can accept these tokens on the same routes as user tokens. The design question is not whether the flow works but which identities each route should admit. Before go-live, confirm with your Entra ID administrator which app registrations act as service clients, which API scopes or app roles each one requests, and whether each route will check for them. Do not assume that a valid token from any registered application is acceptable.

At the gateway, a service token is validated the same way as a user token: signature, issuer, audience and expiry. The difference is what the token carries. A service token normally has no user identity, so claims such as the user's group membership do not apply, and the route policy has to rely on the scopes or app roles in the token. Treat each service identity as a consumer with its own allowed routes and scopes. Require a scope check on every route that accepts service tokens, and confirm that the check fails closed when the claim is missing. Test this with a token that is valid but carries the wrong scope, since that case is the most common gap.

Rotation of client secrets or certificates happens in Microsoft Entra ID and in the system that holds the credential, not inside APISIX. Ask your team to document who rotates each service credential, how often, and how the calling service picks up the new value without downtime. On the gateway side, confirm where the client secret used by the openid-connect plugin is stored, who can read it, and how it is changed without editing route configuration by hand. Also confirm how the gateway handles a token issued under an old credential after rotation. Your secret storage approach should be agreed before the first service goes live, because changing it later affects every calling service.

Security controls for Entra ID at the APISIX gateway

Entra ID tokens only protect an API if the gateway checks them strictly, fails safely and keeps its own configuration tight. The cards below pair each control with the risk it addresses, so you can verify each one in your environment before go-live.

Strict issuer and audience validation

Accept a token only when its issuer matches your tenant and its audience matches the app registration of the API it is calling. Without these checks, a token issued for another application in the same tenant, or from another issuer, can be replayed against your API. Configure the valid issuers and audience explicitly in the openid-connect plugin, and test with tokens minted for a different API to confirm they are rejected.

Required scopes per route

Authentication only proves who the caller is, not what they may do. Declare the scopes each route requires, so a valid token with only read permissions cannot reach write operations. Map each route to its scopes in a reviewed configuration file, and confirm that the gateway rejects a token missing a required scope with a clear denial rather than passing it upstream.

Fail-closed behavior

Decide in advance what the gateway does when the identity provider's discovery document or keys cannot be reached. A gateway that falls back to accepting traffic turns an identity outage into an authentication bypass. Confirm the APISIX version you run enforces fail-closed bearer introspection, and test by blocking access to the discovery endpoint from the gateway network.

Client secrets kept out of route config

The client secret used for the openid-connect plugin is a credential, and route configuration is often readable by many engineers and stored in etcd. Reference the secret from a secrets manager or environment variable instead of pasting it into a route. Check who can read the Admin API output and the etcd backups, and plan a rotation procedure that does not require editing every route.

TLS to Microsoft endpoints

The gateway fetches discovery documents, keys and token responses from Microsoft endpoints, and a misconfigured TLS verification step lets an attacker on the path substitute their own keys. Keep certificate verification enabled on upstream calls to the identity provider, trust the system CA bundle used by your gateway image, and confirm the outbound egress rules allow only the endpoints you have listed.

Restricted Admin API access

Anyone who can write to the Admin API can change which routes require authentication, or remove the plugin entirely. Bind the Admin API to a management network, require strong API keys that are not the default, and restrict which operators and pipelines can call it. Review access logs for changes to openid-connect settings, since an authentication change is one of the highest-impact edits the gateway accepts.

Logs that exclude raw tokens

Access logs and error logs can capture bearer tokens from headers, which turns a log store into a credential store. Limit logging to the subject, client identifier, issuer, audience and the decision, and make sure header fields such as Authorization are not written to logs or forwarded to third-party logging plugins. Test the logging path with a known token and search the output for it before relying on the log pipeline.

Common Entra ID validation failures and their causes

This table lists the failures teams most often hit when APISIX validates Microsoft Entra ID tokens, with the likely cause and fix for each. Read each row against your own tenant, since token version, issuer and scope claims depend on how your app registrations are configured.

FailureLikely causeFix and what to confirm
401 on every requestDiscovery document unreachable, or the plugin cannot fetch the Entra ID metadata. Since APISIX 3.18.0, bearer introspection fails closed when discovery is unavailable.Confirm the discovery URL resolves and is reachable from every gateway node, including egress rules and proxy settings. Check the gateway error log for the discovery fetch.
Audience mismatchThe token's aud claim does not match the audience configured in the plugin. Entra ID issues aud as the API's application ID URI or client ID, depending on how the API is registered and which token version is requested.Compare the aud value in a decoded test token with the configured audience. Confirm which identifier your API app registration exposes and align the plugin setting to it.
Issuer mismatch after tenant or v1 versus v2 token differencesThe iss claim differs by token version. v1 tokens use the sts.windows.net issuer form, while v2 tokens use the login.microsoftonline.com form with the tenant ID. Since APISIX 3.19.0, introspection responses whose iss does not match valid_issuers are rejected.Decode a token from each client and note its iss value. Set valid_issuers to match the token version your clients request, and confirm the accessTokenAcceptedVersion setting on the API app registration.
Missing scopes in scp or rolesThe required scope is absent from the token. Delegated tokens carry scp, while app-only tokens carry roles. Required scopes configured in the plugin may not match the claim that holds them.Confirm which claim your token type uses. Check that the client was granted the scope or app role and that admin consent was given. Match the required scope names exactly, including case.
Discovery endpoint unreachableNetwork path from the gateway to the Entra ID login endpoint is blocked, DNS fails inside the cluster, or an outbound proxy is not configured for the plugin.Test connectivity from a gateway pod or host with the same network policy. Confirm DNS resolution and proxy settings. Ask your network team to confirm outbound rules for the Microsoft login endpoints in your environment.
Stale JWKS keysSigning keys rotated at Entra ID, but the gateway still uses a cached key set, or the local public_key was pinned to an old key. Local verification then rejects valid tokens.Prefer use_jwks so the plugin refreshes keys from the metadata. Where a static public_key is set, plan a rotation step and confirm the current key with Microsoft's documentation for your tenant before cutover.
Token accepted in tests but rejected in productionTest tokens came from a different tenant, client or token version than production clients use, or production clients use a different audience.Validate with tokens issued by the same app registrations and tenant that production clients use. Record iss, aud, scp or roles and exp for each client type during staging.

Questions teams ask before connecting Entra ID to APISIX

How much effort does connecting Entra ID to APISIX take?

The effort depends mainly on tenant complexity, the number of APIs and clients, and the validation mode you choose. A single API with one client and a clear app registration is a small task. Multiple APIs, several client types, multiple tenants or guest users add work in app registration design, scope mapping and test cases. Validation mode matters too: the openid-connect plugin validates bearer tokens through the provider's introspection endpoint by default, while setting public_key or use_jwks verifies JWT signatures locally and skips introspection. Local verification adds work to confirm key sources, issuer and audience values and rotation handling, but it avoids a network call on each request. Ask any partner to break its quote down by these drivers.

Can an internal team connect Entra ID to APISIX without outside help?

Yes, a team with gateway, identity and cloud skills can do this in-house, provided it has time to learn the plugin's configuration and to test the failure paths. The work spans three areas: Entra ID app registrations, APISIX route and plugin configuration, and test coverage for valid, expired, wrong-audience and wrong-issuer tokens. Teams without someone who has run openid-connect in production often find the discovery, JWKS and introspection behavior takes longer to verify than to configure. A fixed-scope engagement can cover the parts your team has not done before, and you keep the written deliverables for later changes.

What do Entra ID admins and network owners need to provide?

Plan for at least three kinds of input before build work starts:

  • Entra ID administrators to create or review app registrations for each API and client, define application roles or scopes, and confirm which tenant or tenants issue tokens.
  • Network owners to confirm that APISIX can reach the Entra ID discovery document and JWKS endpoints, or the introspection endpoint if you use it, through egress rules, proxies or firewall policy.
  • Security and platform owners to approve how secrets for client credentials are stored and rotated, and where TLS certificates for the gateway come from.

Agree on who signs off on each item and on the change process for Entra ID settings, since a changed audience or scope can break clients without any gateway change.

How long does testing take for an Entra ID integration?

Testing time depends on how many APIs, clients and token types you must cover, not on a fixed number of days. Plan test cases for each route: a valid user token, a token with the wrong audience, a token from an unexpected issuer, an expired token, a token missing a required scope and a client credentials token from a service principal. Add tests for the failure mode you chose, including what happens when the discovery document is unavailable. APISIX 3.18.0 made bearer introspection fail closed when discovery is unavailable, and 3.19.0 rejects introspection responses whose iss does not match valid_issuers, so confirm the version you run and test those behaviors directly. Ask for the test matrix in writing before accepting a timeline.

What does a fixed-scope engagement for this integration cover?

A fixed-scope engagement covers the agreed list of APIs, clients, routes and validation modes, with deliverables and timelines confirmed in writing before work starts. For this integration, expect the agreed scope to include the app registration design, the APISIX route and plugin configuration for each protected API, issuer, audience and scope checks, the validation mode, client credentials flow for services where needed, the test matrix, and operating notes for key rotation and configuration changes. It does not automatically include unrelated identity work, such as changes to the wider Entra ID tenant or application code changes in the APIs themselves. Ask for the exclusions list alongside the inclusions.

What recurring work follows after the integration goes live?

Recurring work is mostly operational. Entra ID signing keys rotate, so the JWKS source must be reachable and cached correctly if you verify tokens locally. APISIX releases change plugin behavior, so each upgrade needs a regression run of your token test matrix. New APIs or clients need app registrations, route entries and tests. Some teams buy ongoing support or a retainer for these tasks, while others assign them to an internal owner. Ask any partner which of these tasks is covered by the fixed-scope work and which needs a separate agreement.

Does DeployOpen handle the Entra ID tenant itself?

DeployOpen works with your Entra ID administrators on the app registrations, permissions and scopes that the gateway depends on, but the tenant remains under your control. DeployOpen implements, configures and documents the APISIX side, including the openid-connect plugin, route configuration and test evidence, inside your own infrastructure. Changes to tenant-wide policy, conditional access or user lifecycle are owned by your identity team. Confirm the split of responsibilities in the written scope before work starts.

How DeployOpen scopes and delivers the Entra ID integration

DeployOpen plans and implements Apache APISIX as a self-hosted gateway in infrastructure you control, including OpenID Connect validation against Microsoft Entra ID. Each engagement starts from a written scope covering your app registrations, token checks and route policies, so your team knows what is delivered before work begins.

How we scope

  • We map which APIs, clients and service accounts will call the gateway and which Entra ID tenants they belong to.
  • We agree in writing how issuer, audience and required scope checks apply to each protected route.
  • We confirm whether tokens are checked by introspection or by local JWKS verification, and record the reason for that choice.

How we build

  • We configure the openid-connect plugin on test routes, with discovery, issuer and audience settings matched to your app registrations.
  • We test valid, expired, wrong-audience and missing-scope tokens against each route before any traffic moves.
  • We set up client credentials paths for services and confirm the APISIX version pinned for the build includes the fail-closed behavior you need.

How we hand over

  • You receive the route and plugin configuration, app registration settings and a record of the verification test results.
  • We document the runbook for rotating client secrets, updating JWKS sources and adding new APIs under the same policy.
  • Handover sessions walk your identity and platform engineers through the configuration so they can operate it without us.

How we support

  • Engagements are fixed-scope, and ongoing support, upgrades and continuous testing are available as a retainer.
  • Retainers can cover reviewing APISIX release notes that affect token validation before you upgrade a gateway.
  • Ask any provider to confirm how changes to Entra ID tenants, certificates or APISIX versions are handled in the quote.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.