Skip to main content

a6-plugin-wolf-rbac

Overview

The wolf-rbac plugin provides Role-Based Access Control (RBAC) by integrating with the Wolf RBAC server. It enables centralized authentication and fine-grained URL+method permission checking across multiple applications without modifying backend services.

Priority: 2555 (authentication plugin, runs in rewrite phase).

When to Use

  • Centralized RBAC across multiple HTTP applications
  • URL + HTTP method level permission control
  • Unified user management for microservices
  • Need login, user-info, and password-change API endpoints

Prerequisites

  1. Wolf RBAC server running (default http://127.0.0.1:12180)
  2. In Wolf console, configure: Application → Users → Roles → Permissions → Resources
  3. Install Wolf via Docker: https://github.com/iGeeky/wolf/blob/master/quick-start-with-docker/README.md

Plugin Configuration Reference (Consumer)

FieldTypeRequiredDefaultDescription
serverstringNohttp://127.0.0.1:12180Wolf RBAC server URL
appidstringNounsetApplication ID registered in Wolf console
header_prefixstringNoX-Prefix for injected headers (UserId, Username, Nickname)

Note: Configure on the Consumer, not the Route. Route config is empty {}.

Token Format

V1#<appid>#<wolf_jwt_token>

Example: V1#restful#eyJhbGciOiJIUzI1NiIs...

Token Extraction Priority

  1. Query parameter: ?rbac_token=V1%23app%23token (URL-encoded)
  2. Authorization header: Authorization: V1#app#token
  3. Custom header: x-rbac-token: V1#app#token
  4. Cookie: x-rbac-token=V1#app#token

API Endpoints

The plugin registers three endpoints (must be exposed via public-api plugin):

POST /apisix/plugin/wolf-rbac/login

Authenticate and obtain rbac_token.

Request:

{
"appid": "restful",
"username": "test",
"password": "user-password",
"authType": 1
}
  • authType: 1 = password (default), 2 = LDAP (Wolf v0.5.0+)

Response (200):

{
"rbac_token": "V1#restful#eyJhbGci...",
"user_info": {"id": "749", "username": "test", "nickname": "test"}
}

GET /apisix/plugin/wolf-rbac/user_info

Get authenticated user details. Requires valid rbac_token.

Response (200):

{
"user_info": {
"id": 749,
"username": "test",
"nickname": "test",
"permissions": {"USER_LIST": true},
"roles": {}
}
}

PUT /apisix/plugin/wolf-rbac/change_pwd

Change password. Requires valid rbac_token.

Request:

{"oldPassword": "old", "newPassword": "new"}

Authorization Flow

1. Client sends request with rbac_token
2. APISIX parses token → extracts appid + wolf_token
3. Matches appid to Consumer configuration
4. Calls Wolf server: GET /wolf/rbac/access_check
- appID, resName (URL), action (HTTP method), clientIP
5. Wolf checks user roles/permissions for the resource
6. Success → inject X-UserId, X-Username, X-Nickname headers
7. Failure → return 401 (invalid token) or 403 (no permission)

Retry behavior: Up to 3 retries for 5xx Wolf server errors, 100ms between retries.

Step-by-Step Setup

1. Create Consumer

a6 consumer create -f - <<'EOF'
{
"username": "wolf_rbac",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "restful"
}
}
}
EOF

2. Create Protected Route

a6 route create -f - <<'EOF'
{
"id": "protected-api",
"uri": "/api/*",
"plugins": {
"wolf-rbac": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {"backend:8080": 1}
}
}
EOF

3. Expose Login Endpoint

a6 route create -f - <<'EOF'
{
"id": "wolf-login",
"uri": "/apisix/plugin/wolf-rbac/login",
"plugins": {
"public-api": {}
}
}
EOF

4. Expose User Info Endpoint

a6 route create -f - <<'EOF'
{
"id": "wolf-userinfo",
"uri": "/apisix/plugin/wolf-rbac/user_info",
"plugins": {
"public-api": {}
}
}
EOF

5. Expose Change Password Endpoint

a6 route create -f - <<'EOF'
{
"id": "wolf-changepwd",
"uri": "/apisix/plugin/wolf-rbac/change_pwd",
"plugins": {
"public-api": {}
}
}
EOF

6. Test Login

curl -X POST http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login \
-H "Content-Type: application/json" \
-d '{"appid":"restful","username":"test","password":"user-password"}'

7. Access Protected Resource

curl http://127.0.0.1:9080/api/users \
-H "Authorization: V1#restful#<token_from_step_6>"

Multi-Application Setup

# App 1 consumer
a6 consumer create -f - <<'EOF'
{
"username": "wolf_app1",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "app1"
}
}
}
EOF

# App 2 consumer
a6 consumer create -f - <<'EOF'
{
"username": "wolf_app2",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "app2"
}
}
}
EOF

Each appid in the token determines which Consumer (and which Wolf application) is used for permission checking.

Custom Header Prefix

a6 consumer create -f - <<'EOF'
{
"username": "wolf_custom",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "myapp",
"header_prefix": "Wolf-"
}
}
}
EOF

Injected headers become: Wolf-UserId, Wolf-Username, Wolf-Nickname.

Config Sync Example

version: "1"
consumers:
- username: wolf_rbac
plugins:
wolf-rbac:
server: "http://127.0.0.1:12180"
appid: restful

routes:
- id: protected-api
uri: /api/*
plugins:
wolf-rbac: {}
upstream_id: api-backend

- id: wolf-login
uri: /apisix/plugin/wolf-rbac/login
plugins:
public-api: {}

- id: wolf-userinfo
uri: /apisix/plugin/wolf-rbac/user_info
plugins:
public-api: {}

- id: wolf-changepwd
uri: /apisix/plugin/wolf-rbac/change_pwd
plugins:
public-api: {}

Injected Headers

After successful authentication, these headers are added to both request (upstream) and response (client):

HeaderExampleDescription
{prefix}UserIdX-UserId: 749Wolf user ID
{prefix}UsernameX-Username: adminWolf username
{prefix}NicknameX-Nickname: administratorURL-encoded nickname

Error Responses

StatusMessageCause
401Missing rbac token in requestNo token in any supported location
401invalid rbac token: parse failedToken format not V1#appid#jwt
401Invalid appid in rbac tokenNo Consumer with matching appid
401ERR_TOKEN_INVALIDJWT expired or signature invalid
403ERR_ACCESS_DENIEDUser lacks permission for URL+method
500request to wolf-server failedWolf server unreachable or error

Security Recommendations

  • Use HTTPS for Wolf server URL in production
  • Prefer Authorization header over query parameter (avoids logging tokens)
  • Set HttpOnly and Secure flags when using cookies
  • Combine with limit-req on login endpoint to prevent brute force
  • Combine with ip-restriction for additional network-level security

Troubleshooting

SymptomCauseFix
400 "appid is missing" on loginMissing appid in login request bodyInclude appid field
400 "appid not found"No Consumer configured with that appidCreate Consumer with matching appid
401 on every requestToken expired or not passed correctlyRe-login to get fresh token; check token location
403 "ERR_ACCESS_DENIED"User not authorized for URL+method in WolfConfigure permissions in Wolf console
500 "request to wolf-server failed"Wolf server down or unreachableVerify Wolf server URL and connectivity
Login endpoint returns 404Not exposed via public-apiCreate route with public-api plugin for login URI

This page is generated from a6-plugin-wolf-rbac/SKILL.md in the api7/a6 repository. Browse all skills on the AI Agent Skills page.

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation