Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Na tej stronie opisano typowe wzorce implementowania zasad filtrowania wierszy ABAC i maski kolumn.
- Aby zapoznać się z ogólnymi pojęciami, zobacz Podstawowe pojęcia dotyczące kontroli dostępu opartej na atrybutach (ABAC).
- Aby uzyskać informacje o składni zasad, zobacz Tworzenie i zarządzanie zasadami filtrowania wierszy i maski kolumn.
- Informacje o zasadach GRANT można znaleźć w sekcji zasady ABAC GRANT.
- Jeśli środowisko używa mechanizmu RBAC, zobacz Używanie RBAC z ABAC, aby dowiedzieć się, jak działają funkcje tożsamości, gdy użytkownicy przejmują rolę, oraz poznać wzorce łączące RBAC z ABAC.
Funkcje maskowania zgodne z rzutowaniem
Azure Databricks automatycznie rzutuje dane wyjściowe funkcji maskowania w celu dopasowania ich do typu danych kolumny docelowej. Zobacz Automatyczne rzutowanie typów dla masek kolumn.
Poniższe wzorce ułatwiają projektowanie funkcji maskowania zgodnych z rzutowaniem.
Zwracanie typu rzutowalnego
Podczas maskowania kolumny zwróć ten sam typ danych lub typ, który można do niego rzutować. Sprawdź typy danych kolumn określonych w Twojej polityce i upewnij się, że każda gałąź funkcji zwraca wartość zgodną typem danych.
-- 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;
Unikaj przepełnienia liczbowego
Gdy funkcja maski akceptuje i zwraca szerszy typ liczbowy niż kolumna docelowa, wynik jest automatycznie przekształcany z powrotem do typu kolumny. Jeśli zwrócona wartość przekracza zakres węższego typu, rzutowanie powoduje jego przepełnienie i zapytanie kończy się niepowodzeniem podczas wykonywania.
-- 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;
Używanie wariantu dla wielu typów kolumn
Zobacz Funkcje maskowania oparte na wariantach dla wielu typów kolumn.
Zgodność rzutów testowych
Testowanie funkcji maskowania przy użyciu różnych wzorców danych.
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;
Funkcje maskowania oparte na wariantach dla wielu typów kolumn
Jeśli musisz maskować kolumny różnych typów danych (na przykład INT, DOUBLE, DECIMAL(10,2), DECIMAL(15,5) i tak dalej), możesz napisać pojedynczą funkcję maskowania zdefiniowaną przez użytkownika, która akceptuje i zwraca typ VARIANT. Azure Databricks automatycznie rzutuje dane wyjściowe funkcji maski kolumn w celu dopasowania ich do typu danych kolumny docelowej zgodnie ze standardami ANSI SQL.
Takie podejście zmniejsza liczbę wymaganych funkcji UDF i zasady. Zamiast pisać oddzielne funkcje maskowania dla każdego typu kolumny, jedna funkcja obsługuje wszystkie typy.
Maskuj wiele typów liczbowych za pomocą jednej funkcji
Zamiast tworzyć oddzielną funkcję maski dla każdej precyzji liczbowej, można użyć VARIANT do obsługi wszystkich jednym rozwiązaniem.
CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;
Ta funkcja zwraca 0 jako VARIANT, które Azure Databricks automatycznie rzutuje do typu kolumny docelowej. Jedna polityka ABAC korzystająca z tej funkcji może maskować kolumny INT, DOUBLE i DECIMAL bez konieczności stosowania oddzielnych funkcji dla każdego stopnia precyzji.
Jeśli wolisz jawnie zachować typ w funkcji, możesz rozgałęzić typ i zwrócić odpowiednią wartość maskowaną dla każdego z nich przy użyciu polecenia 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;
Maskuj kolumny struktury przy użyciu VARIANT
W przypadku środowiska Databricks Runtime 18.1 lub nowszego można również maskować kolumny strukturalne, przekonwertowując je na VARIANT w ramach zasady ABAC. Rozgałęzienie kształtu struktury w celu selektywnego redagowania pól:
Uwaga / Notatka
Rzutowanie struktur do VARIANT maskowania jest obsługiwane tylko w ramach zasad maskowania kolumn ABAC.
W poniższym przykładzie użyto schema_of_variant() do identyfikowania dwóch różnych kształtów struktur i zaciemniania poufnych pól w każdej strukturze.
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;
Zapobiegaj dostępowi, dopóki poufne kolumny nie zostaną otagowane
Typowym wzorcem ładu jest kontrolowanie dostępu na podstawie tego, czy dane zostały sklasyfikowane. Można to zaimplementować za pomocą domyślnego restrykcyjnego tagu i zasad, które wymuszają różne poziomy ochrony w zależności od stanu klasyfikacji.
- Zastosuj tag podobny
classification : unverifieddo wszystkich nowych obiektów domyślnie za pomocą automatyzacji lub dziedziczenia tagów, stosując tag na poziomie katalogu lub schematu, aby wszystkie nowe tabele dodane do wykazu lub schematu automatycznie dziedziczyły tag. - Utwórz zasady filtrowania wierszy, które blokują dostęp do tabel oznaczonych tagiem
classification : unverified. - Utwórz zasady maski kolumn, które maskują poufne kolumny w tabelach, w których
classification : unverifiedtag nie jest już obecny. - Po zakończeniu klasyfikacji przez stewarda danych aktualizują tag. Zasady blokowania nie są już zgodne, a zasady maskowania obowiązują.
-- 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');
Aby chronić poufne dane po sklasyfikowaniu, zdefiniuj zasady maski kolumn, które obowiązują, gdy classification : unverified tag nie jest już obecny:
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;
Częściowe ujawnianie bez użycia wyrażeń regularnych
Ujawnianie części wartości poufnej przy użyciu manipulacji ciągami znaków zamiast wyrażeń regularnych. Maskowanie oparte na wyrażeniach regularnych skanuje całą wartość dla każdego wiersza, co jest kosztowne w przypadku dużych pól tekstowych (zobacz Unikanie maskowania wyrażeń regularnych w dużych polach tekstowych).
CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
DETERMINISTIC
RETURN CONCAT('***-**-', RIGHT(ssn, show_last));
Spójne wyznaczanie wartości skrótu (deterministyczna pseudonimizacja)
Spójne tworzenie skrótów (nazywane również pseudonimizacją deterministyczną) zastępuje poufne dane wartością skrótu, która jest taka sama w wielu tabelach. Oznaczanie funkcji, jak DETERMINISTIC informuje aparat, że funkcja zawsze zwraca ten sam wynik dla tych samych danych wejściowych, co pomaga zoptymalizować zapytanie. Zobacz Używanie deterministycznych, bezpiecznych od błędów wyrażeń.
Następująca funkcja stale skrótuje wartość ciągu i używa parametru version do obsługi rotacji kluczy. Zwiększ licznik poprzez klauzulę polityki version, aby wygenerować nowe skróty, nie naruszając danych historycznych, które korzystały z poprzedniej wersji. Funkcja łączy oryginalną wartość z numerem wersji przed hashingiem, więc te same dane wejściowe z tą samą wersją zawsze generują ten sam skrót.
CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);
Maskuj kolumnę opartą na atrybutach użytkownika zapytującego
Ważna
Atrybuty tożsamości w politykach ABAC są w fazie beta. Aby z nich korzystać, administrator konta musi włączyć podgląd funkcji Atrybuty tożsamości w zasadach ABAC na stronie Wersje zapoznawcze w konsoli konta. Zobacz Zarządzanie podglądami na poziomie konta.
Polityka maski kolumnowej może wykorzystywać atrybuty tożsamości użytkownika do maskowania wrażliwych danych bez potrzeby dedykowanych grup. Na przykład może pozostawiać dane niezamaskowane dla użytkowników z uprawnieniem department = HR i maskować je dla wszystkich pozostałych.
Te wzorce wymagają atrybutów tożsamości dostarczanych użytkownikom przez dostawcę tożsamości, a funkcje te zachowują się inaczej niż warunki tylko tagów, co wpływa na sposób pisania polityki. Przed ich użyciem zapoznaj się z funkcjami atrybutów tożsamości i atrybutami tożsamości.
Ważna
Funkcje zwracają wartość false, gdy użytkownik nie ma przypisanej wartości tego atrybutu lub gdy klucz atrybutu nie istnieje. Zapisz warunek tak, aby ten false wynik ograniczał dostęp, a nie go przyznawał. Zaneguj dopasowanie za pomocą NOT, aby maska była stosowana, chyba że atrybut pasuje. Na przykład maskuje kolumnę dla wszystkich oprócz użytkowników, WHEN NOT has_identity_attribute_value('department', 'HR') których departament to HR, a ponieważ brakująca wartość jest również false, użytkownicy bez atrybutu departamentu również są maskowani. Unikaj sytuacji odwrotnej: warunek, który maskuje tylko wtedy, gdy atrybut ma pasującą wartość, pozostawia użytkowników, którzy nie mają wartości tego atrybutu, niezamaskowanych.
Informacje o zachowaniu podczas oceny można znaleźć w sekcji Warunki atrybutu tożsamości. Ograniczenia można znaleźć w artykule Atrybuty tożsamości w warunkach polityki.
Dopasuj stałą wartość
Maskuj ssn dla wszystkich, których dział nie jest 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;
W tym przykładzie użytkownik, którego dział jest wydziałem HR , widzi rzeczywiste wartości. Użytkownik w dowolnym innym dziale oraz użytkownik bez atrybutu departamentu widzą maskę.
Mecz przeciwko kontrolowanemu tagowi
Poprzedni przykład określa konkretną wartość atrybutu (HR) w polityce, więc pokrycie kilku działów oznaczałoby napisanie osobnej polityki dla każdego z nich. Aby pokryć wszystkie działy jedną polityką, oznacz każdą tabelę działem, który ją posiada, a następnie porównaj atrybut użytkownika department zapytującego z tym tagiem. Kolumna ujawnia się tylko wtedy, gdy dział użytkownika zgadza się z wartością dept_tag tabeli:
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;
W kluczach i wartościach atrybutów rozróżniana jest wielkość liter, a wartości są porównywane dokładnie: Finance i finance nie pasują do siebie.
Ogranicz dostęp dla zewnętrznych agentów działających w imieniu użytkownika
Ważna
Atrybuty kontekstowe w politykach ABAC są w fazie beta. Aby z nich korzystać, administrator konta musi włączyć podgląd atrybutów kontekstu UC ABAC na stronie Podglądu konsoli konta. Zobacz Zarządzanie podglądami na poziomie konta.
Atrybuty kontekstu mogą być używane do ograniczania dostępu do danych dla żądań składanych w imieniu użytkownika za pośrednictwem aplikacji OAuth (autoryzacja użytkownik-maszyna (U2M)). Jeśli agenci są połączeni przez OAuth, takie ustawienie może uniemożliwić im dostęp do danych, gdy działają w imieniu użytkownika, mimo że użytkownik nadal może odczytać dane, gdy zapyta je bezpośrednio w przestrzeni roboczej.
Każdy dostęp uwierzytelniony za pomocą OAuth za pośrednictwem interfejsu wiersza polecenia Azure Databricks CLI, zestawów SDK lub interfejsu API SQL Statement Execution API powoduje ustawienie wartości request.is_on_behalf_of na 'true', nawet gdy użytkownik ręcznie wykonuje zapytanie. Dostęp uwierzytelniany za pomocą osobistego tokenu dostępu (PAT) — nie. Dostępu Genie nie można uzyskać za pomocą tego mechanizmu.
Wzorce te wykorzystują funkcje atrybutów kontekstu. Aby poznać dostępne atrybuty i zachowanie, zobacz Context attribute functions (Beta).
Połącz agenta z usługą Azure Databricks
Aby użyć atrybutów kontekstu, połącz agenta za pomocą niestandardowej aplikacji OAuth:
- Administrator konta umożliwia podgląd atrybutów kontekstu UC ABAC z konsoli konta. Zobacz Zarządzanie wersjami zapoznawczami usługi Azure Databricks.
- Administrator konta rejestruje niestandardową aplikację OAuth w konsoli konta i zapisuje jej identyfikator klienta.
- Połącz agenta z MCP zarządzanym przez Azure Databricks za pośrednictwem tej aplikacji OAuth. Zobacz Łączenie klientów za pomocą uwierzytelniania OAuth.
Agent korzystający z wbudowanego databricks-cli klienta nadal uwierzytelnia się przez OAuth, więc request.is_on_behalf_of czyta 'true'. Jednak nie da się odróżnić jego żądań od ręcznego korzystania z CLI, ponieważ oba mają wspólny databricks-cli identyfikator klienta. Aby zarządzać konkretną aplikacją, zarejestruj niestandardową aplikację OAuth i połącz agenta przez nią.
Warning
Upewnij się, że agent nie może uzyskać dostępu do danych ścieżką, której Twoja polisa nie obejmuje:
- Jeśli ograniczasz dostęp na podstawie
request.is_on_behalf_of, upewnij się, że agent nie może uwierzytelnić się za pomocą PAT. PAT nie ustawiarequest.is_on_behalf_ofna'true', więc warunek dla tego atrybutu go nie ogranicza. - Jeśli ograniczasz dostęp na podstawie
request.client_id, upewnij się, że agent nie może połączyć się za pomocą klienta, którego ten warunek nie obejmuje, takiego jak ogólny klientdatabricks-cli.
Zamaskuj kolumnę dla żądań w imieniu innego użytkownika
Maskuj ssn dla żądań wykonywanych w imieniu użytkownika, takich jak agent działający przez zarejestrowaną aplikację OAuth, pozostawiając ją niemaskowaną dla bezpośrednich zapytań:
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;
W tym przykładzie bezpośrednie zapytanie zwraca rzeczywiste wartości, a żądanie w imieniu użytkownika zwraca zamaskowane wartości. Podczas korzystania z interfejsu CLI i interfejsu API SQL Statement Execution, request.is_on_behalf_of również odczytuje 'true', więc ta polityka maskuje kolumnę również w przypadku tych żądań. Aby skupić się na konkretnej aplikacji, dopasuj request.client_id do identyfikatora klienta tej aplikacji.
Ogranicz kolumnę do zatwierdzonej aplikacji
Maskuj ssn dla każdego zewnętrznego żądania z wyjątkiem tych z zatwierdzonej aplikacji, identyfikowanych przez identyfikator klienta 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;
Aby zobaczyć, która aplikacja złożyła żądanie, sprawdź identity_metadata.acting_resource pole w logach audytu.
Filtrowanie wierszy przy użyciu predykatów tylko dla kolumn
Filtruj wiersze, używając prostej logiki, która odwołuje się tylko do kolumn tabeli. Predykaty odnoszące się wyłącznie do kolumn umożliwiają filtrowanie predykatów, co pozwala silnikowi pomijać nieistotne dane podczas skanowania (zobacz Omówienie filtrowania predykatów w chronionych tabelach).
CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(region));
Użyj z polityką, która przekazuje dozwolone regiony jako stałą:
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');
Filtrowanie wierszy w wielu powiązanych kolumnach
Jeśli tabela zawiera wiele kolumn reprezentujących powiązane atrybuty (na przykład ship_to_country i bill_to_country), można je dopasować do oddzielnych warunków tagów i przekazać obie do pojedynczej funkcji zdefiniowanej przez użytkownika. Pozwala to uniknąć tworzenia oddzielnych zasad dla każdej kolumny. Polityka może zawierać maksymalnie trzy wyrażenia kolumn w klauzuli MATCH COLUMNS (zobacz Limity polityki).
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');
Analityk widzi tylko zamówienia, w których kraj wysyłki lub rozliczeń znajduje się na liście dozwolonych.
Tabele wyszukiwania w funkcji UDF zasad ABAC
Jeśli reguły dostępu różnią się w zależności od użytkownika i nie można ich wyrazić za pomocą samych klauzul zasad TO/EXCEPT, możesz zweryfikować prawa dostępu względem małej tabeli wyszukiwania. Użyj TO/EXCEPT , jeśli jest to możliwe, ponieważ jest to preferowane podejście dla określania podmiotów głównych (zobacz Podejście do określania podmiotów głównych). Zachowaj małą tabelę wyszukiwania, aby optymalizator konwertował podzapytanie na sprzężenie haszujące nadawcze (zobacz Zachowaj tabele wyszukiwania małe).
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);