Typowe wzorce filtrowania wierszy i maskowania kolumn

Na tej stronie opisano typowe wzorce implementowania zasad filtrowania wierszy ABAC i maski kolumn.

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 Maskowanie wielu typów kolumn za pomocą jednej funkcji.

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;

Maskowanie wielu typów kolumn za pomocą jednej funkcji

Pojedyncza funkcja UDF maskująca, która akceptuje i zwraca wartość typu VARIANT, może maskować kolumny wielu typów danych, co zmniejsza liczbę funkcji UDF i zasad, które utrzymujesz. Azure Databricks rzutuje wartość kolumny na VARIANT przed uruchomieniem funkcji, a następnie rzutuje zwracaną wartość z powrotem na typ kolumny zgodnie z regułami ANSI SQL.

W funkcji użyj schema_of_variant(), aby sprawdzić wartość i wykonać rozgałęzienie w zależności od jej typu. W każdej gałęzi zwróć wartość, którą można przekonwertować do typu kolumny docelowej.

Maskowanie wielu typów numerycznych

Najprostsza VARIANT maska zwraca pojedynczą stałą, którą Azure Databricks rzutuje na typ każdej kolumny. Jedna polityka wykorzystująca tę funkcję może maskować kolumny INT, DOUBLE i DECIMAL bez osobnej funkcji dla każdego poziomu precyzji:

CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;

Aby zmieniać maskowaną wartość w zależności od typu, rozgałęź logikę na podstawie schema_of_variant() i zwróć odpowiednią wartość dla każdego typu:

CREATE FUNCTION flexible_mask(data VARIANT)
RETURNS VARIANT
RETURN CASE
  WHEN schema_of_variant(data) = 'BIGINT' 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;

Typy liczb całkowitych są rozszerzane do BIGINT w VARIANT, więc uzależnij rozgałęzienie od BIGINT, a nie od INT lub TINYINT.

Maskuj kolumny STRUCT, ARRAY i MAP

To podejście VARIANT maskuje również kolumny o typie złożonym, rozszerzając powyższy przykład numeryczny tak, aby obejmował również dane zagnieżdżone. Kolumna STRUCT, ARRAY lub MAP jest przekazywana do funkcji jako VARIANT, a usługa Azure Databricks rzutuje cokolwiek funkcja zwróci z powrotem na zadeklarowany typ kolumny. Zwrócona wartość musi mieć ten sam schemat co dane wejściowe, w przeciwnym razie rzutowanie nie powiedzie się i zapytanie zwróci błąd.

Uwaga / Notatka

STRUCT kolumny są obsługiwane w Databricks Runtime 18.1 i nowszych wersjach. ARRAY i MAP kolumny są obsługiwane w Databricks Runtime w wersji 19 i nowszych. To rzutowanie działa tylko w zasadach ABAC dotyczących masek kolumn i filtrów wierszy, a nie w ogólnym języku SQL ani w maskach na poziomie tabeli.

Poniższy przykład funkcji maskuje konkretne STRUCT, ARRAY, oraz MAP typy. Dodaj WHEN gałąź dla każdego schematu, który musisz zamaskować:

CREATE OR REPLACE FUNCTION generic_mask(val VARIANT)
RETURNS VARIANT
RETURN CASE
  -- STRUCT<id: INT, ssn: STRING>: keep id, redact ssn
  WHEN schema_of_variant(val) = 'OBJECT<id: BIGINT, ssn: STRING>' THEN
    to_variant_object(named_struct('id', val:id, 'ssn', 'xxx-xx-xxxx'))
  -- ARRAY<STRING>: return a single redacted element
  WHEN schema_of_variant(val) = 'ARRAY<STRING>' THEN
    to_variant_object(array('redacted'))
  -- MAP<STRING, STRING>: redact every value
  WHEN schema_of_variant(val) = 'OBJECT<key1: STRING, key2: STRING>' THEN
    to_variant_object(map('key1', 'redacted', 'key2', 'redacted'))
  ELSE NULL::VARIANT
END;

Każda WHEN gałąź wykonuje dwie funkcje, opisane w następujących sekcjach:

  1. Zidentyfikuj schemat VARIANT. Każdy schemat VARIANT wymaga własnej logiki maskowania, więc funkcja rozgałęzia się w zależności od ciągu schematu, który zwraca schema_of_variant(val), aby zastosować odpowiednie maskowanie do każdego z nich.
  2. Odbuduj wartość maskowaną. Utwórz zanonimizowaną wartość typu tej kolumny i opakuj ją w to_variant_object(), aby zwrócić VARIANT.

Wartoś, której schemat nie pasuje do żadnej gałęzi, przechodzi do ELSE.

Zidentyfikuj schemat VARIANT

Dopasuj do schematu wartości VARIANT , a nie do zadeklarowanego typu kolumny: casting to VARIANT normalizuje dane, dzięki czemu schemat może różnić się od definicji kolumny. Poniższe przykłady pokazują typowe przypadki:

Typ kolumny schema_of_variant() wynik Notes
ARRAY<STRING> ARRAY<STRING>
ARRAY<INT> ARRAY<BIGINT> Typy liczb całkowitych rozszerzają się do BIGINT.
STRUCT<id: INT, name: STRING> OBJECT<id: BIGINT, name: STRING> Kolumny STRUCT i MAP obie stają się OBJECT.
STRUCT<name: STRING, id: INT> OBJECT<id: BIGINT, name: STRING> Pola są sortowane alfabetycznie według klucza, a nie kolejności deklaracji.
ARRAY<STRUCT<id: INT, name: STRING>> ARRAY<OBJECT<id: BIGINT, name: STRING>>
MAP<STRING, STRING> Orzeczenie {a: 'x'} OBJECT<a: STRING> Różni się w zależności od wiersza: klucze każdego wiersza określają schemat.
MAP<STRING, STRING> Orzeczenie {a: 'x', b: 'y'} OBJECT<a: STRING, b: STRING> Inny wiersz tej samej kolumny generuje inny schemat.
MAP<STRING, STRING> Orzeczenie {a: null} OBJECT<a: VOID> Wartość null staje się VOID.
MAP<STRING, STRUCT<id: INT, name: STRING>> Orzeczenie {a: ...} OBJECT<a: OBJECT<id: BIGINT, name: STRING>, ...>

Odbuduj wartość maskowaną

Dla każdego dopasowanego schematu utwórz zanonimizowaną wartość o tej samej strukturze, a następnie umieść ją w elemencie to_variant_object():

  • Użyj named_struct(), aby odbudować STRUCT, zachowując wybrane pola i zastępując pozostałe.
  • Użyj array(), aby ponownie skompilować ARRAY.
  • Użyj map(), aby odtworzyć MAP z zanonimizowanymi wartościami.

Azure Databricks rzutuje zwrócone VARIANT z powrotem na zadeklarowany typ kolumny, więc każda ponownie utworzona wartość musi dać się rzutować na ten typ.

Testuj maskę VARIANT

Zanim przypiszesz funkcję do polityki, możesz przetestować ją w zwykłym zapytaniu, aby potwierdzić zamaskowany wynik. Następująca funkcja maskuje kolumnę ARRAY<STRUCT<id: BIGINT, value: FLOAT>> i powoduje błąd dla dowolnego innego schematu:

CREATE OR REPLACE FUNCTION mask_points(v VARIANT)
RETURNS VARIANT
RETURN CASE
  WHEN schema_of_variant(v) = 'ARRAY<OBJECT<id: BIGINT, value: FLOAT>>' THEN
    to_variant_object(array(named_struct('id', 1, 'value', 2.1)))
  ELSE raise_error('Unexpected VARIANT schema: ' || schema_of_variant(v))
END;

Przekonwertuj kolumnę za pomocą to_variant_object(), zastosuj funkcję maskowania i użyj variant_get(), aby rzutować zamaskowane VARIANT z powrotem na typ kolumny. To odzwierciedla to, co polityka robi w czasie działania:

SELECT variant_get(mask_points(to_variant_object(points)), '$', typeof(points)) AS masked
FROM my_catalog.my_schema.my_table;

Limitations

  • Kolumny złożonej, która zawiera TIME, VARIANT, GEOGRAPHY, GEOMETRY lub VARCHAR, nie można maskować za pomocą CHAR.
  • MAP Klucze muszą być STRING. Kolumny wpisane MAP<INT, ...>, MAP<DATE, ...>, i tak dalej nie są konwertowane.

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.

  1. Zastosuj tag podobny classification : unverified do 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.
  2. Utwórz zasady filtrowania wierszy, które blokują dostęp do tabel oznaczonych tagiem classification : unverified.
  3. Utwórz zasady maski kolumn, które maskują poufne kolumny w tabelach, w których classification : unverified tag nie jest już obecny.
  4. 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:

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:

  1. Administrator konta umożliwia podgląd atrybutów kontekstu UC ABAC z konsoli konta. Zobacz Zarządzanie wersjami zapoznawczami usługi Azure Databricks.
  2. Administrator konta rejestruje niestandardową aplikację OAuth w konsoli konta i zapisuje jej identyfikator klienta.
  3. Połącz agenta z MCP zarządzanym przez Azure Databricks za pośrednictwem tej aplikacji OAuth. Zobacz konfigurację klienta MCP.

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 ustawia request.is_on_behalf_of na '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 klient databricks-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 filtru wierszy może zawierać do sześciu wyrażeń kolumn, a polityka maskowania kolumn może zawierać do trzech wyrażeń kolumn w klauzuli MATCH COLUMNS (patrz Limity zasad).

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);