Quando si amministrano i dati aziendali all’interno di una qualsiasi piattaforma utilizzata da molte persone, per questioni di sicurezza prima o poi emergerà la necessità di assegnare ruoli e permessi agli utenti, in modo che ciascuno abbia visibilità e accesso soltanto a quanto di propria competenza. Per esempio, alcuni utenti devono avere accesso ai dati in sola lettura, mentre altri devono poter scrivere soltanto su alcune risorse o API; inoltre, dovranno sicuramente esserci persone con accesso illimitato su tutte le risorse disponibili.

Esiste un meccanismo di autorizzazione costruito per gestire casi di questo tipo, ed è chiamato Role‑Based Access Control (RBAC). Nel corso di questo articolo vedremo come questo tipo di soluzione è stato implementato all’interno di Mia‑Platform, e come abbiamo risolto le sfide che questa implementazione ha portato.

 

Cos’è il RBAC?

Il RBAC è un meccanismo di autorizzazione che ha come elementi base i concetti di ruoli, permessi e gruppi di utenti. Questi elementi permettono di creare modelli di accesso sicuro, basati sulle funzioni reali che le persone hanno all’interno dell’organizzazione invece che sulle azioni che devono poter svolgere.

 

RBAC vs ABAC

Quando si parla di RBAC viene spesso menzionato anche l'Attribute‑Based Access Control (ABAC), un altro meccanismo di autorizzazione costruito sulle basi del RBAC stesso. L'ABAC permette di definire il modello di sicurezza anche su alcune caratteristiche delle richieste o degli utenti. Ad esempio, le caratteristiche possono includere la posizione geografica, il fuso orario, il meccanismo di autenticazione, il tipo di dispositivo o qualunque cookie presente mentre l’utente esegue l’accesso.

 

I benefici del RBAC

Il RBAC si è rivelato particolarmente efficace per la gestione dei ruoli e viene adottato da sempre più organizzazioni, tanto che ormai è uno dei modelli di controllo degli accessi più diffuso. Infatti, benché nella fase di implementazione sia necessaria una pianificazione meticolosa e uno studio approfondito dei permessi, una volta a regime il RBAC porta diversi benefici, tra cui:

  • Governance più semplice: per assegnare un ruolo a un nuovo utente gli amministratori di sistema non dovranno scegliere a mano i singoli permessi, ma semplicemente selezionare il ruolo già creato. Inoltre, qualora alcuni permessi dovessero essere aggiunti o revocati, una modifica unica al ruolo sarà immediatamente propagata a tutti gli utenti;
  • Riduzione dei costi: dal momento che la governance sarà più semplice, aumenterà anche la velocità di assegnazione dei permessi, e i costi legati a queste attività diminuiranno drasticamente;
  • Riduzione dell’attività manuale: non dovendo più cercare e assegnare i singoli permessi a mano, sarà più facile creare delle logiche di automazione. Inoltre, i rischi di errori nell’assegnazione saranno significativamente ridotti;
  • Maggiore sicurezza: grazie alla riduzione degli errori di assegnazione, diminuirà anche il rischio di accessi indesiderati a risorse critiche, e la sicurezza sarà più facile da garantire;
  • Monitoraggio più semplice: non dovendo controllare i singoli permessi assegnati ad ogni utente, gli amministratori di sistema potranno monitorare chi ha accesso alle risorse aziendali semplicemente consultando i ruoli.

 

Il caso d’uso di Mia‑Platform

Perché in Mia‑Platform abbiamo intrapreso il progetto di adozione del RBAC?

All’interno della nostra piattaforma gli utenti possono eseguire diverse azioni quali, ad esempio: vedere e collaborare su diversi progetti, configurare i loro microservizi e creare nuove repository, vedere le risorse utilizzate, riavviare i Pod Kubernetes, e molto altro. Avevamo quindi bisogno di limitare la possibilità di compiere azioni all’interno della piattaforma, per far sì che ogni azione venisse svolta soltanto dagli utenti che dovevano effettivamente eseguirla perché parte integrante del loro lavoro.

Di seguito vedremo i passaggi chiave che ci hanno portato a definire come sviluppare il nostro RBAC.

 

Fase 1: identificazione di permessi e ruoli

Per implementare la nostra soluzione RBAC siamo partiti dall’identificazione dei permessi e dei ruoli già attivi nella nostra piattaforma, in modo da creare le entità sulle quali il RBAC dovesse essere poi modellato.

I permessi individuati sono stati i seguenti:

  • vedere le informazioni di un progetto,
  • salvare la configurazione di un progetto,
  • deployare un progetto,
  • modificare le variabili segrete.
I ruoli individuati per svolgere le azioni sopra elencate sono stati: Amministratore di Progetto, Editor, Viewer.
Per esempio, un Editor può vedere le informazioni di un progetto e può eseguire operazioni in fase di deploy, ma non può modificare le variabili segrete, le quali sono responsabilità solo degli Amministratori.

 

Una volta individuate le nostre entità RBAC il passaggio successivo era quello di integrarle all’interno del nostro software. Ma qual era la strada giusta? Abbiamo dovuto affrontare molte sfide prima di trovare una risposta definitiva su come volessimo che il RBAC funzionasse.

 

Fase 2: collocamento del RBAC all’esterno della codebase

Il primo requisito fondamentale che volevamo per il nostro RBAC era che i controlli di autorizzazione non fossero incorporati all’interno di ciascuna API. Infatti, questo non solo avrebbe comportato una duplicazione del codice all’interno del nostro software, ma ci avrebbe portato anche a dover distribuire le configurazioni di autorizzazione tramite il codice, rendendo le configurazioni hardcoded e difficili da mantenere nel tempo. Inoltre, dato che le nostre API sono sviluppate attraverso diversi microservizi scritti in linguaggi differenti, questi controlli sarebbero dovuti essere scritti in diversi linguaggi, diventando difficili da astrarre e raggruppare in librerie software riutilizzabili.

Per questi motivi abbiamo deciso che il RBAC dovesse risiedere all’esterno della nostra codebase. Questa prima decisione ci ha portati ad affrontare una seconda sfida.

 

Fase 3: adozione del Sidecar Container Pattern

Stabilito che il RBAC fosse collocato all’esterno dei microservizi, è nata l’esigenza di creare un altro microservizio che lo gestisse. Una possibile soluzione poteva essere lo sviluppo di un servizio RBAC che ogni altro servizio dovesse contattare per sapere se autorizzare o meno la richiesta in entrata; ma qualsiasi soluzione che avesse un RBAC manager API separato portava ad un’architettura che presentava un single point of failure.

Basandoci sulla definizione di Pod Kubernetes, abbiamo deciso di adottare il Sidecar Container Pattern, aggiungendo un container addizionale (chiamato in gergo Sidecar), collocato all’interno di ogni servizio che necessitava del RBAC. Il Sidecar si occupa di implementare i controlli di autorizzazione, intercettando tutte le richieste in entrata e inoltrandole  al vero e proprio microservizio soltanto se superano i controlli di autorizzazione.

 

Fase 4: adozione dell'Open Policy Agent (OPA)

Trovata la soluzione adatta per la nostra architettura, agnostica rispetto ai linguaggi e senza single point of failure, si è presentata un’altra questione: in che modo sviluppare e implementare i controlli di autorizzazione?

Una configurazione decentralizzata sarebbe stata difficile da mantenere. Una possibile soluzione poteva essere implementare un servizio che si connettesse a un database, eseguisse una query per capire se l’utente che stava richiedendo accesso all’API avesse i giusti permessi, e che poi accettasse o rifiutasse la richiesta di conseguenza.
Questa soluzione però, avrebbe limitato ciò che avremmo potuto fare con il nostro RBAC. Come avremmo fatto se, ad esempio, avessimo voluto implementare un permesso specifico che permettesse all’utente di modificare alcune proprietà di un documento che altrimenti sarebbero rimaste riservate? Questa strada non era percorribile.

Perciò abbiamo deciso che il nostro servizio RBAC dovesse supportare alcune policy definite dall’utente per valutare se accettare o meno la richiesta. Dal momento che non volevamo implementare un nuovo linguaggio per la valutazione delle policy perché sarebbe stata un’operazione lunga e dispendiosa, oltre che difficile da mantenere nel tempo, abbiamo deciso di adottare Open Policy Agent (OPA) nella nostra infrastruttura. Il nostro servizio RBAC utilizza OPA per valutare specifiche policy (scritte nel linguaggio Rego), che permettono di ottenere molto più di un semplice controllo sui permessi. Oltre a verificare se un utente possiede un certo ruolo o permesso, infatti, possiamo anche arricchire le policy con informazioni sulle richieste e sugli utenti (per supportare totalmente le verifiche ABAC), o anche fornire il payload dell’API per permettere di filtrare delle proprietà o di consolidare alcuni dati.

 

Conclusioni

Questo è il percorso che abbiamo intrapreso per implementare il RBAC all’interno della nostra piattaforma. Ricapitolando, abbiamo innanzitutto individuato i ruoli e i permessi, definendo le entità sulle quali modellare il RBAC. Poi, per facilitare la manutenzione e per essere agnostici rispetto ai linguaggi, abbiamo deciso di tenere il RBAC all’esterno della codebase. In seguito, evitando di creare un microservizio dedicato al RBAC e inserendolo invece in un Sidecar Container posto all’interno dei microservizi, abbiamo ottenuto un’architettura priva di single points of failure. Infine, grazie all’adozione di OPA siamo riusciti a garantire una configurazione centralizzata, e pertanto più semplice da mantenere, delle policy. 

La nostra soluzione RBAC migliora la sicurezza dei dati, fornendo una governance dei permessi a 360°. A partire dal rilascio di Mia‑Platform v9.0 la nostra soluzione RBAC sarà disponibile a tutti gli utilizzatori della piattaforma, e potranno integrarla nei loro progetti definendo le loro policy, i ruoli e i permessi. 


L’articolo è stato scritto da Federico Maggi, Senior Technical Leader.

Torna all'inizio

CLICCA QUI per scaricare il White Paper: "Kubernetes 101: Guida al sistema operativo del futuro"

© MIA s.r.l. Tutti i diritti riservati