Pular para o conteúdo principal

Casbin in 2025: Authorization for the AI Agent Era

· 5 min de leitura

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

· 8 min de leitura

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
informação

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

informação

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.

Autorização no APISIX usando Casbin

· 6 min de leitura
Rushikesh Tote
Membro do Casbin

Introdução

APISIX é um gateway de API nativo da nuvem de alta performance e escalável baseado em Nginx e etcd. É um projeto de código aberto da Apache Software Foundation. Além disso, o que torna o APISIX tão bom é o suporte de muitos ótimos plugins integrados que podem ser usados para implementar recursos como autenticação, monitoramento, roteamento, etc. E o fato de que os plugins no APISIX são recarregados em tempo real (sem reinicializações) o torna muito dinâmico.

Mas ao usar o APISIX, podem surgir cenários em que você queira adicionar lógica de autorização complexa em sua aplicação. É aqui que o authz-casbin pode ajudá-lo, authz-casbin é um plugin do APISIX baseado no Lua Casbin que permite uma autorização poderosa baseada em vários modelos de controle de acesso. Casbin é uma biblioteca de autorização que suporta modelos de controle de acesso como ACL, RBAC, ABAC. Originalmente escrito em Go, foi portado para muitas linguagens e Lua Casbin é a implementação em Lua do Casbin. O desenvolvimento do authz-casbin começou quando propusemos um novo plugin para autorização no repositório do APISIX (#4674) ao qual os membros principais concordaram. E após as revisões úteis que levaram a algumas mudanças importantes e melhorias, o PR (#4710) foi finalmente mesclado.

Neste blog, usaremos o plugin authz-casbin para mostrar como você pode implementar um modelo de autorização baseado em Controle de Acesso Baseado em Funções (RBAC) no APISIX.

NOTA: Você precisará usar algum outro plugin ou fluxo de trabalho personalizado para autenticar o usuário, já que o Casbin fará apenas autorização e não autenticação.

Criando um modelo

O plugin usa três parâmetros para autorizar qualquer solicitação - sujeito, objeto e ação. Aqui, sujeito é o valor do cabeçalho do nome de usuário, que poderia ser algo como [username: alice]. Então, o objeto é o caminho da URL que está sendo acessado e a ação é o método de solicitação usado.

Vamos dizer que queremos criar um modelo com três recursos nos caminhos - /, /res1 e /res2. E queremos ter um modelo assim:

imagem

Isso significaria que todos os usuários (*) como por exemplo jack podem acessar a página inicial (/). E usuários com permissões de admin como alice e bob podem acessar todas as páginas e recursos (como res1 e res2). Além disso, vamos restringir usuários sem quaisquer permissões de admin a usar apenas o método de solicitação GET. Para este cenário, poderíamos definir o modelo como:

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

Criando uma política

Do cenário acima, a política seria:

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

O matcher do modelo significa:

  1. (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)): Ou o sujeito da solicitação tem um papel como o sujeito da política ou o sujeito da solicitação corresponde ao sujeito da política em keyMatch. keyMatch é uma função integrada no Lua Casbin, você pode dar uma olhada na descrição da função e em mais funções que podem ser úteis aqui.
  2. keyMatch(r.obj, p.obj): O objeto da solicitação corresponde ao objeto da política (caminho da URL aqui).
  3. keyMatch(r.act, p.act): A ação da solicitação corresponde à ação da política (método de solicitação HTTP aqui).

Habilitando o plugin em uma rota

Uma vez que você tenha criado o modelo e a política, você pode habilitá-los em uma rota usando a API Admin do APISIX. Para habilitá-los usando caminhos de arquivos de modelo e política:

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

Aqui, o campo de nome de usuário é o nome do cabeçalho que você usará para passar o sujeito. Por exemplo, se você for passar o cabeçalho de nome de usuário como user: alice, você usaria "username": "user".

Para usar texto de modelo/política em vez de arquivos, você pode usar os campos model e policy em vez disso:

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

Habilitando o plugin usando um modelo/política global

Pode haver situações em que você queira usar uma única configuração de modelo e política em várias rotas. Você pode fazer isso primeiro enviando uma solicitação PUT para adicionar a configuração de modelo e política aos metadados do plugin por:

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

E então para habilitar a mesma configuração em alguma rota, envie uma solicitação usando a API Admin:

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

Isso adicionará a configuração de metadados do plugin à rota. Você também pode facilmente atualizar a configuração de metadados do plugin reenviando a solicitação aos metadados do plugin com a configuração de modelo e política atualizada, o plugin atualizará automaticamente todas as rotas usando a configuração de metadados do plugin.

Casos de Uso

  • O principal caso de uso deste plugin seria na implementação de autorização em suas APIs. Você pode facilmente adicionar este plugin em qualquer rota de API que você esteja usando com seu modelo de autorização e configuração de política.
  • Se você quiser ter um único modelo de autorização para todas as suas APIs, você pode usar o método de modelo/política global. Isso facilita a atualização da política para todas as rotas, já que você só precisa atualizar os metadados no etcd.
  • Enquanto se você gostaria de usar um modelo diferente para cada rota diferente, você pode usar o método de rota. Isso é útil quando diferentes rotas de API têm diferentes conjuntos de permissões de usuário. Você também pode usar isso quando estiver lidando com políticas maiores, pois tornará a autorização mais rápida quando filtrada em várias rotas.

Yang Luo - Vencedor do Prêmio Google Open Source Peer Bonus

· 2 min de leitura
Casbin
Conta Oficial

Hoje, temos o prazer de anunciar que o fundador do Casbin, Yang Luo, foi premiado com o "vencedores do Google Open Source Peer Bonus" por seu trabalho no Casbin, Npcap e Nmap no 3º trimestre de 2019.

ospb

A carta de premiação original pode ser acessada aqui.

O programa Google Open Source Peer Bonus é descrito como:

Da mesma forma que um Google Peer Bonus é usado para reconhecer um colega do Google que se destacou, um Open Source Peer Bonus reconhece pessoas externas que fizeram contribuições excepcionais para o código aberto.

O anúncio dos vencedores de 2019 está disponível em:

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

Yang e Casbin estão listados entre desenvolvedores e projetos de código aberto que têm um impacto relevante, como Git, TensorFlow, V8, CPython, LLVM, projetos Apache, Angular ou Jenkins.

Estamos felizes em ver o Casbin reconhecido desta forma por sua contribuição ao código aberto e à segurança na nuvem!

Obrigado por voar com Casbin!

Reestruturando nossa Documentação

· Leitura de um minuto
Yang Luo
Criador do Casbin

Hoje, migramos a documentação do Casbin do Wiki do GitHub para Docs deste site, que é alimentado pelo Docusaurus. O Docusaurus oferece muitos recursos incríveis como melhores estilos de Markdown, busca de texto completo, versionamento, tradução.

A documentação ainda não está perfeita e ainda precisa de ajustes. O código fonte está hospedado no GitHub: https://github.com/casbin/casbin-website-v2 .

Qualquer contribuição ou sugestão é bem-vinda!

node-Casbin: Novo Membro da Família Casbin

· Leitura de um minuto
Zixuan Liu
Mantenedor do Casbin

Hoje, nós portamos com sucesso o Casbin para Node.js, que é nomeado como: node-Casbin.

node-Casbin compartilha o uso similar e a API com outras implementações do Casbin. Os middlewares para Express, Koa2 e Egg.js estão prontos para uso. O adaptador de armazenamento para Sequelize também está preparado.

Espero que possa atender bem às suas necessidades :)

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

O Casbin Server foi lançado!

· Leitura de um minuto
Helong Zhang
Mantenedor do Casbin

Alguns de nossos clientes perguntam se o Casbin pode ser usado como um serviço em vez de uma biblioteca. A resposta é SIM. Hoje, lançamos o projeto Casbin Server como uma solução concreta para Controle de Acesso como um Serviço.

Casbin Server está em desenvolvimento ativo pela nossa equipe principal. Ele possui várias características:

  • Desenvolvido puramente em Golang.
  • Pode gerenciar milhares de instâncias do Casbin, para que você possa mover a lógica de aplicação de políticas de múltiplos serviços para um único Casbin Server.
  • gRPC é usado para se comunicar com o Casbin Server. Também consideramos adicionar suporte RESTful em um futuro próximo.
  • Um portal administrativo amigável é fornecido para administradores não desenvolvedores gerenciarem todos os detalhes como instâncias do Casbin, modelos, armazenamento de políticas e balanceamento de carga.

O código-fonte está hospedado no GitHub: https://github.com/casbin/casbin-server

Quaisquer problemas ou pull requests são bem-vindos :)