Satır filtreleme ve sütun maskeleme için ortak desenler

Bu sayfada, ABAC satır filtresi ve sütun maskesi ilkeleri uygulamak için yaygın desenler açıklanmaktadır.

Dönüşümle uyumlu maskeleme işlevleri

Azure Databricks maskeleme işlevi çıkışını hedef sütunun veri türüyle eşleşecek şekilde otomatik olarak yayınlar. Ayrıntılı bilgi için bakınız Sütun maskeleri için otomatik tür dönüştürme.

Aşağıdaki şablonlar, dönüşüme uyumlu maskeleme fonksiyonları tasarlamanıza yardımcı olur.

Türü dönüştürülmüş geri döndürme

Bir sütunu maskelerken, aynı veri türünü veya bu veri türüne dönüştürülebilen bir türü döndürün. İlkenizin hedeflediğini sütunların veri türlerini denetleyin ve işlevin her dalının uyumlu bir değer döndürdüğünü doğrulayın.

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

Sayısal taşma önleme

Maske işlevi hedef sütundan daha geniş bir sayısal türü kabul edip döndürdüğünde, sonuç otomatik olarak sütunun türüne geri döner. Döndürülen değer daha dar türün aralığını aşarsa, atama taşması ve sorgu çalışma zamanında başarısız olur.

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

Birden çok sütun türü için VARIANT kullanma

Bkz. Birden çok sütun türü için DEĞIŞKEN tabanlı maskeleme işlevleri.

Yayın uyumluluğunu test edin

Maskeleme işlevlerini farklı veri desenleriyle test etme.

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;

Birden çok sütun türü için VARYANT tabanlı maskeleme işlevleri

Farklı veri türlerindeki sütunları maskelemeniz gerektiğinde (örneğin, INT, DOUBLE, DECIMAL(10,2), DECIMAL(15,5)vb.), türü kabul eden ve döndüren tek bir VARIANT maskeleme UDF'si yazabilirsiniz. Azure Databricks, ANSI SQL standartlarına göre hedef sütunun veri türüyle uyumlu olacak şekilde sütun maskesi işlevinin çıktısını otomatik olarak dönüştürür.

Bu yaklaşım, gereken UDF'lerin ve ilkelerin sayısını azaltır. Her sütun türü için ayrı maskeleme işlevleri yazmak yerine, bir işlev tüm türleri işler.

Tek bir işlevle birden çok sayısal türü maskele

Her sayısal duyarlık için ayrı bir maske işlevi oluşturmak yerine, hepsini tek bir işlevle işlemek için kullanabilirsiniz VARIANT :

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

Bu işlev, Azure Databricks'in hedef sütunun türüne otomatik olarak dönüştürdüğü 0 olarak VARIANT döndürür. Bu işlevi kullanan tek bir ABAC ilkesi, her duyarlık için ayrı işlevler gerektirmeden INT, DOUBLE, ve DECIMAL sütunlarını maskeleyebilir.

Türü işlev içinde açıkça korumayı tercih ederseniz, türü dallandırabilir ve kullanarak schema_of_variant()her birine uygun bir maskelenmiş değer döndürebilirsiniz:

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

VARIANT ile yapı sütunlarını maskeleme

Databricks Runtime 18.1 ve üstü için, yapı sütunlarını bir ABAC ilkesi içinde VARIANT olarak dönüştürerek maskeleyebilirsiniz. Yapının şekline göre dallandırarak alanları seçmeli olarak gizleyin.

Note

Maskeleme amacıyla VARIANT içine struct ataması yapılması yalnızca ABAC sütun maskeleme politikaları kapsamında desteklenir.

Aşağıdaki örnek, iki farklı yapı şeklini tanımlamak ve her birinde hassas alanları gizlemek için schema_of_variant() kullanır.

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;

Hassas sütunlar etiketlenene kadar erişimi engelleme

Yaygın bir idare düzeni, verilerin sınıflandırılıp sınıflandırılmadığını temel alarak erişimi denetlemektir. Bunu, sınıflandırma durumuna bağlı olarak farklı koruma düzeylerini zorunlu kılan varsayılan kısıtlayıcı etiket ve ilkelerle uygulayabilirsiniz.

  1. Etiketi katalog veya şema düzeyinde uygulayarak otomasyon aracılığıyla veya etiket devralma yoluyla varsayılan olarak tüm yeni nesnelere benzer classification : unverified bir etiket uygulayın; böylece kataloğa veya şemaya eklenen tüm yeni tablolar etiketi otomatik olarak devralır.
  2. etiketli classification : unverifiedtablolara erişimi engelleyen bir satır filtresi ilkesi oluşturun.
  3. Etiketin artık bulunmadığı tablolardaki classification : unverified hassas sütunları maskeleyen bir sütun maske ilkesi oluşturun.
  4. Veri temsilcisi sınıflandırmayı tamamladığında etiketi güncelleştirir. Engelleme ilkesi artık eşleşmez ve maskeleme ilkesi devreye girer.
-- 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');

Sınıflandırıldıktan sonra hassas verileri korumak için etiket artık mevcut olmadığında classification : unverified etkili olacak bir sütun maskesi ilkesi tanımlayın:

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;

Reex olmadan kısmi açığa çıkar

Regex yerine dize işlemlerini kullanarak hassas bir değerin bir kısmını ortaya çıkar. Regex tabanlı maskeleme, büyük metin alanlarında pahalı olan her satır için tüm değeri tarar (bkz. Büyük metin alanlarında regex maskelemekten kaçınma).

CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
DETERMINISTIC
  RETURN CONCAT('***-**-', RIGHT(ssn, show_last));

Tutarlı karma oluşturma (belirleyici takma ad oluşturma)

Tutarlı karma (belirlenimci pseudonimleştirme olarak da adlandırılır), hassas verileri birden çok tabloda aynı karma değerle değiştirir. İşlevi olarak DETERMINISTIC işaretlemek, altyapıya işlevin her zaman aynı giriş için aynı sonucu döndürdüğünü bildirir ve bu da sorguyu iyileştirmeye yardımcı olur. Bkz Deterministic ve hata güvenli ifadeleri kullanma.

Aşağıdaki işlev, bir dize değerini tutarlı bir şekilde hash eder ve anahtar rotasyonu desteklemek için bir version parametresi kullanır. Politikanın version maddesi aracılığıyla sayıyı artırarak, önceki sürümü kullanan geçmiş verileri bozmadan yeni karmalar oluşturun. İşlev, özgün değeri karma oluşturmadan önce sürüm numarasıyla birleştirir, bu nedenle aynı sürüme sahip aynı giriş her zaman aynı karmayı üretir.

CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
  RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);

Yalnızca sütun koşullarını içeren satır filtreleme

Yalnızca tablo sütunlarına başvuran basit boole mantığı kullanarak satırları filtreleyin. Yalnızca sütun koşulları, altyapının taramalar sırasında ilgisiz verileri atlamasına olanak tanıyan koşul itme yeteneğini etkinleştirir (bkz. Korumalı tablolarda koşul itme işlemini anlama).

CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
  RETURN array_contains(split(allowed, ','), lower(region));

İzin verilen bölgeleri sabit olarak geçiren bir ilkeyle kullanın:

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

Birden çok ilişkili sütunda satır filtreleme

Bir tabloda ilişkili öznitelikleri (örneğin ve ship_to_country) temsil eden birden çok sütun olduğunda, bill_to_country bunları ayrı etiket koşullarıyla eşleştirebilir ve her ikisini de tek bir UDF'ye geçirebilirsiniz. Bu, her sütun için ayrı ilkeler oluşturulmasını önler. İlke yan tümcesinde MATCH COLUMNS en fazla üç sütun ifadesi içerebilir (bkz. İlke kotaları).

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

Analist yalnızca sevkiyat veya faturalama ülkesinin izin verilenler listesinde olduğu siparişleri görür.

ABAC politika UDF'lerinde tablo aramaları

Erişim kuralları kullanıcı başına farklılık gösterdiğinde ve yalnızca ilkenin TO/EXCEPT yan tümceleri aracılığıyla ifade edilemediğinde, erişim haklarını küçük bir arama tablosuna göre de kontrol edebilirsiniz. Sorumluları hedeflemek için tercih edilen yaklaşım olduğundan mümkün olduğunda kullanın TO/EXCEPT (bkz. Sorumluları hedefleme yaklaşımı). Optimizatörün alt sorguyu yayınlama karma birleştirmeye dönüştürebilmesi için arama tablosunu küçük tutun (bkz. Arama tablolarını küçük tutma).

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