メインコンテンツにスキップ

· 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 は Nginx や etcd に基づく高性能でスケーラブルなクラウド ネイティブ API ゲートウェイです。 これは、Apache Software Foundationによるオープンソースプロジェクトです。 それに加えて、APISIXがとても良いのは、認証のような機能を実装するために使用できる多くの偉大なプラグインのサポートです。 モニタリングルーティングなど APISIX のプラグインが(再起動なしで)ホットリロードされているという事実は、それを非常に動的にします。

しかし、APISIXを使用している間に、アプリケーションに複雑な認可ロジックを追加するシナリオがあるかもしれません。 ここで、authz-casbinがあなたを助けるかもしれません。 authz-casbin は Lua Casbin をベースにした APISIX プラグインで、さまざまなアクセス制御モデルに基づいた強力な認証を可能にします。 Casbin は、ACL、RBAC、ABACなどのアクセス制御モデルをサポートする認可ライブラリです。 もともとはGoで書かれており、それは多くの言語に移植されており、Lua CasbinはCasbinのLua実装です。 authz-casbinの開発は、コアメンバーが合意したAPISIXリポジトリ(#4674)で承認のための新しいプラグインを提案した時に始まりました。 そして、大きな変更と改善につながった役立つレビューの後、PR (#4710) が最終的にマージされました。

このブログで APISIXのロールベースアクセス制御(RBAC)に基づいて認証モデルを実装する方法を示すために、authz-casbinプラグインを使用します。

注意: Casbinは認証のみを行い、認証しないので、ユーザーを認証するために、他のプラグインまたはカスタムワークフローを使用する必要があります。

モデルの作成

このプラグインは、すべてのリクエストを承認するために3つのパラメータを使用します - 件名、オブジェクト、およびアクション。 ここで、subject はユーザー名ヘッダーの値で、 [username: alice] のようなものになる可能性があります。 次に、オブジェクトはアクセスされているURLパスであり、アクションはリクエストメソッドが使用されています。

/, /res1、および/res2のパスに3つのリソースを持つモデルを作成したいとします。 次のようなモデルが必要です

画像

例えば、jackのようなすべてのユーザー( * )がホームページにアクセスできることを意味します(/)。 alicebob のような 管理者 権限を持つユーザーは、( res1res2 のような) すべてのページとリソースにアクセスできます。 また、 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. ub)) <code>: リクエストの件名は、ポリシーの件名としての役割を持っているか、リクエストの件名は、 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 フィールドは、subject に渡すために使用するヘッダー名です。 例えば、ユーザー名ヘッダーを user: aliceとして渡す場合は、 "username": "user" を使用します。

ファイルの代わりにモデル/ポリシーテキストを使用するには、代わりに モデルポリシー フィールドを使用できます。

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 内のメタデータのみを更新する必要があるため、すべてのルートでポリシーの更新が容易になります。
  • 異なるルートごとに異なるモデルを使用したい場合は、route (ルート)メソッドを使用できます。 これは、異なるAPIルートが異なるユーザ権限セットを持つ場合に役立ちます。 より大きなポリシーを扱っている場合にもこれを使用できます。複数のルートにフィルタされると認可が速くなりますので。

· 1 分で読む
Casbin

今日、我々は喜んでCasbinの創設者、Yang Luoが2019年Q3のCasbinNpcapNmapでの彼の仕事に対して「Google Open Source Peer Bonus winners」を受賞したことを発表します。

spb

オリジナルの賞状はこちら にアクセスできます。

Google Open Source Peer Bonus プログラムは次のように記述されています。

Google ピアボーナスは、上記以降のGoogleの仲間を認識するために使用されるのと同じように。 オープンソースピアボーナスは、オープンソースに卓越した貢献をした外部の人を認識します。

2019年受賞者 アナウンスはこちらでご覧いただけます:

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

ヤン氏とカスビン氏は、オープンソースの開発者やそこに影響を与えるプロジェクトにリストされています。 Git、TensorFlow、V8、CPython、LLVM、Apacheプロジェクト、Angular、Jenkinsなど。

オープンソースとクラウドのセキュリティへの貢献により、Casbinがこのように認識されたことを嬉しく思います。

ご利用ありがとうございます!

· 1 分で読む
Yang Luo

今日、私たちはCasbinのドキュメンテーションをGitHub WikiからこのウェブサイトのDocsに移行しました。これはDocusaurusによって支えられています。 Docusaurusはより良い マークダウンスタイル、全文検索、バージョン管理、翻訳などの素晴らしい機能をたくさん提供しています。

ドキュメントはまだ完璧ではなく、まだチューニングが必要です。 ソースコードはGitHubにホストされています:https://github.com/casbin/casbin-website-v2 .

どんな貢献も提案も歓迎です!

· 1 分で読む
Zixuan Liu

今日、Casbin を Node.js に正常に移植しました。これは node-Casbin という名前です。

node-Casbin は、Casbin の他の実装と同様の使用法と API を共有しています。 Express、Koa2、Egg.jsのミドルウェアは 用意されています。 シーケンス用のストレージアダプタも用意されています。

それがあなたの必要性によく役立つことを願っています:)

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

· 1 分で読む
Helong Zhang

一部のお客様は、Casbinがライブラリの代わりにサービスとして使用できるかどうかを尋ねています。 の答えは はい です。 本日、 Casbin Server プロジェクトを、 Access Control as a Service の具体的なソリューションとして開始しました。

Casbin Server はコアチームによって積極的に開発されています。 いくつかの機能があります:

  • 純粋にゴランで開発されました。
  • 数千のCasbinインスタンスを管理できるため、ポリシー執行ロジックを複数のサービスから1つのCasbinサーバーに移動できます。
  • gRPC はCasbin Server との通信に使用されます。 また、近い将来、 RESTful のサポートを追加することも検討しています。
  • 開発者以外の管理者は、Casbinインスタンス、モデル、ポリシーストレージ、ロードバランシングなどのすべての詳細を管理するためのフレンドリーなWeb管理者ポータルが提供されています。

ソースコードは GitHub でホストされています: https://github.com/casbin/casbin-server

問題やプルリクエストは歓迎します:)