Usare RBAC con ABAC

Importante

RBAC è in anteprima pubblica. ABAC è ora disponibile a livello generale. Questa pagina descrive come interagiscono i due.

Il controllo degli accessi in base al ruolo e il controllo degli accessi in base all'attributo in Unity Catalog sono controlli complementari progettati per collaborare. Rispondono a domande diverse:

  • RBAC controlla con quale identità un utente opera durante una sessione. Un utente assume un ruolo per agire con le autorizzazioni del ruolo anziché con le proprie. Usa RBAC per assegnare a un utente più insiemi distinti di autorizzazioni, tra i quali può passare esplicitamente, ad esempio separando gli accessi tra studi clinici, progetti o livelli di sensibilità.
  • ABAC controlla quali dati l'identità attiva può vedere, riga per riga o colonna per colonna. I criteri sono associati ai dati tramite tag governati e si applicano all’identità che esegue la query. Usa il controllo degli accessi basato sugli attributi (ABAC) per applicare in modo coerente il filtro o il mascheramento a molte tabelle in base agli attributi dei dati.

Il controllo degli accessi basato sui ruoli (RBAC) imposta l'identità attiva per la sessione, e il controllo degli accessi basato sugli attributi (ABAC) valuta le proprie politiche in base a tale identità. Questa pagina illustra come l'interazione si svolge in pratica, il comportamento delle funzioni SQL correlate all'identità e i modelli di utilizzo combinato.

Come si comportano le funzioni dell'identità quando si assume un ruolo

Le funzioni SQL di Unity Catalog relative all’identità fanno riferimento all’identità attiva della sessione, non all’utente autenticato sottostante. Quando un utente assume un ruolo, l'identità della sessione attiva diventa il ruolo:

Function Quando l'utente agisce con la propria identità utente Quando l'utente assume un ruolo
current_user() Restituisce il nome utente dell'utente Restituisce il nome del ruolo assunto
is_member(group) Restituisce true se l'utente è un membro del gruppo (un gruppo locale dell'area di lavoro o un gruppo di account assegnato all'area di lavoro) Restituisce true solo se il ruolo assunto è un membro di group. Restituisce false per i gruppi di cui l'utente sottostante è membro, ma di cui il ruolo assunto non è membro.
is_account_group_member(group) Restituisce true se l'utente è membro del gruppo a livello di account Uguale a is_member: restituisce true solo in base alle appartenenze ai gruppi del ruolo assunto, non all'utente sottostante.

Le policy ABAC che fanno riferimento a queste funzioni vengono valutate in base al ruolo assunto, non all'utente. Il ruolo assunto è l'identità attiva per la valutazione delle policy ABAC, la risoluzione delle autorizzazioni in Unity Catalog e l'attribuzione nei log di audit. Di conseguenza, assumere un ruolo modifica il comportamento delle policy e delle visualizzazioni esistenti create e definite sulla base dell'identità del singolo utente.

Note

Un ruolo non è automaticamente un membro di se stesso. Quando un utente assume il ruolo G, current_user() restituisce G, ma is_member('G') e is_account_group_member('G') restituiscono false a meno che G non sia stato aggiunto esplicitamente come membro di sé stesso. Per trovare una corrispondenza con il ruolo assunto in un criterio, confrontarlo con current_user() anziché testare l'appartenenza a is_member o is_account_group_member.

Errore comune: viste di sicurezza a livello di riga basate su current_user()

Uno schema comune nei modelli ABAC e nei filtri di riga a livello di tabella consiste nel filtrare le righe tramite join con una tabella di provisioning (detta anche tabella di mappatura o elenco di controllo degli accessi), indicizzata in base al nome utente restituito da current_user(). Per esempio:

CREATE OR REPLACE FUNCTION facility_filter(facility_id STRING)
RETURN EXISTS (
  SELECT 1
  FROM governance.user_facility_provisioning p
  WHERE p.user = current_user()
    AND p.facility_id = facility_id
);

Quando lo stesso utente assume un ruolo, current_user() non restituisce più il proprio nome utente. Restituisce il nome del ruolo. Poiché il ruolo non è presente nella tabella di provisioning, il filtro non restituisce righe e l'utente sembra perdere l'accesso ai dati a cui gli era stato concesso l'accesso.

Aggiungere il ruolo alla tabella di provisioning

Considerare il ruolo come un'altra entità nei dati di provisioning: inserire una riga per ogni ruolo con le funzionalità (o altri attributi) che il ruolo dovrebbe visualizzare. Il filtro verifica quindi se l'identità attiva è l'utente o il ruolo assunto.

Modelli di utilizzo combinato

Di seguito sono riportati esempi di come i clienti usano insieme RBAC e ABAC per risolvere problemi concreti di controllo degli accessi. Questi sono punti di partenza, non ricette esaustive.

Filtri a livello di riga per progetto basati sul ruolo assunto

Filtrare le righe in base al progetto è una necessità comune nella ricerca clinica, nel marketing dei contratti, nella consulenza dei clienti e in altre impostazioni in cui un team lavora in diversi progetti isolati. Nell'esempio seguente vengono usati studi clinici, ma il modello viene generalizzato in qualsiasi isolamento dei dati per progetto.

Un'organizzazione di ricerca clinica esegue diverse prove simultanee, ognuna nel proprio ruolo di accesso. Contrassegna ogni tabella con l'identificatore del progetto. Gli utenti visualizzano solo le righe relative al progetto per il cui ruolo sono attualmente abilitati.

Installazione:

  • Le tabelle sotto clinical_trials.* hanno una project_id colonna contrassegnata con la chiave del tag governedproject.
  • Ogni progetto ha un ruolo di accesso corrispondente denominato role-<project> (ad esempio, role-alpha, role-beta).
  • Gli utenti dispongono dell'autorizzazione di assumere solo i ruoli relativi ai progetti su cui lavorano.

UDF del filtro righe:

CREATE FUNCTION project_match(project_id STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN current_user() = CONCAT('role-', project_id);

Politica:

CREATE POLICY per_project_row_filter
ON CATALOG clinical_trials
ROW FILTER project_match
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('project') AS project
USING COLUMNS (project);

Questa funzione definita dall'utente (UDF) mette in relazione l'identità attiva con il valore del tag project di ogni riga, quindi clausole che hanno come destinazione i principal, come TO / EXCEPT, non possono esprimerlo: quelle clausole hanno come destinazione i principal, non il contenuto delle righe. Come spiega la guida al targeting del principal, preferisci TO / EXCEPT per un ambito del principal semplice e riserva le funzioni di identità all'interno di una UDF per casi come questo, in cui una singola regola dipende sia dall'identità attiva sia dal contenuto della riga.

Un singolo criterio copre ogni progetto: USING COLUMNS (project) passa alla UDF il valore del tag project di ogni riga, quindi non serve un criterio separato per ciascun progetto. Per la forma generale di questa tecnica, che guida l'accesso alle righe da una tabella di ricerca anziché la corrispondenza dei nomi dei ruoli, vedere Usare le tabelle di mapping per il controllo dinamico degli accessi.

Comportamento:

  • Un utente che opera con la propria identità utente non vede alcuna riga in nessuna clinical_trials tabella. current_user() restituisce il nome utente, che non corrisponde mai al role-* modello di denominazione. Si tratta del rifiuto predefinito previsto.
  • Un utente che assume role-alpha vede solo le righe in cui project_id è uguale a alpha. Passare a role-beta sostituisce i dati visibili senza eseguire nuovamente altre query.

Mascheramento delle informazioni di identificazione personale ridotto per gli utenti che operano in un ruolo designato

Per impostazione predefinita, le colonne PII (SSN, posta elettronica, telefono) vengono visualizzate mascherate per tutti. Per visualizzare i valori grezzi, un utente deve assumere esplicitamente un ruolo designato autorizzato per i dati personali. I log di audit registrano l'evento di assunzione del ruolo, quindi "Devo consultare PII reali" diventa una scelta esplicita verificabile tramite audit anziché un permesso implicito.

Installazione:

  • Le colonne sensibili vengono contrassegnate con la chiave del tag governed tagpii (valori consentiti, ad esempio ssn, email, phone).
  • Agli utenti autorizzati a visualizzare i PII grezzi viene assegnato un ruolo di accesso denominato role-pii-cleared Assume.

UDF della maschera di colonna (statica: il criterio specifica quali principal mascherare):

CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
DETERMINISTIC
RETURN '***';

Politica:

CREATE POLICY pii_default_mask
ON CATALOG customer_data
COLUMN MASK mask_pii
TO `account users`
EXCEPT `role-pii-cleared`
FOR TABLES
MATCH COLUMNS has_tag('pii') AS pii_col
ON COLUMN pii_col;

La clausola EXCEPT esclude role-pii-cleared del tutto dai criteri, quindi la funzione definita dall'utente (UDF) non viene mai richiamata quando quel ruolo è l'identità attiva. Per indicazioni generali sulla selezione dell'entità di sicurezza tramite TO / EXCEPT, vedere Prefer TO/EXCEPT for principal targeting.

Comportamento:

  • Un utente che opera con la propria identità utente vede *** in ogni colonna PII. Questo è lo stato predefinito per tutti gli utenti, inclusi gli utenti che dispongono dell'autorizzazione Assume per role-pii-cleared.
  • Dopo aver assunto role-pii-cleared, i criteri non si applicano più alla sessione e lo stesso utente vede i valori non elaborati.
  • Le voci del registro di controllo della sessione registrano identity_metadata.run_as = role-pii-cleared, così i revisori possono vedere esattamente quando le informazioni personali identificabili sono state rese visibili e da chi.

Policy del livello di riservatezza che variano in base al ruolo assunto

I dati vengono classificati in livelli di riservatezza (internal, confidential, restricted). Ogni livello ha un ruolo di accesso corrispondente, con restricted che implica anche l'accesso a confidential e internal. Un'unica UDF di filtro delle righe controlla la visibilità delle righe confrontando il tier di ciascuna riga con il ruolo assunto dall'utente.

Installazione:

  • Le tabelle hanno una sensitivity_level colonna contrassegnata con la chiave sensitivity (valori consentiti: internal, confidential, restricted).
  • Tre ruoli di accesso: role-sens-internal, role-sens-confidential, role-sens-restricted.

Funzione definita dall'utente per il filtro delle righe:

CREATE FUNCTION sensitivity_allowed(row_sensitivity STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN CASE
  WHEN current_user() = 'role-sens-restricted' THEN TRUE
  WHEN current_user() = 'role-sens-confidential' THEN row_sensitivity IN ('internal', 'confidential')
  WHEN current_user() = 'role-sens-internal' THEN row_sensitivity = 'internal'
  ELSE FALSE
END;

Politica:

CREATE POLICY sensitivity_filter
ON CATALOG corp_data
ROW FILTER sensitivity_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('sensitivity') AS sens
USING COLUMNS (sens);

Poiché un ruolo non è membro di sé stesso, questa UDF confronta current_user() con il nome di ciascun ruolo anziché verificarne l'appartenenza con is_account_group_member(). Vedere la nota precedente per il motivo per cui i test di appartenenza non corrispondono al ruolo assunto. Consulta Considerazioni sulle prestazioni per i criteri di filtro delle righe e di mascheramento delle colonne per informazioni sulle prestazioni delle funzioni di identità nelle funzioni definite dall'utente.

Comportamento:

  • Un utente che opera con la propria identità utente non vede alcuna riga. Il ELSE FALSE ramo corrisponde a qualsiasi elemento che non sia uno dei tre ruoli. Come nell'esempio per progetto precedente, si tratta della negazione predefinita prevista.
  • Supponendo che role-sens-internal mostri solo internal righe.
  • Supponiamo che role-sens-confidential mostri internal e confidential righe.
  • Supponendo che role-sens-restricted mostri tutte le righe.

Gli utenti presuppongono il livello più alto necessario per la sessione; il filtro esclude automaticamente tutti gli elementi sopra quel livello senza richiedere all'utente di conoscere le tabelle che contengono le classificazioni.

Attribuzione del controllo

Sia le valutazioni dei criteri ABAC che le query sottostanti rispettano l'attribuzione RBAC run_as / run_by. Le voci del registro di controllo riportano identity_metadata.run_by come utente autenticato e identity_metadata.run_as come ruolo assunto, indipendentemente dai criteri ABAC applicati durante la fase di valutazione. Vedere Informazioni di riferimento sulla tabella di sistema del log di controllo per lo schema completo del log di controllo.

Passaggi successivi

  • Accesso esclusivo del modello: applicare modelli per configurare l'accesso esclusivo usando un gruppo locale dell'account o un gruppo sincronizzato da Microsoft Entra ID. Vedere Accesso esclusivo al modello.
  • Cambia ruolo: assumi un ruolo utilizzando il selettore di ruolo, i cluster in modalità di accesso dedicato, la CLI, l'API o strumenti BI di terze parti. Vedi Cambia ruolo.
  • Gestire le autorizzazioni di assunzione del ruolo: concedere o revocare a un gruppo l'autorizzazione ad assumere il ruolo, in modo che gli utenti possano assumere il ruolo corrispondente. Vedere Gestire le autorizzazioni per un gruppo.
  • Rivedi i concetti di base di ABAC: scopri come funzionano i tag governati, i criteri e la valutazione dei criteri. Vedere Controllo degli accessi in base agli attributi in Unity Catalog.