Skip to main content
Version: 2.12




The forward-auth plugin implements a classic external authentication model. We can implement a custom error return or user redirection to the authentication page if the authentication fails.

Forward Auth cleverly moves the authentication and authorization logic to a dedicated external service, where the gateway forwards the user's request to the authentication service and blocks the original request, and replaces the result when the authentication service responds with a non-2xx status.


uristringrequiredAuthorization service uri (eg. https://localhost/auth)
ssl_verifybooleanoptionaltrueWhether to verify the certificate
request_headersarray[string]optionalclient request header that will be sent to the authorization service. When it is not set, no client request headers are sent to the authorization service, except for those provided by APISIX (X-Forwarded-XXX).
upstream_headersarray[string]optionalauthorization service response header that will be sent to the upstream. When it is not set, will not forward the authorization service response header to the upstream.
client_headersarray[string]optionalauthorization response header that will be sent to the client when authorize failure. When it is not set, will not forward the authorization service response header to the client.
timeoutintegeroptional3000ms[1, 60000]msAuthorization service HTTP call timeout
keepalivebooleanoptionaltrueHTTP keepalive
keepalive_timeoutintegeroptional60000ms[1000, ...]mskeepalive idle timeout
keepalive_poolintegeroptional5[1, ...]msConnection pool limit

Data Definition#

The request headers in the following list will have APISIX generated and sent to the authorization service.

SchemeHTTP MethodHostURISource IP


First, you need to setup an external authorization service. Here is an example of using Apache APISIX's serverless plugin to mock.

$ curl -X PUT '' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-H 'Content-Type: application/json' \
-d '{
"uri": "/auth",
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions": [
"return function (conf, ctx)
local core = require(\"apisix.core\");
local authorization = core.request.header(ctx, \"Authorization\");
if authorization == \"123\" then
elseif authorization == \"321\" then
core.response.set_header(\"X-User-ID\", \"i-am-user\");
else core.response.set_header(\"Location\", \"\");

Next, we create a route for testing.

$ curl -X PUT
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
-d '{
"uri": "/headers",
"plugins": {
"forward-auth": {
"uri": "",
"request_headers": ["Authorization"],
"upstream_headers": ["X-User-ID"],
"client_headers": ["Location"]
"upstream": {
"nodes": {
"": 1
"type": "roundrobin"

We can perform the following three tests.

  1. request_headers Send Authorization header from client to authorization service
$ curl -H 'Authorization: 123'
"headers": {
"Authorization": "123",
"Next": "More-headers"
  1. upstream_headers Send authorization service response header to the upstream
$ curl -H 'Authorization: 321'
"headers": {
"Authorization": "321",
"X-User-ID": "i-am-user",
"Next": "More-headers"
  1. client_headers Send authorization service response header to client when authorizing failed
$ curl -i
HTTP/1.1 403 Forbidden

Finally, you can disable the forward-auth plugin by removing it from the route.