Lewati ke konten utama

· Satu menit baca

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.

· Satu menit baca

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

Azure Hierarchy

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. Subscription Owner

When I check the IAM of a Resource Group under this Subscription, you can see that I have inherited Owner access from the subscription. RG Owner

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
  1. The request_definition is the query template of the system. For example, a request alice, write, data1 can be interpreted as "Can subject Alice perform the action 'write' on object 'data1'?".

  2. 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'.

  3. The policy_effect defines the effect of the policy.

  4. 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

acl

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
  1. 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

rbac

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
info

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)
  1. 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

hrbac

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

hrbac-sub-match

Action Matching Visual representation

hrbac-act-match

Object Matching Visual representation

hrbac-obj-match

info

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.

· Satu menit baca
Rushikesh Tote

Pengantar

APISIX adalah gateway API berkinerja tinggi dan dapat diskalakan yang bersifat cloud native, berbasis Nginx dan etcd. Ini adalah proyek sumber terbuka oleh Yayasan Perangkat Lunak Apache. Selain itu, yang membuat APISIX begitu baik adalah dukungan untuk banyak plugin bawaan yang hebat yang dapat digunakan untuk mengimplementasikan fitur seperti autentikasi, pemantauan, perutean, dll. Dan fakta bahwa plugin di APISIX dimuat ulang secara dinamis (tanpa memulai ulang) membuatnya sangat dinamis.

Namun, saat menggunakan APISIX, mungkin ada skenario di mana Anda ingin menambahkan logika otorisasi yang kompleks dalam aplikasi Anda. Di sinilah authz-casbin mungkin dapat membantu Anda, authz-casbin adalah plugin APISIX yang didasarkan pada Lua Casbin yang memungkinkan otorisasi yang kuat berdasarkan berbagai model kontrol akses. Casbin adalah pustaka otorisasi yang mendukung model kontrol akses seperti ACL, RBAC, ABAC. Awalnya ditulis dalam Go, Casbin telah diadaptasi ke banyak bahasa dan Lua Casbin adalah implementasi Lua dari Casbin. Pengembangan authz-casbin dimulai ketika kami mengusulkan plugin baru untuk otorisasi di repositori APISIX (#4674) yang disetujui oleh anggota inti. Dan setelah tinjauan yang membantu yang menyebabkan beberapa perubahan dan peningkatan besar, PR (#4710) akhirnya digabungkan.

Dalam blog ini, kami akan menggunakan plugin authz-casbin untuk menunjukkan bagaimana Anda dapat mengimplementasikan model otorisasi berbasis Role Based Access Control (RBAC) di APISIX.

CATATAN: Anda perlu menggunakan plugin lain atau alur kerja kustom untuk mengautentikasi pengguna karena Casbin hanya akan melakukan otorisasi, bukan autentikasi.

Membuat model

Plugin ini menggunakan tiga parameter untuk mengotorisasi setiap permintaan - subjek, objek, dan aksi. Di sini, subjek adalah nilai dari header nama pengguna, yang bisa berupa sesuatu seperti [username: alice]. Kemudian, objeknya adalah jalur URL yang diakses dan tindakannya adalah metode permintaan yang digunakan.

Misalkan kita ingin membuat model dengan tiga sumber daya pada jalur - /`\`, /res1\ dan `/res2`. Dan kita ingin memiliki model seperti ini:

gambar

Ini berarti semua pengguna (*`\`) misalnya jack\ dapat mengakses halaman utama (/`\`). Dan pengguna dengan izin admin\ seperti alice`\` dan bob\ dapat mengakses semua halaman dan sumber daya (seperti res1`\` dan res2\). Juga, mari kita batasi pengguna tanpa izin admin hanya menggunakan metode permintaan `GET`. Untuk skenario ini, kita bisa mendefinisikan 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 kebijakan

Dari skenario di atas, kebijakan tersebut akan menjadi:

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

Pencocok dari model berarti:

  1. (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)): Baik subjek permintaan memiliki peran sebagai subjek kebijakan atau subjek permintaan cocok dengan subjek kebijakan dalam keyMatch. keyMatch adalah fungsi bawaan dalam Lua Casbin, Anda dapat melihat deskripsi fungsi dan lebih banyak fungsi serupa yang mungkin berguna di sini.
  2. keyMatch(r.obj, p.obj): Objek permintaan cocok dengan objek kebijakan (jalur URL di sini).
  3. keyMatch(r.act, p.act): Tindakan permintaan cocok dengan tindakan kebijakan (metode permintaan HTTP di sini).

Mengaktifkan plugin pada rute

Setelah Anda membuat model dan kebijakan, Anda dapat mengaktifkannya pada rute menggunakan APISIX Admin API. Untuk mengaktifkannya menggunakan jalur file model dan kebijakan:

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, bidang username adalah nama header yang akan Anda gunakan untuk meneruskan subjek. Misalnya, jika Anda akan meneruskan header username sebagai user: alice, Anda akan menggunakan "username": "user".

Untuk menggunakan teks model/kebijakan alih-alih file, Anda dapat menggunakan bidang 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/kebijakan global

Mungkin ada situasi di mana Anda ingin menggunakan konfigurasi model dan kebijakan tunggal di beberapa rute. Anda dapat melakukannya dengan terlebih dahulu mengirim permintaan PUT untuk menambahkan konfigurasi model dan kebijakan 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, kirim 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 menambahkan konfigurasi metadata plugin ke rute tersebut. Anda juga dapat dengan mudah memperbarui konfigurasi metadata plugin dengan mengirim ulang permintaan ke metadata plugin dengan konfigurasi model dan kebijakan yang diperbarui, plugin akan secara otomatis memperbarui semua rute yang menggunakan metadata plugin tersebut.

Kasus Penggunaan

  • Kasus penggunaan utama dari plugin ini adalah dalam mengimplementasikan otorisasi pada API Anda. Anda dapat dengan mudah menambahkan plugin ini pada rute API apa pun yang Anda gunakan dengan konfigurasi model dan kebijakan otorisasi Anda.
  • Jika Anda ingin memiliki model otorisasi tunggal untuk semua API Anda, Anda dapat menggunakan metode model/kebijakan global. Hal ini memudahkan pembaruan kebijakan untuk semua rute, karena Anda hanya perlu memperbarui metadata di etcd.
  • Sedangkan jika Anda ingin menggunakan model yang berbeda untuk setiap rute yang berbeda, Anda dapat menggunakan metode rute. Ini berguna ketika rute API yang berbeda memiliki set izin pengguna yang berbeda. Anda juga dapat menggunakan ini ketika berhadapan dengan kebijakan yang lebih besar, karena akan mempercepat otorisasi ketika difilter ke beberapa rute.

· Satu menit baca
Casbin

Hari ini, kami dengan senang hati mengumumkan bahwa pendiri Casbin, Yang Luo dianugerahi sebagai "Pemenang Bonus Rekan Sumber Terbuka Google" untuk karyanya pada Casbin, Npcap dan Nmap pada kuartal ketiga tahun 2019.

ospb

Surat penghargaan asli dapat diakses di sini.

Program Google Open Source Peer Bonus dijelaskan sebagai:

Dengan cara yang sama seperti Google Peer Bonus digunakan untuk mengakui seorang rekan Googler yang telah melampaui batas, Open Source Peer Bonus mengakui orang luar yang telah memberikan kontribusi luar biasa kepada open source.

Pengumuman untuk pemenang tahun 2019 tersedia di:

https://opensource.googleblog.com/2020/01/announcing-2019-second-cycle-google.html

Yang dan Casbin tercantum di antara pengembang dan proyek open source yang memiliki dampak yang relevan di luar sana, seperti Git, TensorFlow, V8, CPython, LLVM, proyek Apache, Angular, atau Jenkins.

Kami senang melihat Casbin diakui dengan cara ini atas kontribusinya terhadap open source dan keamanan cloud!

Terima kasih telah menggunakan Casbin!

· Satu menit baca
Yang Luo

Hari ini, kami memigrasi dokumentasi Casbin dari GitHub Wiki ke Docs di situs web ini, Docusaurus menyediakan banyak fitur luar biasa seperti gaya Markdown yang lebih baik, pencarian teks lengkap, pengaturan versi, dan terjemahan.

Dokumentasi ini belum sempurna dan masih memerlukan penyetelan. Kode sumbernya di-host

Setiap kontribusi atau saran sangat kami terima!

· Satu menit baca
Zixuan Liu

Hari ini, kami berhasil memindahkan Casbin ke Node.js, yang diberi nama:

node-Casbin memiliki penggunaan dan API yang serupa Middleware untuk Express, Koa2, dan Egg.js siap untuk digunakan. Penyimpanan adaptor untuk Sequelize juga telah disiapkan.

Semoga dapat memenuhi kebutuhan Anda dengan baik :)

GitHub: https://github.com/casbin/node-casbin

· Satu menit baca
Helong Zhang

Beberapa pelanggan kami bertanya apakah Casbin dapat digunakan sebagai layanan bukan sebagai pustaka. Jawabannya adalah YA. Hari ini, kami meluncurkan proyek Casbin Server sebagai solusi konkret untuk

Server Casbin sedang dalam pengembangan aktif oleh tim inti kami. Server ini memiliki beberapa fitur:

  • Dikembangkan murni dalam Golang.
  • Dapat mengelola ribuan instance Casbin, sehingga Anda dapat memindahkan logika penerapan kebijakan dari beberapa layanan ke satu Server Casbin.
  • gRPC digunakan untuk berkomunikasi dengan Server Casbin. Kami juga mempertimbangkan untuk menambahkan dukungan RESTful dalam waktu dekat.
  • Portal administrator web yang ramah disediakan untuk administrator non-developer untuk mengelola semua detail seperti instance Casbin, model, penyimpanan kebijakan, dan load balancing.

Kode sumber di-hosting di GitHub: https://github.com/casbin/casbin-server

Setiap masalah atau permintaan tarik (pull requests) sangat kami harapkan :)