acl
The acl plugin allows or denies request access to upstream resources by verifying whether the user initiating the request is in the access control lists.
Examples
The examples below demonstrate how you can use the acl plugin for different scenarios.
Control Access by Examining Consumer Labels
The following example demonstrates how to control consumer access based on consumer labels, upon a successful authentication.
- Admin API
- ADC
- Ingress Controller
Create two consumers, john and jane, each with their own labels for organizations and projects:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "john",
"labels": {
"org": "[\"opensource\",\"apache\"]",
"project": "[\"tomcat\",\"web-server\",\"http,server\"]"
}
}'
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "jane",
"labels": {
"org": "apache",
"project": "gateway,apisix,web-server"
}
}'
Create key-auth credentials for john and jane:
curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-john-key-auth",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'
curl "http://127.0.0.1:9180/apisix/admin/consumers/jane/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jane-key-auth",
"plugins": {
"key-auth": {
"key": "jane-key"
}
}
}'
Consumer labels can be configured with either of the two approaches:
- comma-separated string value, such as
{"project": "gateway,apisix"} - character escaped string array,such as
{"project": "[\"gateway\",\"apisix\"]"}
Create a route with key-auth enabled, and configure the acl plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "acl-route",
"uri": "/get",
"plugins": {
"key-auth": {},
"acl": {
"allow_labels": {
"org": ["opensource"]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
❶ Allow only consumers with org label value opensource to access the upstream resource.
Create two consumers, john and jane, each with their own labels, credentials, and a route with key-auth and acl plugins configured:
consumers:
- username: john
labels:
org: "[\"opensource\",\"apache\"]"
project: "[\"tomcat\",\"web-server\",\"http,server\"]"
credentials:
- name: cred-john-key-auth
type: key-auth
config:
key: john-key
- username: jane
labels:
org: "apache"
project: "gateway,apisix,web-server"
credentials:
- name: cred-jane-key-auth
type: key-auth
config:
key: jane-key
services:
- name: acl-service
routes:
- name: acl-route
uris:
- /get
plugins:
key-auth: {}
acl:
allow_labels:
org:
- opensource
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
❶ Consumer labels can be configured with either of the two approaches: comma-separated string value, such as "apache", or character escaped string array, such as "[\"opensource\",\"apache\"]".
❷ Allow only consumers with org label value opensource to access the upstream resource.
Synchronize the configuration to the gateway:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
Ingress Controller currently does not support configuring consumer labels.
Ingress Controller currently does not support configuring consumer labels.
Send a request to the route as consumer jane:
curl -i "http://127.0.0.1:9080/get" -H 'apikey: jane-key'
You should see an HTTP/1.1 403 Forbidden response, as consumer jane was not configured with the required label to access the route.
Send a request to the route as consumer john:
curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key'
You should see an HTTP/1.1 200 OK response, as consumer john was configured with the required label to access the route.
Control Access by Examining User Information from External Identity Provider
The following example demonstrates how to control user access based on user labels, upon a successful authentication with an external identity provider. Specifically, the example uses Keycloak and user groups as labels.
Follow the steps in set up SSO with Keycloak how-to guide to create a realm, a client, and a user.
Go to Groups and create two new groups, apisix and opensource:

To add the user to group memberships, click into the user and go to the Groups tab. Select each group in turn and click join:

To include the group membership when user info is requested from Keycloak, go to the client and go to the Mappers tab. Create a new mapper:

Fill in the name for the protocol mapper, select Group Membership as the mapper type, use groups as the token claim name, and click Save:

To verify if the attribute will be visible when requesting user info, first obtain an access token from Keycloak:
OIDC_USER=quickstart-user
OIDC_PASSWORD=quickstart-user-pass
OIDC_CLIENT_ID=apisix-quickstart-client
OIDC_CLIENT_SECRET=bi9NFscFT4k0ljaRzQWlJWthrlygUn3x # replace with your client secret
curl "http://$KEYCLOAK_IP:8080/realms/quickstart-realm/protocol/openid-connect/token" -X POST \
-d 'grant_type=password' \
-d 'client_id='$OIDC_CLIENT_ID'' \
-d 'client_secret='$OIDC_CLIENT_SECRET'' \
-d 'username='$OIDC_USER'' \
-d 'password='$OIDC_PASSWORD''
Save the access token to an environment variable called ACCESS_TOKEN and send a request to the Keycloak user info endpoint with the token:
curl "http://$KEYCLOAK_IP:8080/realms/quickstart-realm/protocol/openid-connect/userinfo" -H "Authorization: Bearer $ACCESS_TOKEN"
You should see a response similar to the following:
{
"sub":"4310e97c-d4c3-479b-bbbd-8c66120e6cee",
"email_verified":false,
"groups":["/apisix", "/opensource"],
"preferred_username":"quickstart-user"
}
Suppose you would like to only allow users with /apisix value in the groups attribute to access upstream resources.
Create a route with openid-connect and acl plugins as such:
- Admin API
- ADC
- Ingress Controller
KEYCLOAK_IP=192.168.1.81 # replace with your host IP
OIDC_DISCOVERY=http://${KEYCLOAK_IP}:8080/realms/quickstart-realm/.well-known/openid-configuration
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "acl-route",
"uri":"/anything/*",
"plugins": {
"openid-connect": {
"bearer_only": true,
"client_id": "'"$OIDC_CLIENT_ID"'",
"client_secret": "'"$OIDC_CLIENT_SECRET"'",
"discovery": "'"$OIDC_DISCOVERY"'",
"scope": "openid profile",
"redirect_uri": "http://localhost:9080/anything/callback"
},
"acl": {
"external_user_label_field": "groups",
"allow_labels": {
"groups": ["/apisix"]
}
}
},
"upstream":{
"type":"roundrobin",
"nodes":{
"httpbin.org:80":1
}
}
}'
❶ Configure external_user_label_field to the name mapped to the group.
❷ Allow only users with groups attribute value /apisix to access the upstream resource.
services:
- name: acl-service
routes:
- name: acl-route
uris:
- /anything/*
plugins:
openid-connect:
bearer_only: true
client_id: ${OIDC_CLIENT_ID}
client_secret: ${OIDC_CLIENT_SECRET}
discovery: http://${KEYCLOAK_IP}:8080/realms/quickstart-realm/.well-known/openid-configuration
scope: "openid profile"
redirect_uri: http://localhost:9080/anything/callback
acl:
external_user_label_field: groups
allow_labels:
groups:
- /apisix
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
❶ Configure external_user_label_field to the name mapped to the group.
❷ Allow only users with groups attribute value /apisix to access the upstream resource.
Synchronize the configuration to the gateway:
adc sync -f adc.yaml
This example requires an external Keycloak instance and environment-specific variables. Configure the openid-connect plugin parameters according to your Keycloak setup.
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: acl-plugin-config
spec:
plugins:
- name: openid-connect
config:
bearer_only: true
client_id: apisix-quickstart-client
client_secret: bi9NFscFT4k0ljaRzQWlJWthrlygUn3x
discovery: http://192.168.1.81:8080/realms/quickstart-realm/.well-known/openid-configuration
scope: "openid profile"
redirect_uri: http://localhost:9080/anything/callback
- name: acl
config:
external_user_label_field: groups
allow_labels:
groups:
- /apisix
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: acl-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: PathPrefix
value: /anything/
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: acl-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80