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

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. 
When I check the IAM of a Resource Group under this Subscription, you can see that I have inherited Owner access from the
subscription. 
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
The request_definition is the query template of the system. For example, a request
alice, write, data1can be interpreted as "Can subject Alice perform the action 'write' on object 'data1'?".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'.The policy_effect defines the effect of the policy.
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

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

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

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

Action Matching Visual representation

Object Matching Visual representation

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.
Autorizzazione in APISIX utilizzando Casbin
Introduzione
APISIX è un gateway API cloud nativo ad alte prestazioni e scalabile basato su Nginx e etcd. È un progetto open source della Apache Software Foundation. Oltre a ciò, ciò che rende APISIX così buono è il supporto di molti ottimi plugin integrati che possono essere utilizzati per implementare funzionalità come autenticazione, monitoraggio, routing, ecc. E il fatto che i plugin in APISIX siano ricaricati in modalità "hot" (senza riavvii) lo rende molto dinamico.
Tuttavia, durante l'uso di APISIX, potrebbero verificarsi scenari in cui potresti voler aggiungere logica di autorizzazione complessa nella tua applicazione. Questo è dove authz-casbin potrebbe aiutarti, authz-casbin è un plugin di APISIX basato su Lua Casbin che abilita un'autorizzazione potente basata su vari modelli di controllo degli accessi. Casbin è una libreria di autorizzazione che supporta modelli di controllo degli accessi come ACL, RBAC, ABAC. Inizialmente scritto in Go, è stato portato in molte lingue e Lua Casbin è l'implementazione Lua di Casbin. Lo sviluppo di authz-casbin è iniziato quando abbiamo proposto un nuovo plugin per l'autorizzazione nel repository di APISIX (#4674) a cui i membri core hanno dato il loro consenso. E dopo le utili revisioni che hanno portato a alcune modifiche e miglioramenti principali, la PR (#4710) è stata finalmente unita.
In questo blog, useremo il plugin authz-casbin per mostrare come puoi implementare un modello di autorizzazione basato sul Controllo degli Accessi Basato sui Ruoli (RBAC) in APISIX.
NOTA: Dovrai utilizzare qualche altro plugin o flusso di lavoro personalizzato per autenticare l'utente poiché Casbin farà solo autorizzazione e non autenticazione.
Creazione di un modello
Il plugin utilizza tre parametri per autorizzare qualsiasi richiesta - soggetto, oggetto e azione. Qui, il soggetto è il valore dell'intestazione del nome utente, che potrebbe essere qualcosa come [username: alice]. Quindi, l'oggetto è il percorso URL che viene acceduto e l'azione è il metodo di richiesta utilizzato.
Diciamo che vogliamo creare un modello con tre risorse nei percorsi - /`\`, /res1\ e `/res2`. E vogliamo avere un modello come questo:

Ciò significherebbe che tutti gli utenti (*`\`) come ad esempio jack\ possono accedere alla homepage (/`\`). E gli utenti con autorizzazioni di admin\ come alice`\` e bob\ possono accedere a tutte le pagine e le risorse (come res1`\` e res2\). Inoltre, limitiamo gli utenti senza alcuna autorizzazione di amministratore all'uso solo del metodo di richiesta `GET`. Per questo scenario, potremmo definire il modello come:
[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)
Creazione di una politica
Dallo scenario sopra descritto, la politica sarebbe:
p, *, /, GET
p, admin, *, *
g, alice, admin
g, bob, admin
Il matcher dal modello significa:
(g(r.sub, p.sub) || keyMatch(r.sub, p.sub))`\`: O il soggetto della richiesta ha un ruolo come il soggetto della politica o il soggetto della richiesta corrisponde al soggetto della politica inkeyMatch\. `keyMatch` è una funzione incorporata in Lua Casbin, puoi dare un'occhiata alla descrizione della funzione e ad altre funzioni simili che potrebbero essere utili qui.- `
keyMatch(r.obj, p.obj)`: L'oggetto della richiesta corrisponde all'oggetto della politica (percorso URL qui). - `
keyMatch(r.act, p.act)`: L'azione della richiesta corrisponde all'azione della politica (metodo di richiesta HTTP qui).
Abilitazione del plugin sulla route
Una volta creato il modello e la politica, puoi abilitarlo su una route utilizzando l'API di amministrazione di APISIX. Per abilitarlo utilizzando i percorsi dei file del modello e del policy:
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": "/*"
}'
Qui, il campo username è il nome dell'intestazione che utilizzerai per passare il soggetto. Ad esempio, se passerà l'intestazione username come user: alice, dovresti usare "username": "user".
Per utilizzare il testo del modello/policy invece dei file, puoi utilizzare i campi model e policy al posto di:
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": "/*"
}'
Abilitazione del plugin utilizzando un modello/policy globale
Potrebbero esserci situazioni in cui potresti voler utilizzare una singola configurazione di modello e policy su più route. Puoi farlo prima inviando una richiesta PUT per aggiungere la configurazione del modello e della policy ai metadati del plugin:
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 poi per abilitare la stessa configurazione su una rotta, invia una richiesta utilizzando l'API di 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/*"
}'
Questo aggiungerà la configurazione dei metadati del plugin alla rotta. Puoi anche facilmente aggiornare la configurazione dei metadati del plugin rispedendo la richiesta ai metadati del plugin con la configurazione del modello e della politica aggiornati, il plugin aggiornerà automaticamente tutte le rotte che utilizzano i metadati del plugin.
Casi d'uso
- Il caso d'uso principale di questo plugin sarebbe nell'implementazione dell'autorizzazione nelle tue API. Puoi facilmente aggiungere questo plugin su qualsiasi rotta API che stai utilizzando con il tuo modello di autorizzazione e configurazione della politica.
- Se desideri avere un singolo modello di autorizzazione per tutte le tue API, puoi utilizzare il metodo del modello/politica globale. Questo rende facile l'aggiornamento della politica per tutte le rotte, poiché devi solo aggiornare i metadati in etcd.
- Mentre se desideri utilizzare un modello diverso per ogni rotta diversa, puoi utilizzare il metodo della rotta. Questo è utile quando diverse route API hanno diversi set di permessi utente. Puoi anche utilizzare questo quando hai a che fare con politiche più grandi, poiché renderà l'autorizzazione più veloce quando filtrata in più route.
Yang Luo - Vincitore del Google Open Source Peer Bonus
Oggi, siamo lieti di annunciare che il fondatore di Casbin, Yang Luo è stato insignito del premio "Google Open Source Peer Bonus winners" per il suo lavoro su Casbin, Npcap e Nmap nel terzo trimestre del 2019.

La lettera originale del premio può essere acceduta qui.
Il programma Google Open Source Peer Bonus è descritto come:
Allo stesso modo in cui un Google Peer Bonus viene utilizzato per riconoscere un collega Googler che ha superato le aspettative, un Open Source Peer Bonus riconosce persone esterne che hanno fatto contributi eccezionali all'open source.
L'annuncio per i vincitori del 2019 è disponibile all'indirizzo:
https://opensource.googleblog.com/2020/01/announcing-2019-second-cycle-google.html
Yang e Casbin sono elencati tra gli sviluppatori e i progetti open source che hanno un impatto rilevante là fuori, come Git, TensorFlow, V8, CPython, LLVM, progetti Apache, Angular o Jenkins.
Siamo lieti di vedere Casbin riconosciuto in questo modo per il suo contributo all'open source e alla sicurezza del cloud!
Grazie per volare con Casbin!
Rielaborazione della nostra Documentazione
Oggi, abbiamo migrato la documentazione di Casbin dalla GitHub Wiki alla sezione Docs di questo sito web, Docusaurus offre molte fantastiche funzionalità come stili Markdown migliori, ricerca full-text, versionamento, traduzione.
La documentazione non è ancora perfetta e necessita ancora di ottimizzazione. Il codice sorgente è ospitato
Qualsiasi contributo o suggerimento è il benvenuto!
node-Casbin: Nuovo Membro della Famiglia Casbin
Oggi, abbiamo portato con successo Casbin su Node.js, che è stato chiamato:
node-Casbin condivide un utilizzo e API simili I middleware per Express, Koa2 e Egg.js sono pronti L'adattatore di storage per Sequelize è anche preparato.
Spero possa soddisfare le tue esigenze bene :)
Casbin Server è stato lanciato!
Alcuni dei nostri clienti chiedono se Casbin può essere utilizzato come servizio invece che come libreria. La risposta è SÌ. Oggi, abbiamo lanciato il progetto Casbin Server come soluzione concreta per
Casbin Server è in fase di sviluppo attivo da parte del nostro team principale. Presenta diverse funzionalità:
- Sviluppato esclusivamente in Golang.
- Può gestire migliaia di istanze Casbin, consentendo di spostare la logica di applicazione dei criteri da più servizi in un unico Casbin Server.
- gRPC viene utilizzato per comunicare con Casbin Server. Consideriamo anche di aggiungere il supporto RESTful nel prossimo futuro.
- È fornito un portale amministratore web intuitivo per consentire agli amministratori non sviluppatori di gestire tutti i dettagli come istanze Casbin, modelli, archiviazione dei criteri e bilanciamento del carico.
Il codice sorgente è ospitato su GitHub: https://github.com/casbin/casbin-server
Tutte le segnalazioni di problemi o le richieste di pull sono benvenute :)