Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Ejemplo 2: Control de acceso multiusuario y RBAC definido por el usuario con OPA y Rego
En este ejemplo, se utilizan OPA y Rego para demostrar cómo se puede implementar el control de acceso en una API para una aplicación multiusuario con funciones personalizadas definidas por los usuarios arrendatarios. También demuestra cómo se puede restringir el acceso en función del inquilino. Este modelo muestra cómo OPA puede tomar decisiones detalladas sobre permisos basándose en la información que se proporciona en un puesto de alto nivel.

Las funciones de los inquilinos se almacenan en datos externos (datos RBAC) que se utilizan para tomar decisiones de acceso a la OPA:
{ "roles": { "tenant_a": { "all_access_role": ["viewData", "updateData"] }, "tenant_b": { "update_data_role": ["updateData"], "view_data_role": ["viewData"] } } }
Estas funciones, cuando las define un usuario arrendatario, deben almacenarse en una fuente de datos externa o en un proveedor de identidad (IdP) que pueda actuar como fuente de verdad al asignar las funciones definidas por el inquilino a los permisos y al propio inquilino.
En este ejemplo, se utilizan dos políticas de la OPA para tomar decisiones de autorización y para examinar cómo estas políticas imponen el aislamiento de los inquilinos. Estas políticas utilizan los datos del RBAC definidos anteriormente.
default allowViewData = false allowViewData = true { input.method == "GET" input.path = ["viewData", tenant_id] input.tenant_id == tenant_id role_permissions := data.roles[input.tenant_id][input.role][_] contains(role_permissions, "viewData") }
Para mostrar cómo funcionará esta regla, considere una consulta OPA que tenga la siguiente entrada:
{ "tenant_id": "tenant_a", "role": "all_access_role", "path": ["viewData", "tenant_a"], "method": "GET" }
La decisión de autorización para esta llamada a la API se toma de la siguiente manera, combinando los datos del RBAC, las políticas de la OPA y la entrada de la consulta de la OPA:
-
Un usuario de
Tenant A
realiza una llamada a la API a./viewData/tenant_a
-
El microservicio de datos recibe la llamada y consulta la
allowViewData
regla, pasando la entrada que se muestra en el ejemplo de entrada de consulta de OPA. -
La OPA utiliza la regla consultada en las políticas de la OPA para evaluar la información proporcionada. La OPA también utiliza los datos del RBAC para evaluar la entrada. La OPA hace lo siguiente:
-
Verifica que el método utilizado para realizar la llamada a la API sea
GET
. -
Verifica que la ruta solicitada sea.
viewData
-
Comprueba que
tenant_id
la ruta es igual a lainput.tenant_id
asociada al usuario. Esto garantiza que se mantenga el aislamiento del inquilino. No se puede autorizar a otro inquilino, incluso con una función idéntica, a realizar esta llamada a la API. -
Extrae una lista de permisos de rol de los datos externos de los roles y los asigna a la variable.
role_permissions
Esta lista se recupera mediante el rol definido por el inquilino que está asociado al usuario eninput.role.
-
Comprueba
role_permissions
si contiene el permisoviewData.
-
-
La OPA devuelve la siguiente decisión al microservicio de datos:
{ "allowViewData": true }
Este proceso muestra cómo la RBAC y el conocimiento de los inquilinos pueden contribuir a tomar una decisión de autorización con la OPA. Para ilustrar mejor este punto, considere la posibilidad de hacer una llamada a la API /viewData/tenant_b
con la siguiente entrada de consulta:
{ "tenant_id": "tenant_b", "role": "view_data_role", "path": ["viewData", "tenant_b"], "method": "GET" }
Esta regla devolvería el mismo resultado que la entrada de la consulta OPA, aunque es para un inquilino diferente que tiene un rol diferente. Esto se debe a que esta llamada es para /tenant_b
y los datos incluidos view_data_role
en el RBAC todavía tienen el viewData
permiso asociado. Para aplicar el mismo tipo de control de acceso/updateData
, puedes usar una regla OPA similar:
default allowUpdateData = false allowUpdateData = true { input.method == "POST" input.path = ["updateData", tenant_id] input.tenant_id == tenant_id role_permissions := data.roles[input.tenant_id][input.role][_] contains(role_permissions, "updateData") }
Esta regla es funcionalmente igual a la allowViewData
regla, pero verifica una ruta y un método de entrada diferentes. La regla sigue garantizando el aislamiento del inquilino y comprueba que el rol definido por el inquilino concede el permiso al que llama a la API. Para ver cómo se puede aplicar esto, examine la siguiente entrada de consulta para ver si hay una llamada a la API a: /updateData/tenant_b
{ "tenant_id": "tenant_b", "role": "view_data_role", "path": ["updateData", "tenant_b"], "method": "POST" }
Esta entrada de consulta, cuando se evalúa con la allowUpdateData
regla, devuelve la siguiente decisión de autorización:
{ "allowUpdateData": false }
Esta llamada no se autorizará. Si bien la persona que llama a la API está asociada a la correcta tenant_id
y llama a la API mediante un método aprobado, input.role
es el definido por el view_data_role
inquilino. view_data_role
No tiene el updateData
permiso; por lo tanto, la llamada a /updateData
no está autorizada. Esta llamada se habría realizado correctamente para un tenant_b
usuario que tiene elupdate_data_role
.