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 controllo degli accessi basati su attributi.
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);
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);