-- UC(三级)
GRANT SELECT ON TABLE payments_catalog.raw.orders TO ROLE payments_analyst;
-- Lakehouse(两级)— 去掉 catalog 前缀
GRANT SELECT ON TABLE gov_raw.orders TO ROLE payments_analyst;
第二步:RBAC — 语法完全一致
GRANT/REVOKE/SHOW GRANTS 语法零改动:
-- 两边完全相同
CREATE ROLE IF NOT EXISTS payments_analyst;
CREATE ROLE IF NOT EXISTS payments_admin;
GRANT SELECT ON TABLE gov_raw.orders TO ROLE payments_analyst;
GRANT ALL PRIVILEGES ON SCHEMA gov_raw TO ROLE payments_admin;
GRANT SELECT ON ALL TABLES IN SCHEMA gov_raw TO ROLE payments_viewer;
GRANT SELECT ON TABLE gov_raw.users TO ROLE payments_admin WITH GRANT OPTION;
SHOW GRANTS TO ROLE payments_analyst;
第三步:列脱敏 —
SET MASK
SET MASK
相同,函数 API 改一处
UC 用
is_account_group_member()
is_account_group_member()
,Lakehouse 用
array_contains(current_roles(), 'workspace.role')
array_contains(current_roles(), 'workspace.role')
:
# UC 脱敏函数
CREATE FUNCTION payments_catalog.raw.mask_email(email STRING)
RETURN CASE
WHEN is_account_group_member('payments_admin') THEN email
ELSE CONCAT(LEFT(email, 2), '***@***.***')
END;
-- Lakehouse 脱敏函数(只改判断 API,逻辑一致)
CREATE OR REPLACE FUNCTION gov_raw.mask_email(email STRING)
RETURNS STRING
RETURN CASE
WHEN array_contains(current_roles(), 'quick_start.payments_admin') -- ← current_roles()
OR array_contains(current_roles(), 'workspace_admin')
THEN email
ELSE CONCAT(LEFT(email, 2), '***@***.***')
END;
-- SET MASK 应用语法完全相同
ALTER TABLE gov_raw.users ALTER COLUMN email SET MASK gov_raw.mask_email;
ALTER TABLE gov_raw.users ALTER COLUMN phone SET MASK gov_raw.mask_phone;
ALTER TABLE gov_raw.accounts ALTER COLUMN card_number SET MASK gov_raw.mask_card;
实测脱敏效果(非 admin 用户看到):
字段
原始值
脱敏后
email
user001@example.com
user001@example.com
u***@***.***
u***@***.***
phone
+12345678901
+12345678901
****8901
****8901
card_number
4866524041574
4866524041574
****-****-****-1574
****-****-****-1574
第四步:行级安全 —
SET ROW FILTER
SET ROW FILTER
语法完全一致
Lakehouse 原生支持
SET ROW FILTER
SET ROW FILTER
,与 UC 语法完全一致,零改动:
-- UC(Databricks)
CREATE FUNCTION payments_catalog.raw.filter_orders_by_region(region STRING)
RETURN CASE
WHEN is_account_group_member('payments_admin') THEN TRUE
WHEN is_account_group_member('payments_analyst')
AND region = 'North America' THEN TRUE
ELSE FALSE
END;
ALTER TABLE payments_catalog.raw.orders
SET ROW FILTER payments_catalog.raw.filter_orders_by_region ON (region);
-- Lakehouse — 语法完全一致,只改函数体里的 is_account_group_member
CREATE OR REPLACE FUNCTION gov_raw.filter_orders_by_role(region STRING)
RETURNS BOOLEAN
AS
array_contains(current_roles(), 'quick_start.payments_admin')
OR array_contains(current_roles(), 'workspace_admin')
OR (array_contains(current_roles(), 'quick_start.payments_analyst')
AND region = 'North America')
OR (array_contains(current_roles(), 'quick_start.payments_viewer')
AND region = 'Asia');
-- SET ROW FILTER 语法完全相同
ALTER TABLE gov_raw.orders SET ROW FILTER gov_raw.filter_orders_by_role ON (region);
-- 验证绑定
DESC EXTENDED gov_raw.orders;
-- 输出末尾显示 # Row Filter 段
-- 移除
ALTER TABLE gov_raw.orders DROP ROW FILTER;
-- UC 审计
SELECT event_time, user_name, action_name, request_params
FROM system.access.audit
WHERE event_time >= current_timestamp() - INTERVAL 7 DAYS
AND action_name IN ('createTable','grantPermission','revokePermission');
-- Lakehouse 审计(列名不同,日期用字面量字符串)
SELECT
job_type,
job_creator, -- UC: user_name
LEFT(job_text, 100) AS sql_preview, -- UC: request_params
status,
LEFT(start_time, 19) AS time
FROM sys.information_schema.job_history
WHERE start_time >= '2026-06-07' -- 必须字面量,不能用 NOW() - INTERVAL
AND (UPPER(job_text) LIKE 'GRANT%'
OR UPPER(job_text) LIKE 'REVOKE%'
OR UPPER(job_text) LIKE 'CREATE TABLE%')
ORDER BY start_time DESC;