ข้ามไปยังเนื้อหาหลัก

· อ่าน 1 นาที

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.

· อ่าน 1 นาที

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
ข้อมูล

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

ข้อมูล

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.

· อ่าน 1 นาที
Rushikesh Tote

บทนำ

APISIX เป็น API gateway ที่มีประสิทธิภาพสูงและสามารถขยายได้ตามความต้องการ พัฒนาบนพื้นฐานของ Nginx และ etcd เป็นโปรเจกต์โอเพนซอร์สโดยมูลนิธิซอฟต์แวร์ Apache นอกจากนี้สิ่งที่ทำให้ APISIX ดีเยี่ยมคือการสนับสนุนปลั๊กอินที่มีประสิทธิภาพมากมายที่สามารถใช้ในการดำเนินการฟีเจอร์ต่างๆ เช่น การตรวจสอบสิทธิ์, การตรวจสอบการทำงาน, การกำหนดเส้นทาง ฯลฯ และความจริงที่ว่าปลั๊กอินใน APISIX สามารถรีโหลดได้ทันที (ไม่ต้องรีสตาร์ท) ทำให้มันมีความยืดหยุ่นสูง

แต่ขณะใช้งาน APISIX อาจมีสถานการณ์ที่คุณต้องการเพิ่มตรรกะการอนุญาตที่ซับซ้อนในแอปพลิเคชันของคุณ นี่คือที่ที่ authz-casbin อาจช่วยคุณได้, authz-casbin เป็นปลั๊กอินของ APISIX ที่พัฒนาบน Lua Casbin ที่ช่วยให้สามารถอนุญาตได้อย่างมีประสิทธิภาพตามโมเดลการควบคุมการเข้าถึงต่างๆ Casbin เป็นไลบรารีการอนุญาตที่รองรับโมเดลการควบคุมการเข้าถึงเช่น ACL, RBAC, ABAC เขียนขึ้นเดิมในภาษา Go และได้ถูกพอร์ตไปยังภาษาอื่นๆ และ Lua Casbin เป็นการนำไปใช้ของ Casbin ในภาษา Lua การพัฒนา authz-casbin เริ่มต้นเมื่อเราเสนอปลั๊กอินใหม่สำหรับการอนุญาตในที่เก็บข้อมูล APISIX (#4674) ซึ่งสมาชิกหลักตกลง และหลังจากการทบทวนที่มีประโยชน์ซึ่งนำไปสู่การเปลี่ยนแปลงและการปรับปรุงที่สำคัญ คำขอ PR (#4710) ก็ถูกผสานเข้าไปในที่สุด

ในบล็อกนี้ เราจะใช้ปลั๊กอิน authz-casbin เพื่อแสดงวิธีการที่คุณสามารถนำไปใช้โมเดลการอนุญาตตาม Role Based Access Control (RBAC) ใน APISIX

หมายเหตุ: คุณจะต้องใช้ปลั๊กอินอื่นหรือกระบวนการทำงานที่กำหนดเองสำหรับการตรวจสอบสิทธิ์ผู้ใช้ เนื่องจาก Casbin จะทำเพียงการอนุญาตและไม่ใช่การตรวจสอบสิทธิ์

การสร้างโมเดล

ปลั๊กอินใช้สามพารามิเตอร์ในการอนุญาตคำขอใดๆ - หัวข้อ, วัตถุ และการกระทำ ที่นี่ หัวข้อคือค่าของหัวข้อ username ซึ่งอาจเป็นอะไรก็ได้เช่น [username: alice] จากนั้น วัตถุคือเส้นทาง URL ที่กำลังถูกเข้าถึง และการกระทำคือวิธีการขอที่กำลังถูกใช้

สมมติว่าเราต้องการสร้างโมเดลที่มีทรัพยากรสามอย่างที่เส้นทาง - /, /res1 และ /res2 และเราต้องการมีโมเดลเช่นนี้:

รูปภาพ

นี่จะหมายความว่าผู้ใช้ทุกคน (*) เช่น jack สามารถเข้าถึงหน้าแรก (/) และผู้ใช้ที่มีสิทธิ์ admin เช่น alice และ bob สามารถเข้าถึงทุกหน้าและทรัพยากร (เช่น res1 และ res2) นอกจากนี้ มาจำกัดผู้ใช้ที่ไม่มีสิทธิ์ admin ให้ใช้เฉพาะวิธีการขอ GET สำหรับสถานการณ์นี้ เราสามารถกำหนดโมเดลได้เป็น:

[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)

การสร้างนโยบาย

จากสถานการณ์ข้างต้น นโยบายจะเป็น:

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

ตัวจับคู่จากโมเดลหมายถึง:

  1. (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)): หัวข้อของคำขอมีบทบาทเหมือนกับหัวข้อของนโยบาย หรือหัวข้อของคำขอตรงกับหัวข้อของนโยบายใน keyMatch keyMatch เป็นฟังก์ชันที่มีอยู่ใน Lua Casbin คุณสามารถดูคำอธิบายของฟังก์ชันและฟังก์ชันอื่นๆ ที่อาจมีประโยชน์ ที่นี่
  2. keyMatch(r.obj, p.obj): วัตถุของคำขอตรงกับวัตถุของนโยบาย (เส้นทาง URL ที่นี่)
  3. keyMatch(r.act, p.act): การกระทำของคำขอตรงกับการกระทำของนโยบาย (วิธีการขอ HTTP ที่นี่)

การเปิดใช้งานปลั๊กอินบนเส้นทาง

เมื่อคุณได้สร้างโมเดลและนโยบายแล้ว คุณสามารถเปิดใช้งานได้บนเส้นทางโดยใช้ APISIX Admin API เพื่อเปิดใช้งานโดยใช้เส้นทางไฟล์โมเดลและนโยบาย:

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": "/*"
}'

ที่นี่ ฟิลด์ username เป็นชื่อหัวข้อที่คุณจะใช้ในการส่งหัวข้อ ตัวอย่างเช่น ถ้าคุณจะส่งหัวข้อ username เป็น user: alice คุณจะใช้ "username": "user"

สำหรับการใช้ข้อความโมเดล/นโยบายแทนไฟล์ คุณสามารถใช้ฟิลด์ model และ policy แทน:

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": "/*"
}'

การเปิดใช้งานปลั๊กอินโดยใช้โมเดล/นโยบายสากล

อาจมีสถานการณ์ที่คุณต้องการใช้โมเดลและนโยบายเดียวกันในหลายเส้นทาง คุณสามารถทำได้โดยการส่งคำขอ PUT เพื่อเพิ่มการกำหนดค่าโมเดลและนโยบายไปยังข้อมูลเมตาของปลั๊กอินโดย:

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"
}'

และจากนั้นเพื่อเปิดใช้งานการกำหนดค่าเดียวกันบนเส้นทางใดๆ ส่งคำขอโดยใช้ 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/*"
}'

นี่จะเพิ่มการกำหนดค่าข้อมูลเมตาของปลั๊กอินไปยังเส้นทาง คุณยังสามารถอัปเดตการกำหนดค่าข้อมูลเมตาของปลั๊กอินได้อย่างง่ายดายโดยการส่งคำขอใหม่ไปยังข้อมูลเมตาของปลั๊กอินด้วยการกำหนดค่าโมเดลและนโยบายที่อัปเดต ปลั๊กอินจะอัปเดตเส้นทางทั้งหมดที่ใช้การกำหนดค่าข้อมูลเมตาโดยอัตโนมัติ

กรณีการใช้งาน

  • กรณีการใช้งานหลักของปลั๊กอินนี้คือการดำเนินการอนุญาตใน API ของคุณ คุณสามารถเพิ่มปลั๊กอินนี้ได้อย่างง่ายดายในเส้นทาง API ใดๆ ที่คุณใช้กับโมเดลการอนุญาตและการกำหนดค่านโยบายของคุณ
  • ถ้าคุณต้องการมีโมเดลการอนุญาตเดียวสำหรับ API ทั้งหมดของคุณ คุณสามารถใช้วิธีโมเดล/นโยบายสากล นี่ทำให้การอัปเดตนโยบายง่ายสำหรับทุกเส้นทาง เนื่องจากคุณเพียงแค่ต้องอัปเดตข้อมูลเมตาใน etcd
  • ในขณะที่ถ้าคุณต้องการใช้โมเดลที่แตกต่างกันสำหรับทุกเส้นทางที่แตกต่างกัน คุณสามารถใช้วิธีเส้นทาง สิ่งนี้มีประโยชน์เมื่อเส้นทาง API ที่แตกต่างกันมีชุดสิทธิ์ผู้ใช้ที่แตกต่างกัน คุณยังสามารถใช้สิ่งนี้เมื่อคุณกำลังจัดการกับนโยบายขนาดใหญ่ เนื่องจากจะทำให้การอนุญาตเร็วขึ้นเมื่อกรองเข้าสู่เส้นทางหลายเส้นทาง

· อ่าน 1 นาที
Casbin

วันนี้, เรายินดีที่จะประกาศว่าผู้ก่อตั้ง Casbin, Yang Luo ได้รับรางวัล "Google Open Source Peer Bonus winners" สำหรับงานของเขาใน Casbin, Npcap และ Nmap ในปี 2019 Q3.

ospb

จดหมายแจ้งรางวัลต้นฉบับสามารถเข้าถึงได้ ที่นี่.

โปรแกรม Google Open Source Peer Bonus ได้รับการอธิบายว่า:

ในลักษณะเดียวกับที่ Google Peer Bonus ใช้เพื่อยกย่องเพื่อนร่วมงานที่ได้ทำงานเกินกว่าที่คาดหวังไว้, Open Source Peer Bonus ยกย่องบุคคลภายนอกที่มีส่วนร่วมอย่างโดดเด่นในโอเพนซอร์ส

ประกาศผู้ชนะประจำปี 2019 สามารถดูได้ที่: announcement for the 2019 winners

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

Yang และ Casbin ถูกจัดอยู่ในหมู่นักพัฒนาโอเพนซอร์สและโปรเจ็กต์ที่มีผลกระทบที่เกี่ยวข้องในที่นั้น, เช่น Git, TensorFlow, V8, CPython, LLVM, โปรเจ็กต์ Apache, Angular หรือ Jenkins.

เรายินดีที่ได้เห็น Casbin ได้รับการยอมรับในลักษณะนี้สำหรับการมีส่วนร่วมในโอเพนซอร์สและความปลอดภัยของคลาวด์!

ขอบคุณที่ใช้บริการ Casbin!

· อ่าน 1 นาที
Yang Luo

วันนี้เราได้ย้ายเอกสารของ Casbin จาก GitHub Wiki ไปยัง Docs ของเว็บไซต์นี้ ซึ่งใช้ Docusaurus Docusaurus มีคุณสมบัติที่ยอดเยี่ยมมากมาย เช่น สไตล์ Markdown ที่ดีกว่า การค้นหาข้อความเต็มรูปแบบ การจัดเวอร์ชัน การแปลภาษา

เอกสารยังไม่สมบูรณ์แบบและยังต้องการการปรับแต่ง ซอร์สโค้ดถูกโฮสต์อยู่บน GitHub: https://github.com/casbin/casbin-website-v2 .

ยินดีต้อนรับทุกข้อเสนอแนะหรือการช่วยเหลือ!

· อ่าน 1 นาที
Zixuan Liu

วันนี้เราได้ทำการย้าย Casbin ไปยัง Node.js สำเร็จ ซึ่งมีชื่อว่า: node-Casbin.

node-Casbin มีการใช้งานและ API ที่คล้ายคลึงกับการใช้งานในรูปแบบอื่นๆ ของ Casbin มิดเดิลแวร์สำหรับ Express, Koa2 และ Egg.js พร้อมใช้งานแล้ว อแดปเตอร์สำหรับการจัดเก็บข้อมูลสำหรับ Sequelize ก็ได้เตรียมไว้แล้ว

หวังว่ามันจะตอบสนองความต้องการของคุณได้ดีนะ :)

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

· อ่าน 1 นาที
Helong Zhang

ลูกค้าบางรายถามว่า Casbin สามารถใช้เป็นบริการแทนที่จะเป็นไลบรารีได้หรือไม่ คำตอบคือ ใช่. วันนี้เราได้เปิดตัวโปรเจค เซิร์ฟเวอร์ Casbin เป็นโซลูชันที่ชัดเจนสำหรับ การควบคุมการเข้าถึงเป็นบริการ.

เซิร์ฟเวอร์ Casbin กำลังถูกพัฒนาอย่างต่อเนื่องโดยทีมงานหลักของเรา มีคุณสมบัติหลายอย่าง:

  • พัฒนาโดยใช้ Golang อย่างบริสุทธิ์
  • สามารถจัดการเซิร์ฟเวอร์ Casbin ได้หลายพันเครื่อง ทำให้คุณสามารถย้ายตรรกะการบังคับนโยบายจากหลายบริการเข้าสู่เซิร์ฟเวอร์ Casbin เดียว
  • gRPC ถูกใช้เพื่อการสื่อสารกับเซิร์ฟเวอร์ Casbin เรายังพิจารณาที่จะเพิ่มการสนับสนุน RESTful ในอนาคตอันใกล้
  • มีพอร์ทัลผู้ดูแลระบบที่เป็นมิตรสำหรับผู้ดูแลที่ไม่ใช่นักพัฒนาเพื่อจัดการรายละเอียดทั้งหมดเช่น เซิร์ฟเวอร์ Casbin, โมเดล, การจัดเก็บนโยบาย และการจัดสรรภาระงาน

ซอร์สโค้ดถูกโฮสต์บน GitHub: https://github.com/casbin/casbin-server

ปัญหาใด ๆ หรือคำขอดึงข้อมูลยินดีต้อนรับ :)