Apache APISIX and Keycloak authorization

Connect Keycloak Authorization Services to Apache APISIX so routes enforce resource and scope policies after openid-connect login. This page covers the setup sequence, identity mapping, failure points and what the work needs from your team.

On this page

How Keycloak authorization services work behind Apache APISIX

If your users already sign in through Keycloak, the next question is usually not who the user is but what they may do on a given route. The authz-keycloak plugin answers that at the gateway by sending each request's resource and scope to Keycloak Authorization Services, which evaluates the policies you defined in the realm and returns a grant or a denial. The openid-connect plugin handles a different job: it runs the browser login or validates the bearer token and gives APISIX the identity context. Treat these as two layers. Login establishes who the caller is, and the authorization check decides what that caller can reach. The authz-keycloak plugin is the supported method for this topic, so your design should assume Keycloak resources, scopes and policies are the source of truth for API decisions.

Before building anything, confirm the exact configuration keys and runtime behavior in the authz-keycloak plugin documentation for the APISIX version you will run. The APISIX 3.19.0 release is dated September 28, 2026, and plugin option names, token handling and how denials are returned can change between versions, so do not copy settings from older examples. Ask your implementation team to record the APISIX version, the Keycloak version and the plugin page version in your design document, and to test each of them together in a non-production environment. Pin the Keycloak release you have validated, since Keycloak minor releases can change behavior even when the project keeps breaking changes opt-in.

The main design decisions sit in the Keycloak model, not in APISIX. Decide which resources map to routes or API operations, which scopes describe actions such as read or approve, and which policies (roles, groups, client or user rules) grant them. Keep the resource count manageable, because every additional resource is one more thing to test and audit. Decide also whether the gateway should enforce decisions or only observe them during rollout, and confirm how the plugin's enforcing and permissive modes behave in your version before relying on either. Finally, confirm where the Keycloak evaluation endpoint sits relative to the gateway, since its latency and availability become part of every protected request.

What you need before wiring Keycloak policies to APISIX routes

Fine-grained authorization with Keycloak behind APISIX depends on five pieces being in place before any policy is written. Each card below is a prerequisite that the later configuration relies on, and each names the check to complete first.

A running APISIX deployment

Run APISIX in traditional or decoupled mode, so the Admin API is available on port 9180 for operators while client traffic uses port 9080. Confirm that operators can reach the Admin API from a management network only, and that the etcd cluster behind it is healthy. The authz-keycloak plugin is configured through routes, so route changes must be possible without a restart. Confirm the APISIX version you run against the plugin's documented compatibility.

A Keycloak server on a supported database

Run Keycloak 26.8.1, published October 13, 2026, with a production database from Keycloak's supported list, such as PostgreSQL 14 to 18. The default development file database is not suitable here. Check that the server is configured for production and that the database replication design matches the high availability model you chose, since both supported multi-node designs need a synchronously replicated database.

A realm with an authorization-enabled client

Create a dedicated realm for the APIs and a confidential client for the gateway. Turn on Authorization on that client so that resources, scopes and policies can be defined in Keycloak Authorization Services. Keep browser login clients separate from the gateway client, so that the client secret and authorization settings are not shared. Record the realm issuer URL and client ID, since the plugin configuration needs both exactly as Keycloak reports them.

A decided route inventory

Before writing any policy, list every APISIX route that needs protection, its HTTP methods, its upstream, and the Keycloak resource that will represent it. Mark which routes need only authentication and which need a scope or permission check. An illustrative inventory might map GET /orders and POST /orders to one resource with separate scopes. Routes without a decided owner tend to be left in permissive mode by mistake, so settle this list first.

Certificates for every hop

Plan TLS certificates for three connections: client to gateway, gateway to Keycloak, and gateway to upstream services. Decide which certificate authority issues them, how trust is distributed to the APISIX nodes, and who renews them. Keycloak's token and policy endpoints must be reached over verified HTTPS, so a self-signed or expired certificate on the Keycloak side will break every authorization decision. Confirm the trust store configuration with your security team before testing.

A version compatibility check

Before configuration, confirm the APISIX release and the Keycloak release you run against the plugin's documented compatibility and the Keycloak release notes. Keycloak minor releases can include breaking changes that are opt-in, so pin versions and review the upgrading guide for each target. Record the chosen versions in your change record so that a later upgrade of either product is tested against the same authorization flow.

Choosing enforcing or permissive mode for each route

A route that already serves traffic is the riskiest place to switch straight to enforcement. Any caller whose token lacks the required scope or permission will begin receiving denials at once. Start in permissive mode so the gateway records what would have been denied without blocking anyone, then decide when the evidence supports enforcement.

  • Inventory the callers first: list the client IDs, service accounts and user groups that reached the route during a representative period, using access logs and Keycloak event records.
  • Collect would-be denials: record the request path, method, client ID, requested scope and the policy that failed, and group them by consumer.
  • Close the gaps in Keycloak: grant missing scopes or assign permissions to clients that legitimately need them before the switch.
  • Agree an exit condition in writing: define what counts as clean, such as no unexplained would-be denials across a window the API owner and security owner choose.

Sign-off usually rests with the API owner and the security owner, with the platform team carrying out the change under a recorded change request. Confirm the permissive option name and what it logs in the authz-keycloak plugin documentation before you depend on it.

How to configure Keycloak resources, scopes and policies for APISIX

This sequence takes a Keycloak realm from a confidential gateway client to fine-grained API permissions enforced by the authz-keycloak plugin in APISIX. Each step ends with a check so the team can confirm the layer works before moving to the next one.

  1. Create the realm and gateway client

    The Keycloak administrator creates or confirms a realm for the APIs, then creates a confidential OpenID Connect client that APISIX will use to talk to Keycloak. Set the client authentication option so Keycloak issues a client secret, and record the redirect URI for any browser login route. Store the secret in your secrets manager rather than in plain route configuration. The step is done when the client shows a client secret under its credentials tab and a token request from the gateway host returns a valid token for a test user. The exact screens are described in the Keycloak server administration guide, and the client keys used by APISIX are listed in the APISIX openid-connect plugin documentation.

  2. Enable authorization on the client

    On the same client, the administrator turns on Authorization so Keycloak creates the Authorization tab with resources, scopes, policies and permissions. Enabling it changes how the client's tokens can carry permission data, so confirm this is done on the client the gateway uses and not on a client shared with unrelated applications. The check is that the Authorization tab opens and shows a default resource and default policy. The Keycloak server administration guide covers the Authorization settings screen for the version you run.

  3. Define resources and scopes for the APIs

    The API owner lists each protected resource as a Keycloak resource, using route paths or a named group of routes that match how APISIX is configured. Then the owner defines scopes for the actions that matter, typically read, write and admin, and attaches the scopes to each resource. Keep the resource names aligned with the APISIX route names so that logs and policy reviews can be traced to the same object. The check is a resource list in which every production route has at least one resource and each resource lists the scopes it accepts.

  4. Create policies and combine them into permissions

    The administrator creates policies based on realm roles, client roles, groups or specific users, depending on how your identity model is organized. Each policy is then referenced by a permission that links a resource and scope set to the policy that is allowed to use them. Keep the number of policies small and name them after business roles so that reviewers can read the rules. The check is the Evaluate tab in the client's Authorization section: a test user with the expected role should receive a grant for the intended scope and a denial for a scope they should not hold.

  5. Configure openid-connect for browser and bearer flows

    On the APISIX route, the engineer configures the openid-connect plugin with the realm discovery URL, the client identifier and the client secret reference. Browser routes use the authorization code flow with PKCE, while API clients that already hold a token use bearer validation through introspection or the JWKS endpoint, as set by the plugin's options. Confirm the discovery URL, the issuer and the audience values against the realm before saving. The check is that an unauthenticated request to a protected route is redirected or rejected as expected, and that a request with a valid token reaches the upstream. The exact keys for each flow are in the openid-connect plugin documentation.

  6. Add authz-keycloak in permissive mode

    The engineer adds the authz-keycloak plugin to the selected routes with permissive mode enabled, so the gateway calls Keycloak for decisions and logs the result but still forwards requests. This lets the team see which requests would be denied without breaking traffic. The plugin reads the same client identifier and secret as the openid-connect configuration, so keep them consistent. The check is that the gateway logs contain permission decisions for test requests and the upstream still receives every request that the team expects to pass.

  7. Test with tokens for each role

    The QA or security engineer obtains tokens for a test user in each role, including a user with no role, and sends requests to every route and method in the permissive configuration. The team compares the logged decisions with the intended matrix of roles, resources and scopes and records any mismatch as a policy defect. Repeat the tests after each policy change. The check is a signed-off matrix in which every role and route combination matches the expected allow or deny result. Keep the test users and their roles documented so the same tests can be rerun during upgrades.

  8. Switch selected routes to enforcing mode

    After the matrix passes, the engineer changes the authz-keycloak setting on selected routes from permissive to enforcing, starting with lower-risk routes and then the higher-risk ones. Denied requests should now return an error at the gateway instead of reaching the upstream, so the rollout should be scheduled with the application owners and a rollback path ready. The check is that the test matrix still passes with enforcing mode on, and the gateway logs show denials only for requests the matrix expected to fail. Confirm the exact enforcing option name and its behavior in the current authz-keycloak plugin documentation before the change.

How Keycloak resources, scopes and roles map to APISIX routes

This table shows one way to line up APISIX routes with Keycloak resources, scopes, policies and the token claims each decision reads. Use it as a starting point, then write your own mapping before the build begins so that every route has a named owner, a resource and an expected token shape. The main takeaway is that most authorization failures come from mismatched names and claims, not from the gateway itself.

APISIX route or pathKeycloak resourceScope and policy typeToken claim or role the decision reads
Route /orders/* (illustrative)Resource named orders, one resource per business objectRole-based policy on the orders scopesrealm_access.roles or resource_access roles for the client
GET and HEAD on /orders/{id}orders resourceScope orders:readscope claim in the access token
POST, PUT and PATCH on /orders/{id}orders resourceScope orders:writescope claim in the access token
DELETE on /orders/{id}orders resourceScope orders:delete with a narrower role policyRole claim from the client's resource_access block
Route /reports/* shared by two teamsreports resource with two named scopesGroup-based policy per teamgroups claim, if the group mapper is enabled in the client
Routes that call a downstream serviceService-account client, not a user resourceClient credentials grant with a scope limited to the serviceazp or client_id claim and the scope claim
Any route accepting the tokenResource server client ID as the expected audienceAudience check before policy evaluationaud claim must include the API client ID (confirm in your Keycloak version)
Admin or internal pathsSeparate resource with its own ownerDeny by default unless a policy matchesRole claim plus source network or client, confirmed with your security team

How the openid-connect login and the authorization check fit together

Authentication and authorization are separate decisions, and this section matters because a gateway can get the first right while the second is never configured. The openid-connect plugin answers who the caller is. Browser users go through the authorization code flow with PKCE, which ends with APISIX holding a session for the user. Services and machine clients typically send a bearer token, which APISIX validates, or they obtain tokens through the client credentials grant. Token introspection asks the identity provider whether a presented token is still active, which matters when you need revocation to take effect quickly. None of these steps tells APISIX whether this particular user may call this particular route with this HTTP method.

The authorization check is a second decision made after authentication succeeds. With authz-keycloak, APISIX sends the request to Keycloak Authorization Services, where resources, scopes and policies are evaluated against the token. A token that is valid, unexpired and issued by the right realm can still be denied for a route because no permission grants the requested scope to that client or user. This is the most common surprise during rollout, so test a denied case for every protected route, not only a successful login. Confirm in the plugin documentation which token and permission fields your APISIX version forwards to Keycloak before you write the resource definitions.

Plan the two layers together. Decide which clients use authorization code with PKCE, which use client credentials, and which accept bearer tokens from other systems, then map each client to the scopes and resources it needs. Keep token lifetimes and introspection settings under review with your identity team, since those values control how long a revoked permission can still be honored. Ask DeployOpen or your own engineers to write one allow case and one deny case per route in your test plan before enforcement is switched on.

Hardening token handling and the Keycloak administration path

The APISIX and Keycloak pairing puts two administrative surfaces and a stream of tokens on the same request path. The cards below cover the settings that connect them: where client secrets live, who can change authorization policy, how tokens expire and get revoked, and what evidence you keep. Confirm each setting against the Keycloak production and metrics documentation and your own APISIX configuration before go-live.

Client secrets and where they live

The openid-connect and authz-keycloak plugins need a client ID and secret for each Keycloak client. Treat that secret as credential material: keep it out of route definitions that are copied into tickets, repositories or shared dashboards. Confirm with the APISIX documentation exactly where the plugin stores the secret in etcd or the standalone file, whether it is encrypted at rest, and whether a secret reference from an external store is supported in your APISIX version. Rotate the secret in Keycloak and in the gateway together.

Limiting who edits authorization policy

Resource, scope and policy changes in Keycloak alter who can call which API, so they carry the same weight as a firewall change. Restrict realm administration to a small named group, use separate realms or clients for production and non-production, and require a reviewed change for every permission edit. Keep the authorization model in version-controlled exports where your process allows it, so a reviewer can see what changed and when.

Restricting the Admin API and console

The APISIX Admin API on port 9180 in traditional mode changes routes and plugin settings, including authorization rules, so it must not be reachable from client networks. Keep it on an internal interface, protected by an admin key you rotate. Apply the same discipline to the Keycloak admin console: place it behind a separate network path or access proxy, restrict it to administrator addresses, and confirm the production hostname settings in Keycloak before go-live.

TLS on every hop

Tokens travel from the browser to APISIX, from APISIX to Keycloak for discovery, introspection or token exchange, and from APISIX to upstream services. Each hop needs TLS with certificate validation enabled, including the connection from the gateway to the Keycloak token and JWKS endpoints. Confirm how the plugin verifies certificates for backchannel calls, and whether your internal certificate authority is trusted by the gateway process. Plain HTTP on any hop can expose bearer tokens.

Short token lifetimes and revocation

Access tokens are the credential the gateway accepts, so their lifetime sets how long a revoked user or changed permission stays effective. Choose access token lifetimes that match your risk, keep refresh tokens shorter for sensitive APIs, and test how a disabled user or removed role takes effect at the gateway. Introspection checks against Keycloak reflect revocation sooner than local JWT verification, at the cost of a call per request. Document the expected delay so application owners know what to expect.

Audit logging of permission decisions

Authorization decisions made at the gateway need evidence: which principal, which route, which scope, and whether the request was allowed or denied. Enable access logging in APISIX with the fields you need, and confirm which of the authorization outcomes the plugin records and at what level. Also keep Keycloak admin and login events, so you can tie a permission change to the person who made it. Make sure logs do not capture full tokens or client secrets.

Keycloak metrics for monitoring

Keycloak exposes metrics that show login volume, token activity and health, which help you spot failed logins, unusual token issuance or an unhealthy node before users report it. Decide which metrics to scrape, enable the endpoint only on an internal network, and set alerts for sustained error rates and unavailability of the token endpoint. A gateway that cannot reach Keycloak will deny or fail requests, so monitor that dependency directly.

Failures to expect: unexpected 403s, stale permissions and token problems

This table pairs each failure you are likely to meet with its usual cause and the check your team should run first. Read it as a triage list: match the symptom you see, confirm the cause with the named check, then apply the fix. Most failures trace back to the token contents, the policy evaluation path, or the gateway's ability to reach Keycloak.

SymptomLikely causeCheck and fix
Every request is denied with 403 after enabling enforcementEnforcement mode is on before the resource, scope and policy mappings match the routes in useSwitch the route back to permissive mode, then compare each route's resource and scope names in Keycloak with the names the plugin sends. Correct the mismatch, re-test with a known token, and only then re-enable enforcement.
Permissions do not change after a Keycloak policy editThe gateway is working from a cached decision or a token issued before the changeConfirm the change in the Keycloak admin console, then request a new token and test again. Short token lifetimes and the time the decision is cached determine how long the old result persists, so record both values before go-live.
Token lacks expected roles or scopesA protocol mapper is missing, or the client scope that carries the claim is not assigned to the clientDecode a sample access token and check the claims the policy reads. Add or fix the mapper, confirm the client scope is a default or requested scope, and check that the audience value matches the client the gateway expects.
Token rejected as not yet valid or expired immediately after issueClock skew between the Keycloak host, the APISIX nodes and the clientCompare system time on all three with NTP status. Correct time synchronization on the hosts first. Do not widen the accepted skew in the gateway until the clocks are confirmed to agree.
Gateway returns 500 or times out on authorization or token requestsAPISIX cannot reach the Keycloak discovery document or token endpoint, often because of DNS, TLS trust or egress rulesFrom a APISIX node, fetch the realm's OpenID configuration URL and confirm the issuer and endpoint values match what the plugin is set to. Check the CA certificate used for TLS and the network path, then retest.
Behavior changes after a Keycloak upgradeA minor or major release changed defaults, deprecated a setting, or altered schema migration or token behaviorRead the release notes and backwards compatibility guidance for the target version before upgrading. Run the authorization test suite against a staging realm restored from production, and keep the operator in manual approval mode so upgrades are scheduled.

What does Apache APISIX Keycloak authorization take, and can our team do it alone?

What actually drives the effort of an APISIX and Keycloak authorization project?

The effort follows the number of routes, resources, scopes and policies that need protecting, along with how the existing Keycloak realm is designed. Each route that carries a distinct permission model adds mapping work, and each resource needs a clear owner and a defined set of scopes. Token claim mapping matters because APISIX decisions depend on what Keycloak puts in the token. Testing depth is the last major driver: a small set of allow and deny cases differs greatly from a full matrix of identities, roles and routes run in both enforcing and permissive modes. Ask any provider to break its quote down along these four drivers so you can see which ones you control.

What costs are one-time and what recurs after go-live?

The one-time work covers discovery, the route inventory, Keycloak resource and policy design, the APISIX configuration, test cases and the cutover from permissive to enforcing mode. Recurring work is policy maintenance as new APIs and roles appear, plus upgrades. APISIX releases and Keycloak releases both need regression testing against your authorization rules. Keycloak plans four minor releases a year, and its Operator documentation strongly recommends manual approval for operator updates, so budget for a review step each time. Ask the provider whether ongoing support is quoted separately as a retainer or included in the fixed scope.

What does our team need to provide before the work starts?

Four inputs make the engagement workable. First, named owners for the APIs, the Keycloak realm and the APISIX gateway, with authority to approve policy decisions. Second, a route inventory listing each upstream, its methods, its current authentication and the business meaning of its resources. Third, test identities covering each role and group that should reach or be denied each route, in non-production realms. Fourth, a change window for the switch from permissive to enforcing mode, with a rollback plan. Missing any of these usually pushes work into discovery and extends the timeline, so confirm them before the quote is finalized.

Can our internal team set up APISIX and Keycloak authorization without outside help?

Yes, if the team already has working knowledge of both products and enough time to run the process properly. The skills needed include Keycloak realms, clients, scopes and authorization services, APISIX routes and plugin configuration, and OpenID Connect token behavior. The most commonly underestimated work is evidence gathering in permissive mode, where requests are logged and evaluated without being blocked so the team can see what enforcement would change. Internal teams often find that this phase, plus the test matrix, takes more calendar time than the configuration itself. A partner can cover part of this work or work alongside your team, depending on the scope agreed in writing.

How long does an APISIX and Keycloak authorization project take?

The duration depends on the scope, and no fixed timeline applies to every organization. A project with a few routes and an existing, well-structured Keycloak realm will move far faster than one covering dozens of APIs with overlapping roles and legacy clients. Schedule risk usually sits in realm design decisions, claim mapping and the permissive-mode review. DeployOpen works from a written scope with agreed deliverables and timelines, so the duration is stated in the quote once the route inventory and realm details are known. Ask for the phases, the dependencies on your teams and the review points in any proposal you receive.

Does DeployOpen issue audit reports for our authorization controls?

No. DeployOpen does not issue audit reports, attestations or certifications. It prepares systems, controls and evidence so that independent auditors and certification bodies can assess them. For authorization, that evidence can include the documented resource and policy model, the test cases and their results, the permissive-mode review records, change approvals and the configuration as it stands at go-live. Your assessor decides what is sufficient for the framework in scope. Agree early with your auditor on which evidence they expect, so the project records it from the start.

Which parts of the work do we need to confirm with the vendors themselves?

Several details depend on the exact versions in your environment, so confirm them rather than assume them. Check that your APISIX version supports the authz-keycloak plugin behavior you plan to use, and review its upgrade notes for any changes in the release you run. Confirm your Keycloak version, its supported database and your high availability design, since those affect how token and policy data is served. Also confirm how your Keycloak Operator update approval is set up. The upstream project documentation and your Red Hat or vendor support terms are the right places to check these points before design begins.

How DeployOpen scopes, delivers and supports this integration

DeployOpen plans and implements Apache APISIX and Keycloak authorization inside your own infrastructure, with the scope agreed in writing before work starts. We build the route, token and policy design together with your identity and platform teams, then hand over documented configuration, tests and runbooks.

How we scope

  • Inventory the APIs, routes and upstreams that need fine-grained authorization at the gateway.
  • Map Keycloak realms, clients, resources, scopes and policies to the access model your teams already use.
  • Agree in writing whether APISIX runs in enforcing or permissive mode during each rollout phase.

How we build

  • Configure openid-connect login for browser-facing apps and token checks for API callers.
  • Wire the authz-keycloak plugin to Keycloak resource and scope policies, then test allow and deny paths per route.
  • Store client secrets and Keycloak endpoints through your chosen secret handling, not in plain route configuration.

How we hand over

  • Deliver the APISIX configuration, Keycloak authorization model and an allow and deny test matrix.
  • Document token grant types, scope names and the procedure for adding a new protected resource.
  • Walk your platform and identity teams through the runbook for changes, rollback and permissive-mode exits.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers, scoped separately from the build.
  • Revisit policies when APISIX or Keycloak releases change plugin behavior or Keycloak upgrade procedures.
  • Confirm support terms, response expectations and included upgrade work with the written proposal before signing.

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.