Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Esempio 2: controllo degli accessi multi-tenant e RBAC definito dall'utente con OPA e Rego
Questo esempio utilizza OPA e Rego per dimostrare come implementare il controllo degli accessi su un'API per un'applicazione multi-tenant con ruoli personalizzati definiti dagli utenti tenant. Dimostra inoltre come è possibile limitare l'accesso in base a un tenant. Questo modello mostra come OPA può prendere decisioni granulari sulle autorizzazioni sulla base delle informazioni fornite in un ruolo di alto livello.

I ruoli degli inquilini sono archiviati in dati esterni (dati RBAC) utilizzati per prendere decisioni di accesso per OPA:
{ "roles": { "tenant_a": { "all_access_role": ["viewData", "updateData"] }, "tenant_b": { "update_data_role": ["updateData"], "view_data_role": ["viewData"] } } }
Questi ruoli, se definiti da un utente tenant, devono essere archiviati in un'origine dati esterna o in un provider di identità (IdP) che possa fungere da fonte di verità durante la mappatura dei ruoli definiti dal tenant alle autorizzazioni e al tenant stesso.
Questo esempio utilizza due politiche in OPA per prendere decisioni di autorizzazione e per esaminare come queste politiche impongono l'isolamento dei tenant. Queste politiche utilizzano i dati RBAC definiti in precedenza.
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") }
Per mostrare come funzionerà questa regola, considera una query OPA con il seguente input:
{ "tenant_id": "tenant_a", "role": "all_access_role", "path": ["viewData", "tenant_a"], "method": "GET" }
Una decisione di autorizzazione per questa chiamata API viene presa come segue, combinando i dati RBAC, le politiche OPA e l'input della query OPA:
-
Un utente di
Tenant A
effettua una chiamata API a./viewData/tenant_a
-
Il microservizio Data riceve la chiamata e interroga la
allowViewData
regola, passando l'input mostrato nell'esempio di input della query OPA. -
OPA utilizza la regola richiesta nelle politiche OPA per valutare l'input fornito. L'OPA utilizza anche i dati dei dati RBAC per valutare l'input. L'OPA esegue le seguenti operazioni:
-
Verifica che il metodo utilizzato per effettuare la chiamata API sia.
GET
-
Verifica che il percorso richiesto sia.
viewData
-
Verifica che il valore
tenant_id
nel percorso sia uguale a quelloinput.tenant_id
associato all'utente. Ciò garantisce il mantenimento dell'isolamento degli inquilini. Un altro tenant, anche con un ruolo identico, non può essere autorizzato a effettuare questa chiamata API. -
Estrae un elenco di autorizzazioni di ruolo dai dati esterni dei ruoli e le assegna alla variabile.
role_permissions
Questo elenco viene recuperato utilizzando il ruolo definito dal tenant associato all'utente ininput.role.
-
Verifica se
role_permissions
contiene l'autorizzazioneviewData.
-
-
OPA restituisce la seguente decisione al microservizio Data:
{ "allowViewData": true }
Questo processo mostra come RBAC e la consapevolezza degli inquilini possono contribuire a prendere una decisione di autorizzazione con OPA. Per illustrare ulteriormente questo punto, considera una chiamata API a /viewData/tenant_b
con il seguente input di query:
{ "tenant_id": "tenant_b", "role": "view_data_role", "path": ["viewData", "tenant_b"], "method": "GET" }
Questa regola restituirebbe lo stesso output dell'input della query OPA, sebbene sia destinata a un tenant diverso che ha un ruolo diverso. Questo perché questa chiamata è destinata /tenant_b
e ai dati view_data_role
in RBAC è ancora associata l'viewData
autorizzazione. Per applicare lo stesso tipo di controllo degli accessi per/updateData
, puoi utilizzare una regola OPA simile:
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") }
Questa regola è funzionalmente la stessa della allowViewData
regola, ma verifica un percorso e un metodo di input diversi. La regola garantisce comunque l'isolamento dei tenant e verifica che il ruolo definito dal tenant conceda l'autorizzazione al chiamante dell'API. Per vedere come ciò potrebbe essere applicato, esamina il seguente input di query per una chiamata API a: /updateData/tenant_b
{ "tenant_id": "tenant_b", "role": "view_data_role", "path": ["updateData", "tenant_b"], "method": "POST" }
Questo input di query, se valutato con la allowUpdateData
regola, restituisce la seguente decisione di autorizzazione:
{ "allowUpdateData": false }
Questa chiamata non sarà autorizzata. Sebbene il chiamante dell'API sia associato all'indirizzo corretto tenant_id
e stia chiamando l'API utilizzando un metodo approvato, input.role
è definito dal view_data_role
tenant. view_data_role
Non dispone dell'updateData
autorizzazione, pertanto la chiamata a non è autorizzata. /updateData
Questa chiamata avrebbe avuto successo per un tenant_b
utente che dispone diupdate_data_role
.