When using Apache APISIX, you may want to add complex authorization logic to your application. In this article, we will use Apache APISIX’s built-in Casbin plug-in (Authz-Casbin) to implement the role-based access Control (RBAC) model.

introduce

Apache APISIX

Apache APISIX is a dynamic, real-time, high-performance API gateway that provides load balancing, dynamic upstream, grayscale publishing, refined routing, traffic limiting, service degradation, service fusing, identity authentication, observability and hundreds of other features. You can use Apache APISIX to handle traditional north-south traffic, as well as east-west traffic between services, or as k8s Ingress Controller.

Casbin

Casbin is a powerful and efficient open source access control framework. Its permission management mechanism supports multiple access control models.

The authz-Casbin plug-in is introduced

In the use of Apache APISIX, there is an implicit contradiction between route matching and request authorization: For higher-grained permission control, higher-grained routes need to be configured to accurately identify and authorize requests. In a complex authorization model scenario, the number of routes increases exponentially, aggravating the operation and maintenance complexity. Authz-casbin is a Lua-Casbin-based Apache APISIX plug-in that supports powerful authorization based on a variety of access models. Casbin is a powerful and efficient open source access control framework, supporting ACL, RBAC, ABAC and other access control models, Lua-Casbin is the Implementation of The LuA version of Casbin access control framework. The authz-Casbin plugin decoups route matching from request authorization. You can load various authorization access models into Apache APISIX and use Lua-Casbin to implement efficient and complex authorization patterns.

Note: If you want to implement authentication, you need to use another plugin or configure it yourself, such as the jwt-Auth plugin.

Authz-casbin Usage guide

Create a model

The authz-Casbin plug-in uses three parameters for authorization: Subject, Object, and Action. Subject is the user name, representing the user in the request; Object is the URL that’s going to be accessed or the resource that’s going to be accessed; An action is an action that requests authorization, such as a read or write operation. Suppose we want to create a model that accesses three resources: /, /res1, /res2. We want a model that looks something like this:

In this model, all users, such as Jack, have access to the main page (/). Users with administrator privileges like Alice and Bob have access to all pages and resources (/res1, /res2, /). Thus, we need to restrict access to specific resources to users without administrator privileges using the GET request method. The required model is as follows:

[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)

Copy the code

Creating a Policy

From the examples above, the strategy would look something like this:

p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob,admin

Copy the code

Matcher in the model shows that:

  1. (g (r.s ub, p. ub) | | keyMatch r.s ub, p. (ub)) : The subject in the request has the same role as the subject in the policy, or the subject in the request and the subject in the policy can be matched using the built-in keyMatch method. KeyMatch is a built-in function of Lua Casbin, the description and more functions can jump to Lua-Casbin.

  2. KeyMatch (R.o.bj, P.o.bj) : The object in the request and the object in the policy can match each other (referring to URL links).

  3. KeyMatch (r.ct, p.ct) : Actions in the request and actions in the policy can match each other.

Use plug-ins on routing

Once you have created the model and policy, you can use the APISIX Admin API for routing. To use this, you can model and policy the file path:

The curl http://127.0.0.1:9080/apisix/admin/routes/1 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "plugins": { "authz-casbin": { "model_path": "/path/to/model.conf", "policy_path": "/path/to/policy.csv", "username": "user" } }, "upstream": { "nodes": {" 127.0.0.1:1980 ": 1}," type ":" roundrobin "}, "uri" : "/ *"} 'Copy the code

In this case, username is the username passed to the subject. For example, you can set “username”:”user” to pass your definition of “user”:” Alice “to username, making username Alice. Again, you can put models and policies directly into it:

The curl http://127.0.0.1:9080/apisix/admin/routes/1 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "plugins": { "authz-casbin": { "model": "[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)", "policy": "P, *, /, GET p, admin, * * g, Alice, admin", "username" : "user"}}, "upstream" : {" nodes ": {" 127.0.0.1:1980" : 1 }, "type": "roundrobin" }, "uri": "/*" }'Copy the code

Use plug-ins using global models/policies

In some cases, you may want to use the same model and policy across multiple routes. You can first send a PUT request to send the configuration of the model and policy to the metadata of the plug-in:

The curl < http://127.0.0.1:9080/apisix/admin/plugin_metadata/authz-casbin > - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -i -X PUT -d ' { "model": "[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)", "policy": "p, *, /, GET p, admin, *, * g, alice, admin g, bob, admin" }'Copy the code

Then, you need to use the Admin API to send requests that make multiple routes use the same model/policy configuration;

The curl http://127.0.0.1:9080/apisix/admin/routes/1 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "plugins": { "authz-casbin": { "username": "user" } }, "upstream": {" nodes ": {" 127.0.0.1:1980" : 1}, "type" : "roundrobin}", "uri" : "/ *"} 'Copy the code

This will dynamically add the plug-in’s configuration to the route. You can easily update the configuration of a plug-in by sending a request to update the model and policy in the plug-in’s configuration data.

The last

Thanks to the developers of Casbin and Apache APISIX community, from The developer rushitote of Casbin community to the developer rushitote of Apache APISIX community for actively reviewing the PR, This cross-community collaboration moves forward amicably and orderly in response to Open Source Makes the world Better.

Authz – casbin plug-in

About the Apache APISIX

Apache APISIX is a dynamic, real-time, high-performance open source API gateway that provides rich traffic management features such as load balancing, dynamic upstream, grayscale publishing, service circuit breaker, authentication, observability, and more. Apache APISIX helps enterprises quickly and securely handle API and microservice traffic, including gateways, Kubernetes Ingress, and service grids.

World has hundreds of companies using Apache APISIX processing key business flow, covering financial, Internet, manufacturing, retail, operators, etc., such as NASA (NASA), the European Union, letter of digital factory, Air China, China mobile, tencent, huawei, weibo, netease, shell to find room, 360, taikang, nai snow tea, etc.

More than 200 contributors contribute to Apache APISIX, the world’s most active open source gateway project. Smart developers! Join this vibrant and diverse community to bring more good to the world!

  • Apache APISIX GitHub: github.com/apache/apis…
  • Apache APISIX website: apisix.apache.org/
  • Apache APISIX document: apisix.apache.org/zh/docs/api…