Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Auf dieser Seite werden allgemeine Muster für die Implementierung von ABAC-Zeilenfilter- und Spaltenformatrichtlinien beschrieben. Allgemeine Konzepte finden Sie unter Kernkonzepte für die attributbasierte Zugriffssteuerung (ABAC). Informationen zur Richtliniensyntax finden Sie unter Erstellen und Verwalten von ABAC-Richtlinien.
Cast-kompatible Maskierungsfunktionen
Azure Databricks wandelt die Ausgabe der Maskierungsfunktion automatisch in den Datentyp der Zielspalte um. Weitere Informationen finden Sie unter Automatische Typumwandlung für Spaltenmasken.
Die folgenden Muster helfen Ihnen beim Entwerfen von casting-kompatiblen Maskierungsfunktionen.
Zurückgeben eines umwandlungsfähigen Typs
Wenn Sie eine Spalte maskieren, verwenden Sie denselben Datentyp oder einen Typ, der in diesen Typ konvertiert werden kann. Überprüfen Sie die Datentypen der Spalten, auf die Ihre Richtlinienziele ausgerichtet sind, und überprüfen Sie, ob jede Verzweigung der Funktion einen kompatiblen Wert zurückgibt.
-- 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;
Vermeiden eines numerischen Überlaufs
Wenn eine Maskenfunktion einen breiteren numerischen Typ als die Zielspalte akzeptiert und zurückgibt, wird das Ergebnis automatisch in den Spaltentyp zurückgeworfen. Wenn der zurückgegebene Wert den Bereich des schmaleren Typs überschreitet, überläuft die Umwandlung und die Abfrage scheitert während der Laufzeit.
-- 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;
Verwenden von VARIANT für mehrere Spaltentypen
Siehe VARIANT-basierte Maskierungsfunktionen für mehrere Spaltentypen.
Testen der Umwandlungskompatibilität
Testen Sie Maskierungsfunktionen mit unterschiedlichen Datenmustern.
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-basierte Maskierungsfunktionen für mehrere Spaltentypen
Wenn Sie Spalten unterschiedlicher Datentypen (z.B. INT, DOUBLE, DECIMAL(10,2), DECIMAL(15,5) usw.) maskieren müssen, können Sie eine einzelne maskierende Funktion schreiben, die einen VARIANT Typ akzeptiert und zurückgibt. Azure Databricks konvertiert die Ausgabe der Spaltenmaskierungsfunktion automatisch, sodass sie mit dem Datentyp der Zielspalte übereinstimmt, gemäß den ANSI SQL-Standards.
Dieser Ansatz reduziert die Anzahl der UDFs und Richtlinien, die erforderlich sind. Anstatt separate Maskierungsfunktionen für jeden Spaltentyp zu schreiben, behandelt eine Funktion alle Typen.
Mehrere numerische Typen mit einer einzigen Funktion maskieren
Anstatt eine separate Maskenfunktion für jede numerische Genauigkeit zu erstellen, können Sie sie alle mit einer einzelnen Funktion behandeln: VARIANT
CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;
Diese Funktion gibt 0 als VARIANT zurück, den Azure Databricks automatisch in den Typ der Zielspalte konvertiert. Eine einzelne ABAC-Richtlinie, die diese Funktion verwendet, kann die Spalten INT, DOUBLE und DECIMAL maskieren, ohne separate Funktionen für jede Präzision zu erfordern.
Wenn Sie den Typ explizit innerhalb der Funktion beibehalten möchten, können Sie den Typ abzweigen und für jeden einen geeigneten maskierten Wert mithilfe von schema_of_variant() zurückgeben.
-- 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;
Strukturspalten maskieren mit VARIANT
Für Databricks Runtime 18.1 und höher können Sie Strukturspalten auch maskieren, indem Sie sie in VARIANT innerhalb einer ABAC-Richtlinie konvertieren. Verzweigen Sie das Shape der Struktur, um selektiv Felder zu redigieren:
Note
Umwandlung von Strukturen zu VARIANT für die Maskierung wird nur in ABAC-Spaltenmaskenrichtlinien unterstützt.
Im folgenden Beispiel wird schema_of_variant() verwendet, um zwei unterschiedliche Strukturschablonen zu identifizieren und vertrauliche Felder in jeder zu schwärzen.
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;
Verhindern des Zugriffs, bis vertrauliche Spalten markiert sind
Ein gängiges Governancemuster besteht darin, den Zugriff basierend darauf zu steuern, ob Daten klassifiziert wurden. Sie können dies mit einem standardmäßigen restriktiven Tag und Richtlinien implementieren, die je nach Klassifizierungsstatus unterschiedliche Schutzebenen erzwingen.
- Wenden Sie ein Tag wie
classification : unverifiedstandardmäßig auf alle neuen Objekte an, über automatisierungs- oder tagvererbung, indem Sie das Tag auf Katalog- oder Schemaebene anwenden, sodass alle neuen Tabellen, die dem Katalog oder Schema hinzugefügt werden, automatisch das Tag erben. - Erstellen Sie eine Zeilenfilterrichtlinie, die den Zugriff auf markierte
classification : unverifiedTabellen blockiert. - Erstellen Sie eine Spaltenmaskierungsrichtlinie, die vertrauliche Spalten in Tabellen maskiert, in denen das
classification : unverifiedTag nicht mehr existiert. - Wenn ein Data Steward die Klassifizierung abgeschlossen hat, aktualisiert der Data Steward das Etikett. Die Blockierungsrichtlinie stimmt nicht mehr überein, und die Maskierungsrichtlinie wird wirksam.
-- 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');
Um vertrauliche Daten nach der Einstufung zu schützen, definieren Sie eine Spaltenmaskierungsrichtlinie, die wirksam wird, wenn das classification : unverified Tag nicht mehr vorhanden ist.
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;
Partielle Anzeige ohne regex
Zeigen Sie einen Teil eines vertraulichen Werts mithilfe von Zeichenfolgenvorgängen anstelle von regex an. Regex-basierte Maskierung überprüft den gesamten Wert für jede Zeile, was für große Textfelder teuer ist (siehe Vermeiden der Regex-Maskierung für große Textfelder).
CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
DETERMINISTIC
RETURN CONCAT('***-**-', RIGHT(ssn, show_last));
Konsistentes Hashing (deterministische Pseudonymisierung)
Durch konsistentes Hashing (auch als deterministische Pseudonymisierung bezeichnet) werden vertrauliche Daten durch einen Hashwert ersetzt, der in mehreren Tabellen identisch ist. Indem eine Funktion als DETERMINISTIC markiert wird, wird der Engine mitgeteilt, dass die Funktion bei derselben Eingabe immer dasselbe Ergebnis liefert, was hilft, die Abfrage zu optimieren. Siehe Verwenden von deterministischen, fehlersicheren Ausdrücken.
Die folgende Funktion erstellt konsistent einen Hash-Wert für eine Zeichenfolge und verwendet einen version Parameter, um die Schlüsselrotation zu unterstützen. Erhöhen Sie die version Zahl durch die Klausel der Richtlinie USING COLUMNS , um neue Hashes zu generieren, ohne historische Daten zu unterbrechen, die die vorherige Version verwendet haben. Die Funktion verkettet den ursprünglichen Wert mit der Versionsnummer vor dem Hashing, sodass dieselbe Eingabe mit derselben Version immer denselben Hash erzeugt.
CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);
Zeilenfilterung mit Nur-Spalten-Prädikaten
Filtern Sie Zeilen mithilfe einfacher boolescher Logik, die nur auf Tabellenspalten verweist. Nur Spaltenprädikate ermöglichen Prädikat-Pushdown, wodurch die Engine irrelevante Daten während Scans überspringen kann (siehe Grundlegendes zum Prädikat-Pushdown in geschützten Tabellen).
CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(region));
Wird mit einer Richtlinie verwendet, die die zulässigen Regionen als Konstante übergibt:
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');
Zeilenfilterung über mehrere verwandte Spalten
Wenn eine Tabelle mehrere Spalten hat, die verwandte Attribute darstellen (z. B. ship_to_country und bill_to_country), können Sie diese mit separaten Tag-Bedingungen abgleichen und beide an eine einzelne UDF übergeben. Dadurch wird verhindert, dass für jede Spalte separate Richtlinien erstellt werden. Eine Richtlinie kann bis zu drei Spaltenausdrücke in der MATCH COLUMNS Klausel enthalten (siehe Richtlinienkontingente).
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');
Ein Analyst sieht nur Bestellungen, bei denen sich entweder das Versand- oder Abrechnungsland in ihrer zulässigen Liste befindet.
Tabellenabfrage in ABAC-Richtlinien-UDFs
Wenn Zugriffsregeln je Benutzer variieren und nicht allein über die Klauseln der Richtlinie TO/EXCEPT ausgedrückt werden können, können Sie die Zugriffsrechte gegen eine kleine Nachschlagetabelle abgleichen. Verwenden Sie TO/EXCEPT nach Möglichkeit, da es sich um den bevorzugten Ansatz für Zielprinzipale handelt (siehe Ansatz für Zielprinzipale). Halten Sie die Nachschlagetabelle klein, damit der Optimierer die Unterabfrage in eine Broadcast-Hashverknüpfung konvertiert (siehe Nachschlagetabellen klein).
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);