Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
På den här sidan beskrivs vanliga mönster för implementering av ABAC-radfilter och kolumnmaskprinciper.
- Övergripande begrepp finns i Grundläggande begrepp för attributbaserad åtkomstkontroll (ABAC).
- Principsyntax finns i Skapa och hantera principer för radfilter och kolumnmask.
- För GRANT policyer (Beta), se ABAC-policyer GRANT (Beta).
- Om din miljö använder RBAC läser du Använda RBAC med ABAC för hur identitetsfunktioner beter sig när användare tar på sig en roll och mönster som kombinerar RBAC med ABAC.
Cast-kompatibla maskeringsfunktioner
Azure Databricks automatiskt omvandlar maskeringsfunktionens utdata så att de matchar målkolumnens datatyp. Se Automatisk typgjutning för kolumnmasker.
Följande mönster hjälper dig att utforma cast-kompatibla maskeringsfunktioner.
Returnera en typ möjligt att konvertera
När du maskerar en kolumn returnerar du samma datatyp eller en typ som kan castas till den. Kontrollera datatyperna för kolumnerna som dina principmål har och kontrollera att varje gren av funktionen returnerar ett kompatibelt värde.
-- 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;
Undvik numeriskt överflöde
När en maskfunktion accepterar och returnerar en bredare numerisk typ än målkolumnen kastas resultatet automatiskt tillbaka till kolumnens typ. Om det returnerade värdet överskrider intervallet för den begränsade typen, flödar kastet över och frågan misslyckas under körning.
-- 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;
Använda VARIANT för flera kolumntyper
Se VARIANT-baserade maskeringsfunktioner för flera kolumntyper.
Testa kompatibilitet för streaming
Testa maskeringsfunktioner med olika datamönster.
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;
VARIANT-baserade maskeringsfunktioner för flera kolumntyper
När du behöver maskera kolumner med olika datatyper (till exempel INT, , DOUBLEDECIMAL(10,2), , DECIMAL(15,5)och så vidare) kan du skriva en enda maskerings-UDF som accepterar och returnerar en VARIANT typ. Azure Databricks automatiskt omvandlar kolumnmaskfunktionens utdata så att de matchar målkolumnens datatyp enligt ANSI SQL-standarder.
Den här metoden minskar antalet UDF:er och principer som behövs. I stället för att skriva separata maskeringsfunktioner för varje kolumntyp hanterar en funktion alla typer.
Maskera flera numeriska typer med en enda funktion
I stället för att skapa en separat maskfunktion för varje numerisk precision kan du använda VARIANT för att hantera dem alla med en enda funktion:
CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;
Den här funktionen returnerar 0 som en VARIANT, vilket Azure Databricks automatiskt kastar till målkolumnens typ. En enskild ABAC-princip som använder den här funktionen kan maskera INT, DOUBLEoch DECIMAL kolumner utan att kräva separata funktioner för varje precision.
Om du föredrar att bevara typen explicit i funktionen kan du förgrena på typen och returnera ett lämpligt maskerat värde för var och en med hjälp av 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;
Maskera structkolumner med VARIANT
För Databricks Runtime 18.1 och senare kan du också maskera structkolumner genom att göra om dem till VARIANT inom en ABAC-policy. Anpassa sig efter strukturen av structen för att selektivt dölja eller ta bort fält:
Note
Att konvertera structs till VARIANT för maskering stöds endast inom ABAC-kolumnmaskprinciper.
I följande exempel används schema_of_variant() för att identifiera två olika structformer och redigera känsliga fält i var och en:
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;
Förhindra åtkomst tills känsliga kolumner har taggats
Ett vanligt styrningsmönster är att kontrollera åtkomsten baserat på om data har klassificerats. Du kan implementera detta med en standardbegränsande tagg och principer som tillämpar olika skyddsnivåer beroende på klassificeringsstatusen.
- Använd en tagg som
classification : unverifiedalla nya objekt som standard, via automatisering eller genom taggarv genom att tillämpa taggen på katalog- eller schemanivå, så att alla nya tabeller som läggs till i katalogen eller schemat automatiskt ärver taggen. - Skapa en radfilterprincip som blockerar åtkomst till tabeller taggade
classification : unverified. - Skapa en kolumnmaskprincip som maskerar känsliga kolumner i tabeller där taggen
classification : unverifiedinte längre finns. - När en dataförvaltare slutför klassificeringen uppdaterar de taggen. Blockeringsprincipen matchar inte längre och maskeringsprincipen börjar gälla.
-- 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');
Om du vill skydda känsliga data efter att de har klassificerats definierar du en kolumnmaskprincip som börjar gälla när taggen classification : unverified inte längre finns:
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;
Partiell avslöjande utan regex
Visa en del av ett känsligt värde med hjälp av strängåtgärder i stället för regex. Regex-baserad maskering söker igenom hela värdet för varje rad, vilket är dyrt för stora textfält (se Undvik regexmaskering på stora textfält).
CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
DETERMINISTIC
RETURN CONCAT('***-**-', RIGHT(ssn, show_last));
Konsekvent hashning (deterministisk pseudonymisering)
Konsekvent hashning (kallas även deterministisk pseudonymisering) ersätter känsliga data med ett hashvärde som är detsamma i flera tabeller. Markera en funktion som DETERMINISTIC talar om för motorn att funktionen alltid returnerar samma resultat för samma indata, vilket hjälper den att optimera frågan. Se Använda deterministiska, felsäkra uttryck.
Följande funktion hashar konsekvent ett strängvärde och använder en version parameter för att stödja nyckelrotation. Öka version talet genom en klausul i policyn USING COLUMNS för att generera nya hashvärden utan att bryta historiska data som använde den tidigare versionen. Funktionen sammanfogar det ursprungliga värdet med versionsnumret före hashning, så samma indata med samma version genererar alltid samma hash.
CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);
Maskera en kolumn baserat på attribut hos den sökande användaren
Important
Identitetsattribut i ABAC-policyer är i Beta. För att använda dem måste en kontoadministratör aktivera förhandsversionen Identity Attributes i ABAC-principer på sidan Förhandsversioner i kontokonsolen. Se Hantera förhandsversioner på kontonivå.
En kolumnmaskpolicy kan använda användarens identitetsattribut för att maskera känslig data utan att behöva dedikerade grupper. Till exempel kan den hålla data omaskerad för användare med department = HR och maskera den för alla andra.
Dessa mönster kräver identitetsattribut som tillhandahålls till dina användare från din identitetsleverantör, och funktionerna beter sig annorlunda än tagg-only-villkor på sätt som påverkar hur du skriver policyn. Innan du använder dem, granska funktioner för identitetsattribut och identitetsattribut.
Important
Funktionerna löses till false när användaren inte har något värde för attributet eller när attributnyckeln inte existerar. Skriv villkoret så att detta false resultat begränsar åtkomst snarare än ger den. Neutralisera matchningen med NOT så att masken gäller om inte attributet matchar. Till exempel WHEN NOT has_identity_attribute_value('department', 'HR') maskerar kolumnen för alla utom användare vars avdelning är HR, och eftersom ett saknat värde också falseär , maskeras användare utan avdelningsattribut också. Undvik det motsatta: ett villkor som bara maskerar när attributet matchar lämnar användare som inte har något värde för attributet omaskerade.
För utvärderingsbeteende, se Identitetsattributvillkor. För begränsningar, se Identitetsattribut i policyvillkor.
Matcha ett fast värde
Dölj ssn för alla vars avdelning inte är 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;
I detta exempel ser en användare vars avdelning är HR verkliga värden. En användare i någon annan avdelning, och en användare utan avdelningsattribut, ser båda masken.
Matcha mot en reglerad tagg
Det föregående exemplet namnger ett specifikt attributvärde (HR) i policyn, så att täcka flera avdelningar skulle innebära att man skriver en separat policy för varje avdelning. För att täcka alla avdelningar med en enda policy, tagga varje tabell med den avdelning som äger den, och jämför sedan användarens department attribut med den taggen. Kolumnen avslöjas endast när användarens avdelning matchar tabellens dept_tag värde:
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;
Attributnycklar och värden är båda kasuskänsliga, och värden jämförs exakt: Finance och finance matchar inte.
Begränsa åtkomsten för externa agenter som agerar på uppdrag av en användare
Important
Kontextattribut i ABAC-policyer är i Beta. För att använda dem måste en kontoadministratör aktivera UC ABAC Context Attributes förhandsvisning från kontokonsolens Förhandsgranskningssida . Se Hantera förhandsversioner på kontonivå.
Kontextattribut kan användas för att begränsa dataåtkomst för förfrågningar som görs på användarens vägnar via en OAuth-applikation. Om agenter är anslutna via OAuth kan denna uppsättning användas för att förhindra att de får tillgång till data när de agerar på användarens vägnar, även om användaren fortfarande kan läsa datan när de frågar direkt i arbetsytan.
All OAuth-autentiserad åtkomst via Azure Databricks CLI, SDK:erna eller SQL Statement Execution API ställs request.is_on_behalf_of in till 'true', även när en användare gör en manuell förfrågan. Åtkomst som autentiseras med en personlig åtkomsttoken (PAT) gör det inte. Genie-åtkomst kan inte registreras via den här mekanismen eftersom den inte sätter request.is_on_behalf_of till 'true'.
Dessa mönster använder kontextattributfunktionerna. För tillgängliga attribut och beteende, se Context attribut-funktioner (Beta).
Sätt upp en agent för att skicka kontextattribut
För att använda kontextattribut, koppla agenten till Azure Databricks med en anpassad OAuth-applikation:
- En kontoadministratör aktiverar förhandsvisningen av UC ABAC Context Attributes från kontokonsolen. Se Hantera förhandsversioner av Azure Databricks.
- En kontoadministratör registrerar en anpassad OAuth-applikation i kontokonsolen och noterar dess klient-ID. Se Aktivera eller inaktivera OAuth-partnerprogram.
- Koppla agenten till den Azure Databricks hanterade MCP via den OAuth-applikationen. Se Koppla klienter med OAuth-autentisering.
En agent som använder den inbyggda databricks-cli klienten autentiserar sig fortfarande över OAuth, så request.is_on_behalf_of läser 'true'. Du kan dock inte skilja dess förfrågningar från manuell användning av CLI, eftersom båda delar databricks-cli klient-ID. För att styra en specifik applikation, registrera en anpassad OAuth-applikation och koppla agenten genom den.
För OAuth-koncept, se Auktorisera användaråtkomst till Azure Databricks med OAuth.
Varning
Se till att en agent inte kan nå datan via en väg som din försäkring inte täcker:
- Om du begränsar åtkomsten baserat på
request.is_on_behalf_of, se till att agenten inte kan autentiseras med en PAT. En PAT sätterrequest.is_on_behalf_ofinte till'true', så ett villkor på det attributet begränsar det inte. - Om du begränsar åtkomst baserat på
request.client_id, se till att agenten inte kan ansluta via en klient som ditt tillstånd inte täcker, som den generiskadatabricks-cliklienten.
Maskera en kolumn för begäranden som görs för någon annans räkning
Mask ssn för förfrågningar som körs för en användares räkning, såsom en agent som agerar via en registrerad OAuth-applikation, medan den lämnas omaskad för direkta frågor:
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;
I det här exemplet returnerar en direkt fråga faktiska värden, och en begäran som görs för någon annans räkning visar de maskerade värdena. Med CLI:t och SQL Statement Execution API:t läser request.is_on_behalf_of också 'true', så den här policyn maskerar kolumnen även för dessa begäranden. För att rikta in dig på en specifik applikation istället, matcha request.client_id mot applikationens klient-ID.
Begränsa en kolumn till en godkänd applikation
Mask ssn för varje extern förfrågan utom de från din godkända applikation, identifierad av dess OAuth-klient-ID:
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;
För att se vilken applikation som gjort en begäran, granska identity_metadata.acting_resource fältet i revisionsloggarna.
Radfiltrering med endast kolumnpredikat
Filtrera rader med enkel boolesk logik som endast refererar till tabellkolumner. Endast kolumnpredikat aktiverar predikat-pushdown, vilket gör att motorn kan hoppa över irrelevanta data under genomsökningar (se Förstå predikat-pushdown på skyddade tabeller).
CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(region));
Använd med en policy som överför de godkända regionerna som en konstant.
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');
Radfiltrering över flera relaterade kolumner
När en tabell har flera kolumner som representerar relaterade attribut (till exempel ship_to_country och bill_to_country), kan du matcha dem med separata taggvillkor och skicka båda till en enda UDF. Detta undviker att skapa separata principer för varje kolumn. En princip kan innehålla upp till tre kolumnuttryck i MATCH COLUMNS -satsen (se Principkvoter).
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');
En analytiker ser bara beställningar där leverans- eller faktureringslandet finns i listan över tillåtna.
Uppslagstabeller i ABAC-policy UDF:er
När åtkomstreglerna varierar per användare och inte kan uttryckas enbart via principens satser kan du kontrollera åtkomsträttigheterna mot en liten uppslagstabell TO/EXCEPT . Använd TO/EXCEPT när det är möjligt, eftersom det är den bästa metoden för att rikta in sig på huvudkonton (se Metod för att rikta in sig på huvudkonton). Håll uppslagstabellen liten så att optimeraren konverterar underfrågan till en sändningshashkoppling (se Behåll uppslagstabeller små).
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);