Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa pagina descrive i pattern comuni per l'implementazione di politiche di filtro di riga e maschera di colonna ABAC.
- Per i concetti generali, vedere Concetti di base per il controllo degli accessi in base all'attributo.
- Per la sintassi dei criteri, vedere Creare e gestire i criteri di filtro di riga e maschera di colonna.
- Per le GRANT politiche (Beta), vedi le politiche ABAC GRANT (Beta).
- Se il tuo ambiente usa RBAC, consulta Usare RBAC con ABAC per informazioni sul comportamento delle funzioni di identità quando gli utenti assumono un ruolo e sui modelli che combinano RBAC con ABAC.
Funzioni di mascheramento compatibili con il cast
Azure Databricks esegue automaticamente il cast dell'output della funzione di maschera in modo che corrisponda al tipo di dati della colonna di destinazione. Consulta Cast automatico dei tipi per le maschere di colonna.
I modelli seguenti consentono di progettare funzioni di mascheramento compatibili con il casting.
Restituire un tipo convertibile
Quando si maschera una colonna, restituire lo stesso tipo di dati o un tipo coerente con esso. Controllare i tipi di dati delle colonne a cui si applicano i criteri e verificare che ogni ramo della funzione restituisca un valore compatibile.
-- Succeeds: Masks a DOUBLE column, returns DOUBLE in every branch
CREATE FUNCTION mask_salary(salary DOUBLE, user_role STRING)
RETURNS DOUBLE
RETURN CASE
WHEN user_role IN ('admin', 'hr') THEN salary
WHEN user_role = 'manager' THEN ROUND(salary / 1000) * 1000
ELSE 0.0
END;
-- Fails: 'CONFIDENTIAL' cannot be cast to a DOUBLE column type
CREATE FUNCTION mask_salary_as_text(salary DOUBLE, user_role STRING)
RETURNS STRING
RETURN CASE
WHEN user_role IN ('admin', 'hr') THEN CAST(salary AS STRING)
ELSE 'CONFIDENTIAL'
END;
Evitare l'overflow numerico
Quando una funzione maschera accetta e restituisce un tipo numerico più ampio rispetto alla colonna di destinazione, il risultato viene automaticamente convertito al tipo della colonna. Se il valore restituito supera l'intervallo del tipo più stretto, il cast provoca un overflow e la query fallisce durante l'esecuzione.
-- The target column is TINYINT (max 127). The input is upcast to BIGINT
-- for the function. Adding 1000 produces a BIGINT result that overflows
-- when cast back to TINYINT.
CREATE FUNCTION mask_score(score BIGINT)
RETURNS BIGINT
RETURN score + 1000;
Usare VARIANT per più tipi di colonna
Vedere Funzioni di maschera basate su VARIANT per più tipi di colonna.
Compatibilità del cast di test
Testare le funzioni di mascheramento con modelli di dati diversi.
SELECT CAST(mask_salary(salary, 'admin') AS DOUBLE) FROM employees;
SELECT CAST(mask_salary(salary, 'manager') AS DOUBLE) FROM employees;
SELECT CAST(mask_salary(salary, 'viewer') AS DOUBLE) FROM employees;
Funzioni di maschera basate su VARIANT per più tipi di colonna
Quando è necessario mascherare colonne di tipi di dati diversi, ad esempio INT, DOUBLE, DECIMAL(10,2), DECIMAL(15,5) e così via, è possibile scrivere una singola funzione definita dall'utente per la mascheratura che accetta e restituisce un tipo VARIANT. Azure Databricks esegue automaticamente il casting dell'output della funzione di mascheramento della colonna per corrispondere al tipo di dati della colonna target seguendo gli standard SQL ANSI.
Questo approccio riduce il numero di funzioni definite dall'utente e delle politiche necessarie. Anziché scrivere funzioni di maschera separate per ogni tipo di colonna, una funzione gestisce tutti i tipi.
Mascherare più tipi numerici con una singola funzione
Anziché creare una funzione maschera separata per ogni precisione numerica, è possibile usarle VARIANT per gestirle tutte con una singola funzione:
CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;
Questa funzione restituisce 0 come VARIANT, che Azure Databricks effettua automaticamente il cast al tipo corrispondente della colonna. Un singolo criterio ABAC, utilizzando questa funzione, può mascherare le colonne INT, DOUBLE e DECIMAL senza richiedere funzioni separate per ogni livello di precisione.
Se si preferisce mantenere il tipo in modo esplicito all'interno della funzione, è possibile creare un ramo sul tipo e restituire un valore mascherato appropriato per ognuno usando schema_of_variant():
-- Use VARIANT to accommodate different data types
CREATE FUNCTION flexible_mask(data VARIANT)
RETURNS VARIANT
RETURN CASE
WHEN schema_of_variant(data) = 'INT' THEN 0::VARIANT
WHEN schema_of_variant(data) = 'DATE' THEN DATE'1970-01-01'::VARIANT
WHEN schema_of_variant(data) = 'DOUBLE' THEN 0.00::VARIANT
ELSE NULL::VARIANT
END;
Mascherare le colonne struct con VARIANT
Per Databricks Runtime 18.1 e versioni successive, è anche possibile mascherare le colonne struct eseguendone il cast a VARIANT all'interno di un criterio ABAC. Creare un ramo nella forma dello struct per redattire in modo selettivo i campi:
Annotazioni
Il cast degli struct a VARIANT per il mascheramento è supportato solo nei criteri di maschera di colonna ABAC.
Nell'esempio seguente viene usato schema_of_variant() per identificare due forme struct diverse e oscurare i campi sensibili in ognuno di essi.
CREATE FUNCTION flexible_mask(data VARIANT)
RETURNS VARIANT
RETURN CASE
WHEN schema_of_variant(data) = 'OBJECT<age: BIGINT, email: STRING>' THEN
to_variant_object(named_struct('age', data:age, 'email', 'redacted'))
WHEN schema_of_variant(data) = 'OBJECT<id: BIGINT, ssn: STRING>' THEN
to_variant_object(named_struct('id', data:id, 'ssn', 'xxx-xx-xxxx'))
ELSE NULL::VARIANT
END;
Impedire l'accesso fino a quando non vengono contrassegnate le colonne sensibili
Un modello di governance comune consiste nel controllare l'accesso in base al fatto che i dati siano stati classificati. È possibile implementare questa impostazione con un tag e criteri restrittivi predefiniti che applicano livelli di protezione diversi a seconda dello stato di classificazione.
- Applicare un tag come
classification : unverifieda tutti i nuovi oggetti per impostazione predefinita, tramite l'automazione o l'ereditarietà dei tag applicando il tag a livello di catalogo o schema, in modo che tutte le nuove tabelle aggiunte al catalogo o allo schema ereditino automaticamente il tag. - Creare criteri di filtro di riga che bloccano l'accesso alle tabelle con tag
classification : unverified. - Creare un criterio di maschera di colonna che maschera le colonne sensibili nelle tabelle in cui il
classification : unverifiedtag non è più presente. - Quando un amministratore dei dati completa la classificazione, aggiorna il tag. I criteri di blocco non corrispondono più e il criterio di maschera diventa effettivo.
-- Block access to unverified tables for all non-admin users
CREATE FUNCTION catalog.schema.block_all() RETURNS BOOLEAN
RETURN FALSE;
CREATE POLICY block_unverified
ON CATALOG my_catalog
ROW FILTER catalog.schema.block_all
TO `account users` EXCEPT `data_admins`
FOR TABLES
WHEN has_tag_value('classification', 'unverified');
Per proteggere i dati sensibili dopo la classificazione, definire un criterio di maschera di colonna che diventa effettivo quando il classification : unverified tag non è più presente:
CREATE FUNCTION catalog.schema.mask_pii(val STRING)
RETURNS STRING
RETURN '***';
CREATE POLICY mask_reviewed_pii
ON CATALOG my_catalog
COLUMN MASK catalog.schema.mask_pii
TO `account users`
EXCEPT `data_admins`
FOR TABLES
WHEN NOT has_tag_value('classification', 'unverified')
MATCH COLUMNS (has_tag_value('pii', 'name') OR has_tag_value('pii', 'address')) AS m
ON COLUMN m;
Reveal parziale senza espressione regolare
Rivelare parte di un valore sensibile usando operazioni stringa anziché regex. La maschera basata su regex analizza l'intero valore per ogni riga, che è costosa nei campi di testo di grandi dimensioni(vedere Evitare la maschera regex in campi di testo di grandi dimensioni).
CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
DETERMINISTIC
RETURN CONCAT('***-**-', RIGHT(ssn, show_last));
Hashing coerente (pseudonimizzazione deterministica)
L'hashing coerente (detto anche pseudonimo deterministico) sostituisce i dati sensibili con un valore hash identico in più tabelle. Contrassegnare una funzione come DETERMINISTIC indica al motore che la funzione restituisce sempre lo stesso risultato per lo stesso input, che consente di ottimizzare la query. Vedere Usare espressioni deterministiche e sicure per gli errori.
La funzione seguente esegue costantemente l'hashing di un valore stringa e usa un version parametro per supportare la rotazione delle chiavi. Incrementare il numero version tramite la clausola USING COLUMNS della politica per generare nuovi hash senza interrompere i dati storici che hanno utilizzato la versione precedente. La funzione concatena il valore originale con il numero di versione prima dell'hashing, quindi lo stesso input con la stessa versione produce sempre lo stesso hash.
CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);
Maschera una colonna in base agli attributi dell'utente che interroga
Importante
Gli attributi di identità nelle policy ABAC sono in Beta. Per utilizzarli, un amministratore dell'account deve abilitare l'anteprima Attributi di identità nei criteri ABAC dalla pagina Anteprime della console dell'account. Vedi Gestire le anteprime a livello di account.
Un criterio di mascheramento di colonna può utilizzare gli attributi di identità dell’utente che esegue la query per mascherare dati sensibili senza richiedere gruppi dedicati. Ad esempio, può mantenere i dati non mascherati per gli utenti con department = HR e mascherarli per tutti gli altri.
Questi pattern richiedono attributi di identità forniti ai tuoi utenti dal tuo fornitore di identità, e le funzioni si comportano in modo diverso dalle condizioni solo tag, influenzando il modo in cui scrivi la policy. Prima di usarli, esamina le funzioni di attributo identità e gli attributi identità.
Importante
Le funzioni restituiscono false quando l'utente non ha alcun valore per l'attributo o quando la chiave dell'attributo non esiste. Scrivi la condizione in modo che questo false risultato limiti l'accesso invece di concederlo. Annulla la corrispondenza con NOT così che la maschera valga a meno che l'attributo non corrisponda. Ad esempio, WHEN NOT has_identity_attribute_value('department', 'HR') maschera la colonna per tutti tranne gli utenti il cui dipartimento è HR, e poiché un valore mancante è anche false, gli utenti senza attributo dipartimento sono mascherati. Evitare il contrario: una condizione che maschera solo quando l'attributo coincide lascia non mascherati gli utenti privi di un valore per l'attributo.
Per il comportamento di valutazione, vedi Condizioni dell'attributo di identità. Per le limitazioni, vedi Attributi di identità nelle condizioni di policy.
Abbina un valore fisso
Maschera ssn per tutti coloro il cui reparto non è HR:
CREATE FUNCTION hr_catalog.people.mask_ssn(s STRING) RETURNS STRING RETURN '***-**-****';
CREATE OR REPLACE POLICY mask_ssn_non_hr
ON SCHEMA hr_catalog.people
COLUMN MASK hr_catalog.people.mask_ssn
TO `account users`
FOR TABLES
WHEN NOT has_identity_attribute_value('department', 'HR')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;
In questo esempio, un utente il cui dipartimento è HR vede valori reali. Un utente in qualsiasi altro dipartimento, e un utente senza attributo di dipartimento, vedono entrambi la maschera.
Match contro un tag governato
L'esempio precedente indica un valore di attributo specifico (HR) nella policy, quindi coprire diversi dipartimenti significherebbe scrivere una policy separata per ciascuno. Per coprire tutti i dipartimenti con una sola politica, tagga ogni tabella con il dipartimento che ne è proprietario, poi confronta l'attributo dell'utente department che fa la query con quel tag. La colonna viene rivelata solo quando il reparto dell'utente corrisponde al valore della dept_tag tabella:
CREATE FUNCTION prod.sales.mask_ssn(s STRING) RETURNS STRING RETURN '***-**-****';
CREATE OR REPLACE POLICY mask_unless_dept_matches
ON SCHEMA prod.sales
COLUMN MASK prod.sales.mask_ssn
TO `account users`
FOR TABLES
WHEN NOT has_identity_attribute_tag_match('department', 'dept_tag')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;
Sia le chiavi sia i valori degli attributi distinguono tra maiuscole e minuscole e i valori vengono confrontati in modo esatto: Finance e finance non corrispondono.
Limitare l'accesso per agenti esterni che agiscono per conto di un utente
Importante
Gli attributi di contesto nelle policy ABAC sono in Beta. Per utilizzarli, un amministratore dell'account deve abilitare la funzionalità di anteprima Attributi di contesto UC ABAC dalla pagina Anteprime della console dell'account. Vedi Gestire le anteprime a livello di account.
Gli attributi di contesto possono essere usati per limitare l'accesso ai dati per richieste effettuate per conto di un utente tramite un'applicazione OAuth. Se gli agenti sono connessi tramite OAuth, questa configurazione può essere usata per impedire loro di accedere ai dati quando agiscono per conto di un utente, anche se l'utente può comunque leggere i dati quando li interroga direttamente nello spazio di lavoro.
Qualsiasi accesso autenticato OAuth tramite la CLI di Azure Databricks, gli SDK o l'API di esecuzione delle istruzioni SQL si imposta request.is_on_behalf_of su 'true', anche quando l'utente effettua query manualmente. L'accesso autenticato con un token di accesso personale (PAT) non avviene. L'accesso a Genie non può essere rilevato mediante questo meccanismo perché non imposta request.is_on_behalf_of su 'true'.
Questi schemi utilizzano le funzioni di attributo contestuale. Per attributi e comportamenti disponibili, vedi Funzioni di attributo contestuale (Beta).
Configura un agente per inviare attributi contestuali
Per usare attributi di contesto, collega l'agente ad Azure Databricks usando un'applicazione OAuth personalizzata:
- Un amministratore account abilita l'anteprima degli attributi di contesto UC ABAC dalla console dell'account. Vedere Gestire le anteprime di Azure Databricks.
- Un amministratore dell'account registra un'applicazione OAuth personalizzata nella console dell'account e annota il suo ID client. Vedere Abilitare o disabilitare le applicazioni OAuth dei partner.
- Collega l'agente all'MCP gestito da Azure Databricks tramite quell'applicazione OAuth. Consulta Connettere i client tramite l'autenticazione OAuth.
Un agente che utilizza il client integrato databricks-cli si autentica comunque su OAuth, quindi request.is_on_behalf_of legge 'true'. Tuttavia, non puoi distinguere le sue richieste dall'uso manuale della CLI, perché entrambe condividono l'ID databricks-cli client. Per governare un'applicazione specifica, registra un'applicazione OAuth personalizzata e collega l'agente tramite essa.
Per i concetti OAuth, vedi Autorizzare l'accesso dell'utente ad Azure Databricks con OAuth.
Warning
Assicurati che un agente non possa accedere ai dati tramite un percorso che la tua polizza non copre:
- Se limiti l'accesso in base a
request.is_on_behalf_of, assicurati che l'agente non possa autenticarsi con un PAT. Un PAT non impostarequest.is_on_behalf_ofsu'true', quindi una condizione su tale attributo non lo limita. - Se limiti l'accesso in base a
request.client_id, assicurati che l'agente non possa connettersi tramite un cliente che la tua condizione non copre, come il cliente genericodatabricks-cli.
Maschera una colonna per le richieste per conto di
Maschera ssn per le richieste eseguite per conto di un utente, ad esempio da un agente che opera tramite un'applicazione OAuth registrata, lasciandolo non mascherato per le query dirette:
CREATE FUNCTION hr_catalog.people.mask_ssn(s STRING) RETURNS STRING RETURN '***-**-****';
CREATE OR REPLACE POLICY mask_ssn_for_agents
ON SCHEMA hr_catalog.people
COLUMN MASK hr_catalog.people.mask_ssn
TO `account users`
FOR TABLES
WHEN has_context_attribute_value('request.is_on_behalf_of', 'true')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;
In questo esempio, una query diretta restituisce valori reali e una richiesta per conto di un altro utente mostra i valori mascherati. Usando la CLI e l'API di esecuzione delle istruzioni SQL, request.is_on_behalf_of legge anche 'true', quindi questa policy maschera la colonna anche per quelle richieste. Per selezionare invece come destinazione un'applicazione specifica, fai corrispondere request.client_id all'ID client di tale applicazione.
Limita una colonna a una domanda approvata
Nascondi ssn per ogni richiesta esterna tranne quelle provenienti dalla tua applicazione approvata, identificata dal relativo ID client OAuth:
CREATE OR REPLACE POLICY mask_ssn_unapproved_apps
ON SCHEMA hr_catalog.people
COLUMN MASK hr_catalog.people.mask_ssn
TO `account users`
FOR TABLES
WHEN NOT has_context_attribute_value('request.client_id', '<your-app-client-id>')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;
Per vedere quale applicazione ha effettuato una richiesta, ispeziona il identity_metadata.acting_resource campo nei log di audit.
Filtro di righe con predicati di sola colonna
Filtrare le righe usando una logica booleana semplice che fa riferimento solo alle colonne della tabella. I predicati di sola colonna abilitano il pushdown del predicato, che consente al motore di ignorare i dati irrilevanti durante le analisi (vedere Informazioni sul pushdown del predicato nelle tabelle protette).
CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(region));
Usare con un criterio che passa le aree consentite come costante:
CREATE POLICY regional_access
ON CATALOG analytics
ROW FILTER filter_by_region
TO 'emea_team'
FOR TABLES
MATCH COLUMNS has_tag('region') AS rgn
USING COLUMNS (rgn, 'emea,apac');
Filtro delle righe tra più colonne correlate
Quando una tabella include più colonne che rappresentano attributi correlati, come ship_to_country e bill_to_country, è possibile abbinarle a condizioni di tag separate e passare entrambe a una singola funzione definita dall'utente. In questo modo si evita di creare criteri separati per ogni colonna. Un criterio può includere fino a tre espressioni di colonna nella MATCH COLUMNS clausola (vedere Quote dei criteri).
CREATE FUNCTION filter_by_countries(ship_country STRING, bill_country STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(ship_country))
OR array_contains(split(allowed, ','), lower(bill_country));
CREATE POLICY regional_orders
ON SCHEMA prod.orders
ROW FILTER filter_by_countries
TO analysts
FOR TABLES
WHEN has_tag_value('sensitivity', 'high')
MATCH COLUMNS
has_tag('ship_country') AS ship,
has_tag('bill_country') AS bill
USING COLUMNS (ship, bill, 'us,ca,mx');
Un analista vede solo gli ordini in cui il paese di spedizione o fatturazione è incluso nell'elenco consentito.
Tabelle di ricerca nelle UDF (Funzioni Definite dall'Utente) dei criteri ABAC
Quando le regole di accesso variano per utente e non possono essere espresse solo tramite le clausole dei TO/EXCEPT criteri, è possibile controllare i diritti di accesso rispetto a una tabella di ricerca di piccole dimensioni. Usare TO/EXCEPT quando possibile, poiché è l'approccio preferito per le entità di destinazione (vedere Approccio per le entità di destinazione). Mantenere la tabella di ricerca piccola in modo che Optimizer converta la sottoquery in un hash join broadcast (vedere Mantenere le tabelle di ricerca di piccole dimensioni).
CREATE TABLE access_rules (
principal VARCHAR(255),
priority VARCHAR(64)
);
INSERT INTO access_rules VALUES
('alice@company.com', '1-URGENT'),
('alice@company.com', '2-HIGH'),
('bob@company.com', '1-URGENT');
CREATE FUNCTION priority_allowed(o_priority STRING) RETURNS BOOLEAN
RETURN EXISTS (
SELECT 1 FROM access_rules
WHERE principal = session_user() AND priority = o_priority
);
CREATE POLICY priority_filter
ON CATALOG operations
ROW FILTER priority_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('priority') AS pri
USING COLUMNS (pri);