2024 was the year AI agents went from demos to production. With the Model Context Protocol (MCP) gaining adoption from Google, OpenAI, Microsoft, and countless others, we're seeing a fundamental shift in how applications interact with external services. And with that shift comes a whole new set of authorization challenges that we at Casbin have been thinking about.
Understanding How Casbin Matching Works in Detail
In this post, I will explain the design and implementation of RBAC using the Casbin library. For a SaaS platform dealing with multiple resource hierarchies and roles that inherit permissions from higher levels, Casbin provides a performant alternative to consider.
Introduction to RBAC
RBAC is a method of restricting access to resources based on the roles that individuals hold. To better understand how hierarchical RBAC works, let's take a look at Azure's RBAC system in the next section and then attempt to implement a similar system.
Understanding Azure's Hierarchical RBAC

There is a role called Owner for all resources in Azure. Suppose if I have the Owner role assigned to me at the subscription level, that means I am the Owner of all the resource groups and resources under that subscription. If I have Owner at the resource group level, then I am the Owner of all the resources under that resource group.
This image shows that I have Owner access at the subscription level. 
When I check the IAM of a Resource Group under this Subscription, you can see that I have inherited Owner access from the
subscription. 
So, this is how Azure's RBAC is hierarchical. Most enterprise software uses hierarchical RBAC because of the hierarchical nature of the resource levels. In this tutorial, we'll try to implement a similar system using Casbin.
How Does Casbin Work?
Before diving into the implementation, it is important to understand what Casbin is and how it functions at a high level. This understanding is necessary because each Role-Based Access Control (RBAC) system may vary based on specific requirements. By grasping the workings of Casbin, we can effectively fine-tune the model.
What is ACL?
ACL stands for Access Control List. It is a method in which users are mapped to actions and actions to resources.
The model definition
Let's consider a simple example of an ACL model.
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
The request_definition is the query template of the system. For example, a request
alice, write, data1can be interpreted as "Can subject Alice perform the action 'write' on object 'data1'?".The policy_definition is the assignment template of the system. For example, by creating a policy
alice, write, data1, you are assigning permission to subject Alice to perform the action 'write' on object 'data1'.The policy_effect defines the effect of the policy.
In the matchers section, the request is matched with the policy using the conditions
r.sub == p.sub && r.obj == p.obj && r.act == p.act.
Now let's test the model on the Casbin editor
Open the editor and paste the above model in the Model editor.
Paste the following in the Policy editor:
p, alice, read, data1
p, bob, write, data2
and the following in the Request editor:
alice, read, data1
The result will be:
true
Visual representation of the ACL model, policy, and request matching

What is RBAC?
RBAC stands for Role-Based Access Control. In RBAC, a user is assigned a role for a resource, and a role can contain arbitrary actions. The request then checks if the user has the permission to perform the action on the resource.
The model definition
Let's consider a simple example RBAC model:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && r.obj == p.obj
- The role_definition is a graph relation builder that uses a Graph to compare the request object with the policy object.
Now let's test the model on Casbin editor
Open the editor and paste the above model in the Model editor.
Paste the following in the Policy editor:
p, alice, reader, data1
p, bob, owner, data2
g, reader, read
g, owner, read
g, owner, write
and the following in the Request editor:
alice, read, data1
alice, write, data1
bob, write, data2
bob, read, data2
bob, write, data1
The result will be:
true
false
true
true
false
Visual representation of the RBAC model, policy, and request matching

The g - Role to action mapping table has a Graph mapping the role to action. This Graph can be coded as a list of edges, as shown in the policy which is a common way of representing a Graph:
g, reader, read
g, owner, read
g, owner, write
p indicates a normal policy that can be compared using the == operator. g is a Graph-based comparison function. You can define multiple Graph comparators by adding a numerical suffix like g, g2, g3, ... and so on.
What is Hierarchical RBAC?
In Hierarchical RBAC, there are more than one type of resources and there is an inheritance relationship between the resource types. For example, "subscription" is one type and "resourceGroup" is another type. A sub1 of type Subscription can contain multiple resourceGroups (rg1, rg2) of type ResourceGroup.
Similar to the resource hierarchy, there will be two types of roles and actions: Subscription roles and actions, and ResourceGroup roles and actions. There is an arbitrary relationship between the Subscription role and ResourceGroup role. For example, consider a Subscription Role sub-owner. This role is inherited by a ResourceGroup Role rg-owner, which means that if I am assigned the sub-owner role on Subscription sub1, then I automatically also get the rg-owner role on rg1 and rg2.
The model definition
Let's take a simple example of the Hierarchical RBAC model:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && g2(p.obj, r.obj)
- The role_definition is a graph relation builder which uses a Graph to compare the request object with the policy object.
Now let's test the model on the Casbin editor
Open the editor and paste the above model in the Model editor.
Paste the following in the Policy editor:
p, alice, sub-reader, sub1
p, bob, rg-owner, rg2
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
And paste the following in the Request editor:
alice, rg-read, rg1
The result will be:
true
Visual representation of the RBAC model, policy, and request matching

The g - Role to (Action, Role) Mapping table has a graph mapping the role to the action, role mapping. This graph can be coded as a list of edges, as shown in the policy, which is a common way of representing a graph:
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
The g2 - Sub to RG Mapping table has a graph mapping subscription to resourceGroup:
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
Subject Matching Visual representation

Action Matching Visual representation

Object Matching Visual representation

When a request is submitted to Casbin, this matching happens for all the policies. If at least one policy matches, then the result of the request is true. If no policy matches the request, then the result is false.
Conclusion
In this tutorial, we learned about how different authorization models work and how they can be modeled using Casbin. In the second part of this tutorial, we will implement this in a demo Spring Boot Application and secure the APIs using Casbin.
Penggunaan Casbin dalam APISIX untuk kebenaran
Pengenalan
APISIX ialah gerbang API berasaskan awan yang berkelajuan tinggi dan boleh diubah suai yang berdasarkan Nginx dan etcd. Ia adalah projek sumber terbuka oleh Yayasan Perisian Apache. Selain itu, apa yang menjadikan APISIX begitu baik ialah sokongan untuk banyak plugin terbina dalam yang hebat yang boleh digunakan untuk melaksanakan ciri-ciri seperti pengesahan, pemantauan, perutean, dsb. Dan hakikat bahawa plugin dalam APISIX dimuat semula secara panas (tanpa mula semula) menjadikannya sangat dinamik.
Tetapi semasa menggunakan APISIX, mungkin terdapat senario di mana anda mungkin ingin menambah logik kebenaran kompleks dalam aplikasi anda. Inilah di mana authz-casbin mungkin boleh membantu anda, authz-casbin adalah plugin APISIX yang berdasarkan Lua Casbin yang membolehkan penggunaan kuasa penggunaan berdasarkan pelbagai model kawalan akses. Casbin adalah perpustakaan penggunaan yang menyokong model kawalan akses seperti ACL, RBAC, ABAC. Asalnya ditulis dalam Go, ia telah dipindahkan ke banyak bahasa dan Lua Casbin adalah pelaksanaan Lua bagi Casbin. Pembangunan authz-casbin bermula apabila kami mencadangkan plugin baru untuk penggunaan dalam repositori APISIX (#4674) yang mana ahli teras bersetuju. Dan selepas ulasan yang membantu yang menyebabkan beberapa perubahan dan penambahbaikan utama, PR (#4710) akhirnya digabungkan.
Dalam blog ini, kami akan menggunakan plugin authz-casbin untuk menunjukkan bagaimana anda boleh melaksanakan model penggunaan berdasarkan Kawalan Akses Berdasarkan Peranan (RBAC) dalam APISIX.
PERHATIAN: Anda perlu menggunakan beberapa plugin lain atau alur kerja tersuai untuk mengesahkan pengguna kerana Casbin hanya akan melakukan penggunaan dan bukan pengesahan.
Membuat model
Plugin ini menggunakan tiga parameter untuk membenarkan sebarang permintaan - subjek, objek dan tindakan. Di sini, subjek adalah nilai tajuk nama pengguna, yang boleh menjadi seperti [username: alice]. Kemudian, objek tersebut adalah laluan URL yang diakses dan tindakan adalah kaedah permintaan yang digunakan.
Katakan kita ingin membuat model dengan tiga sumber pada laluan - /`\`, /res1\ dan `/res2`. Dan kita ingin mempunyai model seperti ini:

Ini bermakna semua pengguna (*`\`) seperti contohnya jack\ boleh mengakses laman utama (/`\`). Dan pengguna dengan kebenaran admin\ seperti alice`\` dan bob\ boleh mengakses semua halaman dan sumber (seperti res1`\` dan res2\). Juga, mari kita hadkan pengguna tanpa sebarang kebenaran admin untuk menggunakan hanya kaedah permintaan `GET`. Untuk senario ini, kita boleh menentukan model sebagai:
[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)
Membuat polisi
Dari senario di atas, polisi tersebut akan menjadi:
p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin
Pencocok dari model bermakna:
(g(r.sub, p.sub) || keyMatch(r.sub, p.sub)): Sama ada subjek permintaan mempunyai peranan sebagai subjek polisi atau subjek permintaan sepadan dengan subjek polisi dalamkeyMatch.keyMatchadalah fungsi terbina dalam Lua Casbin, anda boleh melihat penerangan fungsi dan lebih banyak fungsi yang boleh berguna di sini.keyMatch(r.obj, p.obj): Objek permintaan sepadan dengan objek polisi (laluan URL di sini).keyMatch(r.act, p.act): Tindakan permintaan sepadan dengan tindakan polisi (kaedah permintaan HTTP di sini).
Mengaktifkan plugin pada laluan
Setelah anda mencipta model dan polisi, anda boleh mengaktifkannya pada laluan menggunakan APISIX Admin API. Untuk mengaktifkannya menggunakan laluan fail model dan polisi:
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": "username"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}'
Di sini, medan nama pengguna adalah nama header yang akan anda gunakan untuk menyampaikan subjek. Sebagai contoh, jika anda akan menyampaikan header nama pengguna sebagai user: alice, anda akan menggunakan "username": "user".
Untuk menggunakan teks model/polisi dan bukannya fail, anda boleh menggunakan medan model dan policy sebagai gantinya:
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
g, bob, admin",
"username": "username"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/*"
}'
Mengaktifkan plugin menggunakan model/polisi global
Mungkin terdapat situasi di mana anda mungkin ingin menggunakan konfigurasi model dan polisi tunggal merentasi pelbagai laluan. Anda boleh melakukannya dengan terlebih dahulu menghantar permintaan PUT untuk menambah konfigurasi model dan polisi ke metadata plugin dengan:
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"
}'
Kemudian, untuk mengaktifkan konfigurasi yang sama pada beberapa rute, hantar permintaan menggunakan Admin API:
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"plugins": {
"authz-casbin": {
"username": "username"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/route1/*"
}'
Ini akan menambah konfigurasi metadata plugin ke rute tersebut. Anda juga boleh mengemas kini konfigurasi metadata plugin dengan mudah dengan menghantar semula permintaan ke metadata plugin dengan konfigurasi model dan polisi yang dikemas kini, plugin akan mengemas kini semua rute yang menggunakan metadata plugin secara automatik.
Kes Penggunaan
- Kes penggunaan utama plugin ini adalah dalam melaksanakan kebenaran dalam API anda. Anda boleh menambah plugin ini dengan mudah pada mana-mana rute API yang anda gunakan dengan konfigurasi model dan polisi kebenaran anda.
- Jika anda ingin mempunyai model kebenaran tunggal untuk semua API anda, anda boleh menggunakan kaedah model/polisi global. Ini memudahkan pengemaskinian polisi untuk semua rute, kerana anda hanya perlu mengemas kini metadata dalam etcd.
- Manakala jika anda ingin menggunakan model yang berbeza untuk setiap rute yang berbeza, anda boleh menggunakan kaedah rute. Ini berguna apabila laluan API yang berbeza mempunyai set kebenaran pengguna yang berbeza. Anda juga boleh menggunakan ini apabila anda menangani dasar yang lebih besar, kerana ia akan mempercepatkan pengesahan apabila disaring ke dalam pelbagai laluan.
Yang Luo - Pemenang Bonus Rakan Sejawat Sumber Terbuka Google
Hari ini, kami dengan senang hati mengumumkan bahawa pengasas Casbin, Yang Luo telah dianugerahkan sebagai "Pemenang Bonus Rakan Sejawat Sumber Terbuka Google" untuk kerjanya pada Casbin, Npcap dan Nmap pada suku ketiga 2019.

Surat anugerah asal boleh diakses di sini.
Program Google Open Source Peer Bonus diterangkan sebagai:
Dengan cara yang sama seperti Google Peer Bonus digunakan untuk mengiktiraf rakan sekerja Google yang telah melakukan lebih dari yang diharapkan, Open Source Peer Bonus mengiktiraf orang luar yang telah membuat sumbangan luar biasa kepada sumber terbuka.
Pengumuman untuk pemenang tahun 2019 boleh didapati di:
https://opensource.googleblog.com/2020/01/announcing-2019-second-cycle-google.html
Yang dan Casbin disenaraikan di kalangan pembangun dan projek sumber terbuka yang mempunyai kesan yang relevan di luar sana, seperti Git, TensorFlow, V8, CPython, LLVM, projek Apache, Angular atau Jenkins.
Kami gembira melihat Casbin diiktiraf dengan cara ini kerana sumbangannya kepada sumber terbuka dan keselamatan awan!
Terima kasih kerana menaiki Casbin!
Mengubahsuai Dokumentasi Kami
Hari ini, kami telah memindahkan dokumentasi Casbin dari GitHub Wiki ke Docs laman web ini, Docusaurus menyediakan banyak ciri-ciri hebat seperti gaya Markdown yang lebih baik,
Dokumentasi ini belum sempurna dan masih memerlukan penalaan. Kod sumber dihoskan
Sebarang sumbangan atau cadangan dialu-alukan!
node-Casbin: Ahli Baru Keluarga Casbin
Hari ini, kami berjaya memindahkan Casbin ke Node.js, yang dinamakan sebagai:
node-Casbin berkongsi penggunaan dan API yang serupa Middleware untuk Express, Koa2 dan Egg.js sudah siap Pengaya storan untuk Sequelize juga sudah disediakan.
Semoga ia dapat memenuhi keperluan anda dengan baik :)
Pelancaran Pelayan Casbin!
Beberapa pelanggan kami bertanya jika Casbin boleh digunakan sebagai perkhidmatan dan bukannya perpustakaan. Jawapannya ialah YA. Hari ini, kami melancarkan projek Casbin Server sebagai penyelesaian konkrit untuk
Pelayan Casbin sedang dalam pembangunan aktif oleh pasukan teras kami. Ia mempunyai beberapa ciri:
- Dikembangkan secara tulen dalam Golang.
- Mampu mengurus beribu-ribu contoh Casbin, jadi anda boleh memindahkan logik penguatkuasaan dasar dari berbilang perkhidmatan ke dalam satu Pelayan Casbin.
- gRPC digunakan untuk berkomunikasi dengan Pelayan Casbin. Kami juga mempertimbangkan untuk menambah sokongan RESTful dalam masa terdekat.
- Portal pentadbir web yang mesra disediakan untuk pentadbir bukan pembangun untuk mengurus semua butiran seperti contoh Casbin, model, storan dasar dan penyeimbangan beban.
Kod sumber dihoskan di GitHub: https://github.com/casbin/casbin-server
Sebarang isu atau permintaan tarik dialu-alukan :)