Lakehouse 列级安全(动态脱敏)使用文档
1. 概述
列级安全(Column-level Security)通过动态脱敏(Dynamic Data Masking)提供细粒度数据保护能力,可根据用户身份或角色动态修改敏感数据的显示方式(如部分隐藏、替换字符)。我们仅存储原始数据,在数据读取运行时才执行脱敏函数(mask function)。本文档介绍如何通过 SQL 接口实现此功能。
2. 核心语法
2.1 创建脱敏策略函数
参考CREATE FUNCTION(SQL)语法
CREATE FUNCTION [schema_name.]function_name (col_name column_type)
RETURNS output_type
AS
expression_with_conditional_logic;
关键要素:
- 必须返回与原始列相同的数据类型
- 使用安全上下文函数:
current_user()
获取当前用户(注意大小写)
current_roles()
获取用户角色数组
2.2 绑定策略到列
创建表时指定:
CREATE TABLE table_name (
col1 STRING MASK schema_name.masking_function,
...
);
修改已有表:
ALTER TABLE table_name
CHANGE COLUMN column_name
SET MASK schema_name.masking_function;
添加列时指定脱敏:
ALTER TABLE table_nameADD COLUMN (column_name column_typeMASK schema_name.masking_function);
2.3 解除策略绑定
ALTER TABLE table_name
CHANGE COLUMN column_name
UNSET MASK;
3. 使用场景示例
3.1 基础脱敏
需求: 身份证号前6位+4星号+后4位
CREATE FUNCTION public.idcard_masking(idcard STRING)
RETURNS STRING
AS concat(substr(idcard, 1, 6), repeat('*', 4), substr(idcard, 10, 4));
ALTER TABLE data CHANGE COLUMN idcard SET MASK public.idcard_masking;
查询效果:
原始值:130183199901011234 → 脱敏后:130183****9010
3.2 基于用户的动态脱敏
需求: 仅UAT_TEST用户看到脱敏数据
CREATE FUNCTION public.idcard_masking(idcard STRING)
RETURNS STRING
AS
CASE
WHEN current_user() = "UAT_TEST"
THEN concat(substr(idcard, 1, 6), repeat('*', 4), substr(idcard, 10, 4))
ELSE idcard
END;
--忽略用户名大小写
CREATE FUNCTION public.idcard_masking(idcard STRING)
RETURNS STRING
AS
CASE
WHEN lower(current_user()) = "uat_test"
THEN concat(substr(idcard, 1, 6), repeat('*', 4), substr(idcard, 10, 4))
ELSE idcard
END;
3.3 基于角色的动态脱敏
需求: user_admin角色可查看完整信息
CREATE FUNCTION public.idcard_masking_role(idcard STRING)
RETURNS STRING
AS
CASE
WHEN array_contains(current_roles(), "user_admin")
THEN idcard
ELSE concat(substr(idcard,1,6), '****', substr(idcard,11,4))
END;
4. 完整操作示例
4.1 初始化环境
CREATE SCHEMA IF NOT EXISTS security_demo;
USE security_demo;
-- 通用掩码函数
CREATE FUNCTION security_demo.ssn_mask(ssn STRING)
RETURNS STRING
AS concat('***-**-', substr(ssn, 8, 4));
CREATE TABLE security_demo.user_data (
name STRING,
ssn STRING MASK security_demo.ssn_mask, -- 建表时直接绑定
phone STRING
);
INSERT INTO security_demo.user_data VALUES('James', '123-45-6789','123456789');
SELECT * FROM security_demo.user_data;
4.2 创建策略函数
-- 特权角色豁免
CREATE FUNCTION security_demo.admin_ssn_mask(ssn STRING)
RETURNS STRING
AS
CASE
WHEN array_contains(current_roles(), 'user_admin') THEN ssn
ELSE concat('***-**-', substr(ssn,8,4))
END;
4.3 修改脱敏策略
--去除之前的策略
ALTER TABLE security_demo.user_data CHANGE COLUMN ssn UNSET MASK;
--添加新的策略
ALTER TABLE security_demo.user_data CHANGE COLUMN ssn SET MASK security_demo.admin_ssn_mask;
4.4 验证效果
普通用户查询:
SELECT * FROM user_data;
-- 输出:John Doe ***-**-6789 138****1234
USER_ADMIN角色查询:
SELECT * FROM user_data;
-- 输出:John Doe 123-45-6789 138****1234
5. 管理注意事项
5.1 权限控制
- 仅允许具有
ALTER TABLE
权限的角色修改脱敏策略
- 函数创建需要
CREATE FUNCTION
权限
5.2 性能建议
- 避免在脱敏函数中使用复杂计算
- 对高频查询列谨慎使用条件判断逻辑
6. 限制说明
- 单个列只能绑定一个脱敏策略,如果您想定义多种脱敏规则,可以在一个函数中基于条件判断进行不同的策略