Nel nostro articolo precedente dedicato a Snowflake abbiamo proposto una guida completa al funzionamento di ruoli e privilegi in Snowflake, mostrando come il Role-based Access permetta di costruire una gerarchia di controllo accessi semplice e scalabile.
In questo articolo proseguiamo l'approfondimento sul controllo accessi con consigli e linee guida per impostarlo e gestirlo, accompagnati da un esempio concreto da seguire passo passo.
Quanto trovate qui nasce dall'esperienza diretta maturata in Tasman Analytics, dove abbiamo progettato e implementato gerarchie RBAC in Snowflake per oltre 20 clienti.
Consiglio 1. Partire dal principio del privilegio minimo
Mentre si definisce il modello di accesso e si distribuiscono i permessi tra i vari utenti dell'azienda, l'obiettivo deve essere costruire una struttura in cui ogni utente abbia esattamente i permessi che gli servono (né più né meno) per svolgere il proprio lavoro. Perché mai il nuovo Junior Finance Analyst dovrebbe poter eliminare tabelle, se deve solo interrogare una tabella di bilancio?
Questo concetto è noto come principio del privilegio minimo (Principle of Least Privilege) e, applicato al modello di accesso di Snowflake, porta con sé numerosi vantaggi:
- Riduce rischio e impatto delle minacce esterne: limitare l'accesso degli utenti allo stretto necessario abbassa la probabilità di violazioni di dati accidentali o dolose. E qualora una violazione si verificasse, i danni resterebbero circoscritti alle aree del database accessibili dagli account compromessi.
- Minimizza il rischio di corruzione del sistema e aumenta la stabilità: limitare gli accessi aiuta a prevenire modifiche che potrebbero compromettere integrità o stabilità dei dati; i membri del team con esposizione limitata non dovrebbero poter eliminare i database! :)
- Semplifica audit e monitoraggio: tenere i privilegi al minimo significa anche avere meno privilegi da monitorare e mantenere.
- Agevola la compliance: questo principio facilita inoltre il rispetto dei requisiti normativi in materia di protezione dei dati, quando applicabili (come GDPR o HIPAA), limitando l'accesso ai dati sensibili a quanto strettamente necessario.
Il principio del privilegio minimo è un ottimo punto di partenza, perché bilancia in modo efficace sicurezza e facilità di manutenzione. Alcune aziende possono preferire modelli più semplificati, accettando rischi maggiori, mentre altre possono optare per pratiche più rigorose. Vale la pena approfondire il modello di sicurezza Zero-Trust e il suo legame con il principio del privilegio minimo.
Consiglio 2. Access Role, Functional Role e Service Role
Nell'articolo precedente abbiamo parlato dei diversi tipi di ruolo: account role, database role e instance role. Si tratta di tipologie con differenze tecniche e funzionali sostanziali. Per semplicità, in questo articolo ci concentriamo sugli Account Role.
Esploriamo ora un approccio diverso per definire i ruoli: in base al loro intento. Ecco i 3 tipi di ruolo che vogliamo presentare:
- Gli Access Role servono a controllare l'accesso ai database;
- I Functional Role vengono assegnati agli utenti Snowflake dell'azienda e i livelli di accesso si regolano assegnando loro gli Access Role necessari (secondo il principio del privilegio minimo);
- I Service Role funzionano esattamente come i Functional Role, con l'unica differenza che sono destinati ai servizi e non agli utenti finali (persone).
Da notare che non esiste alcuna differenza tecnica tra Access Role, Functional Role e Service Role: sono tutti creati come Account Role.
Access Role
Gli Access Role nascono per garantire diversi livelli di accesso a database e oggetti del database. Sono i mattoni di base della gerarchia.
Un modo semplice per crearli è prevedere ruoli READ e READWRITE per ogni database esistente:
READ: concede i privilegiSELECTsu tutte le tabelle e viste del database.READWRITE: concede le operazioniSELECT,INSERT,UPDATEeDELETE.
È un buon punto di partenza, ma in base alle esigenze aziendali si possono creare Access Role più granulari (ad esempio per accedere a specifici schemi all'interno di un database).
Functional Role
I Functional Role sono pensati per essere allineati alle funzioni aziendali e includono un mix di Access Role assegnati. Ad esempio, un ruolo DATA_ANALYST può ereditare i privilegi dagli Access Role READ\* * creati per alcuni database. Un ruolo DATA_ENGINEER, invece, può ereditare quelli READWRITE per gli stessi database.
Sono questi i ruoli che verranno assegnati agli utenti finali. Si costruiscono in base alle esigenze reali, usando gli Access Role come mattoni di base (e tenendo sempre presente il principio del privilegio minimo).
Service Role
Questo tipo di ruolo è essenzialmente identico a un Functional Role, con la differenza che viene assegnato a service account anziché agli utenti dell'azienda. Possono essere utilizzati da strumenti di terze parti, come piattaforme BI e di dashboard, o da qualsiasi altro SaaS che richieda accesso READ o READWRITE agli oggetti del database in Snowflake (ad esempio Airbyte, Rudderstack, Mode).
Come per i Functional Role, anche i Service Role si costruiscono in base alle esigenze reali, usando gli Access Role come mattoni di base e tenendo sempre presente il principio del privilegio minimo.
Con questi 3 tipi di ruolo si dispone di tutti i mattoni per costruire una gerarchia di ruoli semplice ed efficace.
Consiglio 3. Costruire una gerarchia di ruoli DRY
Uno dei principi cardine dello sviluppo software è evitare la ripetizione del codice: l'acronimo D.R.Y. sta per "Don't Repeat Yourself". Con Access Role, Functional Role e Service Role si può iniziare ad abbozzare la propria gerarchia di ruoli. Ecco 4 passaggi da iterare.
1. Definire i Functional Role e i Service Role necessari in azienda
Raccogliere i requisiti dai vari utenti Snowflake dell'azienda e stilare un elenco dei Functional Role necessari, con i relativi livelli di accesso. Questo elenco permetterà poi di delineare gli Access Role necessari.
2. Creare gli Access Role
Una volta completato l'elenco dei requisiti, si potranno individuare gli Access Role necessari. A questo punto si possono creare i ruoli e concedere i privilegi adeguati sui rispettivi oggetti del database (ad esempio FINANCE_DB_READ_ROLE).
3. Creare Functional Role e Service Role (e assegnare loro gli Access Role)
Predisposti gli Access Role, c'è tutto il necessario per costruire i Functional Role destinati ai colleghi e i Service Role destinati ai servizi. Per soddisfare i requisiti definiti all'inizio, basta assegnare gli Access Role ai Functional Role e ai Service Role appena creati (ad esempio DATA_ANALYST).
4. Assegnare i Functional Role agli utenti e i Service Role ai service account
La gerarchia dei ruoli è ora completa! L'ultimo passaggio consiste nell'assegnare i Functional Role agli utenti Snowflake e i Service Role ai service account. Se servono aggiustamenti, basta ripetere i passaggi 1-4.
Da evitare…
⛔ Non assegnare gli Access Role direttamente agli utenti finali o ai service account
Saltando il livello dei Functional Role e assegnando un set di Access Role direttamente a un utente, ci si ritroverà a doverlo rifare ogni volta che entrerà nel team una nuova persona con responsabilità simili. Inoltre, ogni volta che servirà un aggiustamento, lo si dovrà applicare manualmente a più utenti.
Avere un Functional Role significa avere un unico punto in cui apportare modifiche: queste verranno applicate automaticamente a tutti gli utenti a cui è stato assegnato quel Functional Role. Il livello degli Access Role serve a standardizzare l'accesso agli oggetti del database all'interno dell'account, non a essere usato direttamente!
⛔ Non assegnare Functional Role ad altri Functional Role
Meglio mantenere le cose semplici! Ogni Functional Role dovrebbe essere una composizione di Access Role. Introdurre dipendenze rischia di complicare la struttura, soprattutto man mano che l'azienda cresce e le posizioni lavorative evolvono nel tempo.
Consiglio 4. Sfruttare i future grant quando si creano gli Access Role
Avete creato gli Access Role per un database, ma vengono aggiunti continuamente nuovi schemi e tabelle e vi ritrovate ad aggiornare costantemente i privilegi? Allora questo consiglio fa per voi! È possibile concedere privilegi sugli schemi futuri di un database, così come su tabelle, viste o altri oggetti futuri. In questo modo, ogni volta che viene creato un nuovo oggetto, il grant viene aggiunto automaticamente.
Usare i future grant nella creazione degli Access Role aiuta a ridurre al minimo le attività di manutenzione, garantendo ai ruoli i privilegi corretti ogni volta che viene creato un nuovo oggetto del database. Non serve più eseguire nuove istruzioni grant ogni volta che il database si arricchisce di nuovi oggetti!
Consiglio 5. Assegnare i Functional Role a SYSADMIN
Quando un ruolo personalizzato viene creato per la prima volta, esiste in isolamento, e lo stesso vale per gli oggetti che crea. Per impostazione predefinita, nemmeno il ruolo ACCOUNTADMIN può modificare o eliminare gli oggetti creati da un ruolo personalizzato. Quindi, quando un ruolo non ha un parent, si rischia di creare nell'account oggetti accessibili solo a quel ruolo.
Assegnando un ruolo personalizzato a SYSADMIN, ci si assicura che almeno i ruoli SYSADMIN (e ACCOUNTADMIN) potranno gestire gli oggetti creati da quello stesso ruolo.
Per concludere, adottate la buona pratica di assegnare i vostri Functional Role a SYSADMIN per impostazione predefinita.
Consiglio 6. Sfruttare la UI di Snowflake
Snowsight offre una funzionalità molto utile per visualizzare la gerarchia dei ruoli esistente nell'account Snowflake. La si può usare per vedere i ruoli creati e le loro relazioni.
Cercate l'opzione Graph in Users & Roles. Potete poi usare l'opzione Focus per esaminare un ruolo specifico e i relativi ruoli parent/child.
Consiglio 7. Probabilmente non vi serve ACCOUNTADMIN per questo…
In altre parole: usate il ruolo giusto per ogni operazione amministrativa. Ricordate il principio del privilegio minimo!
Il ruolo ACCOUNTADMIN ha per impostazione predefinita molti più privilegi di quelli necessari alle operazioni quotidiane, quindi è meglio evitarlo se non c'è una ragione valida. Ecco cosa usare al suo posto per le operazioni più comuni:
- Per creare utenti o ruoli, usate
USERADMIN! - Per gestire i grant (ad esempio assegnare un ruolo a un utente), usate
SECURITYADMIN! - Per creare oggetti come database, schemi o virtual warehouse, usate
SYSADMIN! - Per creare database o oggetti del database come tabelle, viste o altri oggetti, potete usare
SYSADMIN! - Per eseguire operazioni ad-hoc sui dati di una determinata tabella (come una
SELECTo unINSERT), usate un Functional Role adeguato! - Infine, se dovete collegare un servizio di terze parti a Snowflake, non usate assolutamente
ACCOUNTADMIN! Create e utilizzate piuttosto un Service Role appropriato :)
Ad esempio, il pacchetto SELECT dbt-snowflake-monitoring richiede un privilegio speciale, IMPORTED PRIVILEGES, sul database SNOWFLAKE, concedibile solo dal ruolo ACCOUNTADMIN. In questo caso, usate USERADMIN per creare un Access Role dedicato a quel singolo privilegio, concedete il privilegio con ACCOUNTADMIN e usate SECURITYADMIN per assegnare l'Access Role a un Service Role pensato per dbt.
Mettiamo in pratica quanto visto
Contesto
Siete un Data Engineer di un Data Team e state iniziando a implementare Snowflake nella vostra organizzazione. Vi viene chiesto di gestire 3 database:
Ecco una breve descrizione dei 3 database:
HR_DBcontiene dati su dipendenti e organico;FINANCE_DBcontiene dati finanziari, come bilanci e rendiconti;REPORTING_DBcontiene dati per analytics e reporting.
Il vostro compito è ora garantire che tutti, in azienda, abbiano l'accesso corretto a questi database.
Requisiti
Avete interpellato i vari utenti Snowflake dell'azienda sulle loro esigenze e raccolto i seguenti requisiti:
- Richard, un Data Analyst che lavora con i team Finance e HR, chiede di poter leggere tutti i dati di Finance e HR per le sue analisi. Vuole inoltre poter creare tabelle di reporting nel database Reporting.
- Lily, una Data Engineer dell'azienda, deve occuparsi del caricamento dei dati storici nei database Finance e HR.
- Il team Finance sta adottando un nuovo strumento SaaS che deve leggere dati sia dal database Finance sia dal database HR e, in più, scriverà alcuni dati elaborati nel database Finance.
- Vi viene chiesto di configurare un nuovo strumento di BI e dashboard che consumerà i dati dal database Reporting.
Usate il seguente codice per creare i database in Snowflake:
use role SYSADMIN ;
create database FINANCE_DB ;
create database HR_DB ;
create database REPORTING_DB ;
-- Create tables, views, ...
-- ...
Passaggi
Definire i Functional Role e i Service Role
Con i requisiti alla mano, si può iniziare stilando un elenco che chiarisca con precisione cosa serve.
Per i Functional Role:
Per i Service Role:
⚠️ Concedere a uno strumento di terze parti permessi
READWRITEcompleti su tutti gli schemi di un database, come stiamo facendo qui (Finance SaaS), potrebbe non essere la scelta migliore nella realtà. In uno scenario più verosimile, lo strumento avrebbe accesso solo a un insieme specifico di schemi da cui deve leggere o su cui deve scrivere. Ricordate: questo è un modello semplificato.
Creare gli Access Role
In base alle tabelle precedenti, è ora possibile individuare gli Access Role necessari:
HR_READ_ROLEHR_READWRITE_ROLEFINANCE_READ_ROLEFINANCE_READWRITE_ROLEREPORTING_READ_ROLEREPORTING_READWRITE_ROLE
Come accennato, i ruoli READ e READWRITE permetteranno di eseguire rispettivamente istruzioni SELECT oppure SELECT, INSERT, UPDATE e DELETE. Ecco come si presenta:
E queste sono le istruzioni da eseguire in Snowflake:
-- Create Access Roles for HR_DB
use role USERADMIN ;
create role HR_READ_ROLE
comment = 'Access Role READ for HR_DB' ;
create role HR_READWRITE_ROLE
comment = 'Access Role READWRITE for HR_DB' ;
-- Grant Privileges to Access Roles for HR_DB
use role SECURITYADMIN ;
-- Granting Privileges to HR_READ_ROLE
-- Database
grant usage on database HR_DB to role HR_READ_ROLE ;
Espandi codice
Da notare che si possono adottare convenzioni di denominazione fisse per database e Access Role. È possibile creare un unico script e usare il templating per riutilizzarlo e distribuire facilmente più database con i rispettivi Access Role. Ecco un esempio:
-- Assign values to the following variables accordingly
set database_name = 'HR_DB';
set role_read_name = 'HR_READ_ROLE';
set role_readwrite_name = 'HR_READWRITE_ROLE';
-- Create database
use role SYSADMIN ;
create database identifier($database_name) ;
-- Create Access Roles for the database
use role USERADMIN ;
create role identifier($role_read_name) ;
create role identifier($role_readwrite_name) ;
-- Grant Privileges to READ role
Espandi codice
Creare i Functional Role
Con gli Access Role già pronti, costruire i Functional Role che rappresentano le esigenze degli utenti è semplice. È a questo punto che si torna a guardare ai requisiti.
Riprendendo la richiesta di Richard:
🎯 Richard, un Data Analyst che lavora con i team Finance e HR, chiede di poter leggere tutti i dati di Finance e HR per le sue analisi. Vuole inoltre poter scrivere tabelle nel database Reporting.
Ecco come si presenta:
Questa è una semplice implementazione di Access Role e Functional Role per soddisfare le esigenze di Richard. Il ruolo ANALYST_ROLE è il Functional Role ed è parent di HR_READ_ROLE, FINANCE_READ_ROLE e REPORTING_READWRITE_ROLE (tutti Access Role).
A Richard viene quindi assegnato ANALYST_ROLE. Ora può interrogare le tabelle in HR_DB e FINANCE_DB e modificare i dati in REPORTING_DB. E lo stesso ruolo può essere assegnato a chiunque altro nel team di Richard abbia responsabilità simili. 🎉
In Snowflake, ecco come si presenta:
-- Create Functional Role ANALYST_ROLE
use role USERADMIN ;
create role ANALYST_ROLE
comment = 'Functional Role for Data Analysts' ;
-- Grants to role ANALYST_ROLE
use role SECURITYADMIN ;
grant role HR_READ_ROLE to role ANALYST_ROLE ;
grant role FINANCE_READ_ROLE to role ANALYST_ROLE ;
grant role REPORTING_READWRITE_ROLE to role ANALYST_ROLE ;
-- Grant Functional Role to SYSADMIN (good practice mentioned before)
grant role ANALYST_ROLE to role SYSADMIN ;
Espandi codice
Applicando ora gli stessi principi al caso di Lily:
🎯 Lily, una Data Engineer dell'azienda, deve occuparsi del caricamento dei dati storici nei database Finance e HR.
Un esempio analogo per un Functional Role di Data Engineering:
La struttura è simile, ma in questo caso il ruolo ENGINEER_ROLE diventa parent di HR_READWRITE_ROLE e FINANCE_READWRITE_ROLE, e viene poi assegnato a Lily.
L'SQL si presenta così:
-- Create Functional Role ENGINEER_ROLE
use role USERADMIN ;
create role ENGINEER_ROLE
comment = 'Functional Role for Data Engineers' ;
-- Grants to role ANALYST_ROLE
use role SECURITYADMIN ;
grant role HR_READWRITE_ROLE to role ENGINEER_ROLE ;
grant role FINANCE_READWRITE_ROLE to role ENGINEER_ROLE ;
-- Grant Functional Role to SYSADMIN (good practice mentioned before)
grant role ENGINEER_ROLE to role SYSADMIN ;
Espandi codice
Passiamo ora ai requisiti del nuovo Finance SaaS:
🎯 Il team Finance sta adottando un nuovo strumento SaaS che deve leggere dati sia dal database Finance sia dal database HR e, in più, riscriverà alcuni dati elaborati nel database Finance.
Facile, no? Ecco il diagramma:
In questo caso viene creato un nuovo Service Role, chiamato FINANCE_SAAS_ROLE. Si comporta essenzialmente come un Functional Role, con l'unica differenza che verrà usato in modo programmatico e non da una persona. Il ruolo eredita i privilegi da FINANCE_READWRITE_ROLE e HR_READ_ROLE e viene assegnato a un service account Snowflake destinato al servizio.
In codice:
-- Create Service Role FINANCE_SAAS_ROLE
use role USERADMIN ;
create role FINANCE_SAAS_ROLE
comment = 'Service Role for Finance SaaS' ;
-- Grants to role FINANCE_SAAS_ROLE
use role SECURITYADMIN ;
grant role FINANCE_READWRITE_ROLE to role FINANCE_SAAS_ROLE ;
grant role HR_READ_ROLE to role FINANCE_SAAS_ROLE ;
-- Grant Service Role to SYSADMIN (good practice mentioned before)
grant role FINANCE_SAAS_ROLE to role SYSADMIN ;
Espandi codice
Passiamo al caso d'uso dello strumento di BI:
🎯 Vi viene chiesto di configurare un nuovo strumento di BI e dashboard che consumerà i dati dal database Reporting.
Tutto come al solito?
In questo caso, l'unico Access Role di cui BI_ROLE ha bisogno è REPORTING_READ_ROLE. Lo strumento BI potrà ora eseguire query SELECT per popolare le proprie dashboard! 🎉
In codice:
-- Create Service Role BI_ROLE
use role USERADMIN ;
create role BI_ROLE
comment = 'Service Role for BI and Insights Tool' ;
-- Grants to role BI_ROLE
use role SECURITYADMIN ;
grant role REPORTING_READ_ROLE to role BI_ROLE ;
-- Grant Service Role to SYSADMIN (good practice mentioned before)
grant role BI_ROLE to role SYSADMIN ;
-- Grant role to service account
Espandi codice
Tirando le somme
Coperti tutti i casi d'uso, la gerarchia di ruoli iniziale è completa! Nel complesso, ecco come si presenta:
Bonus - Gestire cambiamenti e aggiustamenti
Uno dei vantaggi di una gerarchia DRY è la facilità con cui può essere adattata quando emergono nuovi requisiti. Immaginiamo, ad esempio, che la Data Engineer Lily si sia dimenticata di chiedere l'accesso READWRITE a REPORTING_DB. La richiesta si soddisfa in modo molto semplice:
-- Adjust DATA_ENGINEER functional role
use role SECURITYADMIN ;
grant role REPORTING_READWRITE_ROLE to role DATA_ENGINEER ;
State ora gestendo una gerarchia capace di adattarsi con facilità ai nuovi requisiti di business! 🎉
In questo articolo abbiamo proposto consigli e accorgimenti per costruire una gerarchia RBAC in Snowflake, completati da un esempio concreto per semplificare la vita a chi amministra Snowflake. Conoscete un buon consiglio che qui manca? Fatecelo sapere e aggiorneremo l'articolo!
Miguel Duarte · Data Engineer presso Tasman Analytics
Miguel è Data Engineer presso Tasman Analytics, dove aiuta aziende in rapida crescita a potenziare le proprie capacità in ambito dati. Con un background in BI e Data Analysis, ha maturato una preziosa esperienza tra società di consulenza e aziende di prodotto. Più di recente, spinto dalla curiosità e dalla voglia di confrontarsi maggiormente con gli aspetti tecnici del ciclo di vita dei dati, è passato al Data Engineering. Miguel lavora ogni giorno con strumenti come Snowflake per aiutare le organizzazioni a costruire e ottimizzare la propria infrastruttura dati.