주요 콘텐츠로 건너뛰기

· 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)이 마침내 병합되었습니다.

이 블로그에서는 authz-casbin 플러그인을 사용하여 APISIX에서 역할 기반 접근 제어(RBAC)를 기반으로 한 인증 모델을 어떻게 구현할 수 있는지 보여줄 것입니다.

참고: Casbin은 인증만 수행하므로 사용자를 인증하기 위해 다른 플러그인이나 사용자 정의 워크플로우를 사용해야 합니다.

모델 생성

플러그인은 모든 요청을 인증하는 데 세 가지 매개변수를 사용합니다 - 주체, 객체, 행동. 여기서 주체는 [username: alice]와 같은 사용자 이름 헤더의 값입니다. 그런 다음, 객체는 접근되는 URL 경로이고 행동은 사용되는 요청 메서드입니다.

세 가지 리소스가 있는 모델을 생성하려고 합니다 - 경로 /, /res1/res2. 그리고 이런 모델을 가지고 싶습니다:

이미지

이것은 모든 사용자(*) 예를 들어 jack이 홈페이지(/)에 접근할 수 있다는 것을 의미합니다. 그리고 admin 권한이 있는 사용자들, 예를 들어 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.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"를 사용하게 됩니다.

파일 대신 모델/정책 텍스트를 사용하려면 modelpolicy 필드를 대신 사용할 수 있습니다:

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의 창립자인 양 루오가 2019년 3분기에 Casbin, Npcap 그리고 Nmap에 대한 작업으로 "Google Open Source Peer Bonus winners"를 수상했다는 것을 발표합니다.

ospb

원본 수상 편지는 여기에서 확인하실 수 있습니다.

Google Open Source Peer Bonus 프로그램은 다음과 같이 설명되어 있습니다:

Google Peer Bonus가 특별한 업적을 달성한 동료를 인정하는 것과 마찬가지로, Open Source Peer Bonus는 오픈 소스에 탁월한 기여를 한 외부인을 인정합니다.

2019년 수상자들에 대한 공지는 다음에서 확인하실 수 있습니다:

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

양과 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은 Casbin의 다른 구현과 유사한 사용법과 API를 공유합니다. 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

문제점이나 풀 요청은 언제든지 환영입니다 :)