Ir al contenido principal

Casbin in 2025: Authorization for the AI Agent Era

· Lectura de 5 min

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

· Lectura de 8 min

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
información

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

información

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.

Autorización en APISIX usando Casbin

· Lectura de 6 min
Rushikesh Tote
Miembro de Casbin

Introducción

APISIX es una puerta de enlace API nativa de la nube de alto rendimiento y escalable basada en Nginx y etcd. Es un proyecto de código abierto de la Apache Software Foundation. Además, lo que hace que APISIX sea tan bueno es el soporte de muchos excelentes complementos integrados que se podrían usar para implementar características como autenticación, monitoreo, enrutamiento, etc. Y el hecho de que los complementos en APISIX se recargan en caliente (sin reinicios) lo hace muy dinámico.

Pero al usar APISIX, puede haber escenarios en los que desees agregar lógica de autorización compleja en tu aplicación. Aquí es donde authz-casbin podría ayudarte, authz-casbin es un complemento de APISIX basado en Lua Casbin que permite una autorización poderosa basada en varios modelos de control de acceso. Casbin es una biblioteca de autorización que soporta modelos de control de acceso como ACL, RBAC, ABAC. Originalmente escrito en Go, ha sido portado a muchos idiomas y Lua Casbin es la implementación en Lua de Casbin. El desarrollo de authz-casbin comenzó cuando propusimos un nuevo complemento para la autorización en el repositorio de APISIX (#4674) al cual los miembros principales estuvieron de acuerdo. Y después de las útiles revisiones que llevaron a algunos cambios importantes y mejoras, el PR (#4710) finalmente se fusionó.

En este blog, usaremos el complemento authz-casbin para mostrar cómo puedes implementar un modelo de autorización basado en el Control de Acceso Basado en Roles (RBAC) en APISIX.

NOTA: Necesitarás usar algún otro complemento o flujo de trabajo personalizado para autenticar al usuario, ya que Casbin solo hará autorización y no autenticación.

Creando un modelo

El complemento utiliza tres parámetros para autorizar cualquier solicitud: sujeto, objeto y acción. Aquí, sujeto es el valor del encabezado de nombre de usuario, que podría ser algo como [username: alice]. Luego, el objeto es la ruta URL que se está accediendo y la acción es el método de solicitud que se está utilizando.

Digamos que queremos crear un modelo con tres recursos en las rutas - /, /res1 y /res2. Y queremos tener un modelo así:

imagen

Esto significaría que todos los usuarios (*) como por ejemplo jack pueden acceder a la página de inicio (/). Y los usuarios con permisos de admin como alice y bob pueden acceder a todas las páginas y recursos (como res1 y res2). Además, restrinjamos a los usuarios sin ningún permiso de administrador a usar solo el método de solicitud GET. Para este escenario, podríamos definir el 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)

Creando una política

Del escenario anterior, la política sería:

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

El comparador del modelo significa:

  1. (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)): O bien el sujeto de la solicitud tiene un rol como el sujeto de la política o el sujeto de la solicitud coincide con el sujeto de la política en keyMatch. keyMatch es una función integrada en Lua Casbin, puedes echar un vistazo a la descripción de la función y más funciones que podrían ser útiles aquí.
  2. keyMatch(r.obj, p.obj): El objeto de la solicitud coincide con el objeto de la política (ruta URL aquí).
  3. keyMatch(r.act, p.act): La acción de la solicitud coincide con la acción de la política (método de solicitud HTTP aquí).

Habilitando el complemento en la ruta

Una vez que hayas creado el modelo y la política, puedes habilitarlo en una ruta utilizando la API de administración de APISIX. Para habilitarlo usando rutas de archivos de modelo y 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": "/*"
}'

Aquí, el campo de nombre de usuario es el nombre del encabezado que usarás para pasar el sujeto. Por ejemplo, si pasarás el encabezado de nombre de usuario como user: alice, usarías "username": "user".

Para usar texto de modelo/política en lugar de archivos, puedes usar los campos model y policy en su lugar:

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 el complemento usando un modelo/política global

Puede haber situaciones en las que desees usar una única configuración de modelo y política en múltiples rutas. Puedes hacerlo primero enviando una solicitud PUT para agregar la configuración de modelo y política a los metadatos del complemento 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"
}'

Y luego para habilitar la misma configuración en alguna ruta, envía una solicitud usando la API de administración:

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

Esto agregará la configuración de metadatos del complemento a la ruta. También puedes actualizar fácilmente la configuración de metadatos del complemento reenviando la solicitud a los metadatos del complemento con la configuración de modelo y política actualizada, el complemento actualizará automáticamente todas las rutas que usan la configuración de metadatos del complemento.

Casos de uso

  • El caso de uso principal de este complemento sería en la implementación de autorización en tus API. Puedes agregar fácilmente este complemento en cualquier ruta de API que estés utilizando con tu modelo de autorización y configuración de política.
  • Si deseas tener un único modelo de autorización para todas tus API, puedes usar el método de modelo/política global. Esto facilita la actualización de la política para todas las rutas, ya que solo necesitas actualizar los metadatos en etcd.
  • Mientras que si te gustaría usar un modelo diferente para cada ruta diferente, puedes usar el método de ruta. Esto es útil cuando diferentes rutas de la API tienen diferentes conjuntos de permisos de usuario. También puedes usar esto cuando estás tratando con políticas más grandes, ya que hará que la autorización sea más rápida cuando se filtre en múltiples rutas.

Yang Luo - Ganador del Premio Google Open Source Peer Bonus

· Lectura de 2 min
Casbin
Cuenta Oficial

Hoy, nos complace anunciar que el fundador de Casbin, Yang Luo ha sido galardonado con el premio "Ganadores del Google Open Source Peer Bonus" por su trabajo en Casbin, Npcap y Nmap en el tercer trimestre de 2019.

ospb

La carta original del premio se puede acceder aquí.

El programa Google Open Source Peer Bonus se describe como:

De la misma manera que un Google Peer Bonus se utiliza para reconocer a un compañero de Google que ha ido más allá, un Open Source Peer Bonus reconoce a personas externas que han hecho contribuciones excepcionales al código abierto.

El anuncio de los ganadores de 2019 está disponible en:

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

Yang y Casbin están listados entre los desarrolladores y proyectos de código abierto que han tenido un impacto relevante, como Git, TensorFlow, V8, CPython, LLVM, proyectos Apache, Angular o Jenkins.

¡Estamos contentos de ver a Casbin reconocido de esta manera por su contribución al código abierto y la seguridad en la nube!

¡Gracias por volar con Casbin!

Reestructuración de nuestra Documentación

· Lectura de un minuto
Yang Luo
Creador de Casbin

Hoy, hemos migrado la documentación de Casbin desde GitHub Wiki a Docs de este sitio web, que está potenciado por Docusaurus. Docusaurus ofrece muchas características impresionantes como mejores estilos de Markdown, búsqueda de texto completo, versionado, traducción.

La documentación aún no es perfecta y todavía necesita ajustes. El código fuente está alojado en GitHub: https://github.com/casbin/casbin-website-v2 .

¡Cualquier contribución o sugerencia es bienvenida!

node-Casbin: Nuevo miembro de la familia Casbin

· Lectura de un minuto
Zixuan Liu
Mantenedor de Casbin

Hoy, hemos portado con éxito Casbin a Node.js, el cual se denomina: node-Casbin.

node-Casbin comparte un uso y API similares con otras implementaciones de Casbin. Los middlewares para Express, Koa2 y Egg.js están listos para usar. El adaptador de almacenamiento para Sequelize también está preparado.

Esperamos que pueda satisfacer bien tus necesidades :)

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

¡Se ha lanzado Casbin Server!

· Lectura de un minuto
Helong Zhang
Mantenedor de Casbin

Algunos de nuestros clientes preguntan si Casbin se puede utilizar como un servicio en lugar de una biblioteca. La respuesta es . Hoy, hemos lanzado el proyecto Casbin Server como una solución concreta para Control de Acceso como Servicio.

Casbin Server está en desarrollo activo por nuestro equipo principal. Tiene varias características:

  • Desarrollado puramente en Golang.
  • Puede manejar miles de instancias de Casbin, así que puedes mover la lógica de aplicación de políticas de múltiples servicios a un solo Casbin Server.
  • gRPC se utiliza para comunicarse con Casbin Server. También consideramos agregar soporte RESTful en un futuro cercano.
  • Se proporciona un portal de administración web amigable para administradores no desarrolladores para gestionar todos los detalles como instancias de Casbin, modelos, almacenamiento de políticas y balanceo de carga.

El código fuente está alojado en GitHub: https://github.com/casbin/casbin-server

Cualquier problema o solicitud de extracción es bienvenido :)