当您期望某些用户只可以查看MaxCompute项目中隐藏关键信息的敏感数据时,您可以开启MaxCompute动态脱敏功能,在数据访问或展示时实时隐藏或替换敏感数据,以防止敏感数据泄露。本文为您介绍如何开启MaxCompute动态脱敏功能,并提供参考示例。
功能介绍
MaxCompute提供数据动态脱敏功能,用于业务开发测试、数据共享、运维等场景中对个人身份信息(PII)等敏感数据以脱敏计算和展示的方式进行保护。脱敏策略支持掩码、散列、字符替换、数值取整、日期取整等脱敏策略,支持与数据保护伞的数据分类分级功能联动,满足用户对身份信息、银行卡号、地址、电话等数据的脱敏需求。
MaxCompute数据脱敏在最靠近数据从存储中读取的环节中实现,确保数据在查询、下载、关联、UDF计算时已经处于脱敏状态,避免敏感数据泄露风险。
使用限制
支持地域
该功能目前处于公测阶段,仅华东1(杭州)、华东2(上海)、华北2(北京)、华北3(张家口)、华北6(乌兰察布)、华南1(深圳)、西南1(成都)、中国香港、日本(东京)、马来西亚(吉隆坡)、印度尼西亚(雅加达)、德国(法兰克福)地域支持数据动态脱敏。
支持的驱动版本
MaxCompute连接方式
驱动版本
脱敏功能支持情况
Java SDK
0.48.0-public及以上版本
支持
odpscmd
0.47.1及以上版本
支持
JDBC
3.4.3及以上版本
支持
MaxFrame
不限制
支持
PyODPS
不限制
支持
Go SDK
不限制
支持
内部表
MaxCompute内部表支持数据脱敏策略,外部表不支持。
数据脱敏与行级权限功能互斥,已配置脱敏策略的表不支持再配置行级权限策略,反之亦然。
对中文字符使用掩码策略脱敏时,中文字符编码格式必须为UTF-8。
视图
传统的视图支持数据脱敏策略,视图脱敏策略与原脱敏表脱敏策略同步,当原表绑定、解绑脱敏策略时,传统的视图会同步生效。
物化视图依据视图创建时原表的脱敏策略建立对应的脱敏数据视图。当原表继续绑定、解绑脱敏策略时,物化视图维持创建时的脱敏策略不变。
脱敏策略
当用户访问敏感数据时,如果同时有多条脱敏策略生效,将执行优先级较高的脱敏策略对敏感数据进行脱敏。详情请参见预定义脱敏策略优先级。
数据脱敏流程
在数据返回过程中,会检查用户对应的脱敏规则配置情况,如果已经配置了脱敏规则,需要按照规则返回脱敏后的数据,如果没有配置则返回明文。
脱敏命令
项目开启或关闭数据脱敏功能
脱敏功能开关odps.data.masking.policy.enable
为项目空间的Project级属性,只有项目Owner或被赋予项目级别的Super_Administrator和Admin角色的账号可以进行操作,操作详情请参见为用户赋予内置管理角色。
项目开启数据脱敏功能。
setproject odps.data.masking.policy.enable=true;
项目关闭数据脱敏功能。
setproject odps.data.masking.policy.enable=false;
创建和删除脱敏策略
命令格式
创建脱敏策略。
CREATE DATA MASKING POLICY [IF NOT EXISTS] <policy_name> TO { USER <user_list> | ROLE <role_list> | default } USING <Predefined Masking Policy>;
删除脱敏策略。
DROP DATA MASKING POLICY <policy_name>;
参数说明
参数名称
是否必填
描述
policy_name
是
脱敏策略名称。策略名称大小写不敏感,不支持特殊字符,只能包含a~z、A~Z、数字和下划线。建议以字母开头,名称的长度不超过128字节。
USER | ROLE | default
是
三者选其一。
USER:对用户脱敏,<user_list>填写待脱敏的用户名称。您可以在MaxCompute中执行
list users;
命令获取角色信息。ROLE:对角色脱敏,<role_list>填写待脱敏的角色名称。您可以在MaxCompute中执行
list roles;
命令获取角色信息。default:默认脱敏,用户或角色访问敏感列时如果没有匹配到脱敏策略,那么采用default策略对敏感列进行脱敏。
Predefined Masking Policy
是
预定义的脱敏策略,详情请参见预定义脱敏策略。
使用示例
示例1:为用户userA、userB和userC创建MD5哈希脱敏策略。
CREATE data masking policy IF NOT EXISTS masking_test_001 TO USER (userA, userB, userC) USING MASKED_MD5(0);
示例2:为项目开发角色和运维角色创建MD5哈希脱敏策略。
CREATE data masking policy IF NOT EXISTS masking_test_001 TO ROLE (role_project_deploy, role_project_dev) USING MASKED_MD5(0);
将脱敏策略应用于敏感数据列
命令格式
--将脱敏策略应用于敏感表的敏感数据列 APPLY DATA MASKING POLICY <policy_name> BIND TO TABLE <table_name> COLUMN <column_name>; --为敏感表的敏感数据列取消指定的脱敏策略 APPLY DATA MASKING POLICY <policy_name> UNBIND FROM TABLE <table_name> COLUMN <column_name>; --为敏感表的敏感数据列取消全部脱敏策略 APPLY DATA MASKING POLICY UNBIND ALL FROM TABLE <table_name> COLUMN <column_name>; --为敏感表的全部敏感数据列取消全部脱敏策略 APPLY DATA MASKING POLICY UNBIND ALL FROM TABLE <table_name>;
参数说明
参数名称
是否必填
描述
policy_name
是
脱敏策略名称。
table_name
是
表名称。包含敏感数据的表。
column_name
是
列名称。包含敏感数据的列。
查看脱敏策略
命令格式
--查看脱敏策略的创建信息 DESC DATA MASKING POLICY <policy_name>; --查看表的扩展信息,包含敏感数据列的信息应用的脱敏策略信息 DESC EXTENDED <table_name>; --显示当前Project下所有的脱敏策略名称 LIST DATA MASKING POLICY; --显示与指定用户绑定的脱敏策略名称 LIST DATA MASKING POLICY TO USER <user_name>; --显示与指定角色绑定的脱敏策略名称 LIST DATA MASKING POLICY TO ROLE <role_name>; --显示与指定表绑定的所有脱敏策略名称 LIST DATA MASKING POLICY ON <table_name>; --显示与指定表指定列绑定的所有脱敏策略名称 LIST DATA MASKING POLICY ON <table_name> TO COLUMN <column_name>;
参数说明
参数名称
是否必填
描述
policy_name
是
脱敏策略名称。
table_name
是
表名称。包含敏感数据的表。
column_name
是
列名称。包含敏感数据的列。
user_name
是
用户名称。
role_name
是
角色名称。
预定义脱敏策略
预定义脱敏策略包含掩码、散列、字符替换、取整等脱敏策略,您可以根据敏感数据类型选择适用的脱敏策略实现数据保护。
策略类型 | 策略名称 | 命令格式 | 描述 |
通用 | 不脱敏 | UNMASKED | 不脱敏。 支持类型:全部类型。 |
置空值 | MASKED_NULLIFY | 置空值,数据脱敏后返回NULL。
| |
赋默认值 | MASKED_DV | 赋默认值,每种数据类型的默认值请参见赋默认值脱敏策略(MASKED_DV)的赋值参考。
| |
只保留年份 | MASKED_DATE_YEAR | 只保留时间的年份数值,非年份数值设置为1月1日00:00(UTC时间)。
| |
取整 | MASKED_POINT_RESERVE(<num>) | 取整,保留小数点后0~5位小数。
| |
掩码 | 字符串头尾部分掩码 | MASKED_STRING_MASKED_BA(<before>, <after>) | 字符串头尾部分用
|
字符串中间部分掩码 | MASKED_STRING_UNMASKED_BA(<before>, <after>) | 字符串头尾部分用明文,中间部分用
| |
散列 | SHA256散列 | MASKED_SHA256(<salt>) | SHA256散列算法脱敏。
|
SHA512散列 | MASKED_SHA512(<salt>) | SHA512散列算法脱敏。
| |
MD5散列 | MASKED_MD5(<salt>) | MD5散列算法脱敏。
| |
SM3散列 | MASKED_SM3(<salt>) | SM3散列算法脱敏。
| |
字符替换 | 随机字符替换 | MASKED_REPLACE_RANDOM(<position>) | 用随机字符替换数据,替换后字符串长度不变,随机值包括数字和英文字母。
|
头尾随机字符替换 | MASKED_REPLACE_RANDOM_BA(<before>, <after>) | 用随机字符替换数据的头尾部分,替换后字符串长度不变,随机值包括数字和英文字母。
| |
固定字符替换 | MASKED_REPLACE_FIXED(<position>, <fixed_string>) |
|
使用示例
个人敏感信息脱敏
此处以个人敏感信息为例,为您展示如何配置敏感策略,并对敏感信息进行脱敏。
数据准备。
创建个人敏感信息表,并插入敏感数据。
-- 创建敏感信息表 CREATE TABLE if NOT EXISTS personal_info ( id bigint COMMENT '用户唯一标识ID', name string COMMENT '用户姓名', age int COMMENT '用户年龄', gender string COMMENT '用户性别', height float COMMENT '用户身高', birthday date COMMENT '用户生日', phone_number string COMMENT '用户电话号码', email string COMMENT '用户电子邮箱', address string COMMENT '用户地址', salary decimal(18, 2) COMMENT '用户薪水', create_time timestamp COMMENT '用户信息创建时间', update_time timestamp COMMENT '用户信息更新时间', is_deleted boolean COMMENT '用户信息是否被删除的标志位' ); -- 插入敏感数据 INSERT INTO personal_info VALUES (1, '张三', 18, '男', 178.56, '1990-01-01', '13800000000', 'zhangsan@example.com', '北京市海淀区', 5000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00', false), (2, '李四', 20, '女', 162.70, '1992-02-02', '13900000000', 'lisi@example.com', '上海市浦东新区', 6000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00',false), (3, '王五', 22, '男', 185.21, '1994-03-03', '14000000000', 'wangwu@example.com', '深圳市南山区', 7000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00', false);
配置脱敏策略。
姓名只保留第1个字,其他字符用
*
代替。CREATE data masking policy IF NOT EXISTS masking_name TO USER (RAM$xxx@test.aliyunid.com:xxx) USING MASKED_STRING_UNMASKED_BA(1, 0); apply data masking policy masking_name bind TO TABLE personal_info COLUMN name;
身高字段取整。
CREATE data masking policy IF NOT EXISTS masking_height TO USER (RAM$xxx@test.aliyunid.com:xxx) USING MASKED_POINT_RESERVE(0); apply data masking policy masking_height bind TO TABLE personal_info COLUMN height;
生日只保留年份。
CREATE data masking policy IF NOT EXISTS masking_birthday TO USER (RAM$xxx@test.aliyunid.com:xxx) USING MASKED_DATE_YEAR; apply data masking policy masking_birthday bind TO TABLE personal_info COLUMN birthday;
默认用户使用SM3算法哈希电话号码。
CREATE DATA MASKING POLICY default_sm3 TO DEFAULT USING MASKED_SM3(0); apply data masking policy default_sm3 bind TO TABLE personal_info COLUMN phone_number;
使用被脱敏账号,查询脱敏后的数据。
SELECT id, name, height, birthday, phone_number FROM personal_info; -- 脱敏前 +------------+------+--------+----------+--------------+ | id | name | height | birthday | phone_number | +------------+------+--------+----------+--------------+ | 1 | 张三 | 178.56 | 1990-01-01 | 13800000000 | | 2 | 李四 | 162.7 | 1992-02-02 | 13900000000 | | 3 | 王五 | 185.21 | 1994-03-03 | 14000000000 | +------------+------+--------+----------+--------------+ -- 脱敏后 +------------+------------+------------+------------+--------------+ | id | name | height | birthday | phone_number | +------------+------------+------------+------------+--------------+ | 1 | 张* | 179.0 | 1990-01-01 | lvYJaH4ElL2ilpQx/8tfMUw7xP22yblIgmfWp0/msUQ= | | 2 | 李* | 163.0 | 1992-01-01 | 9fFWacNSwCRZLAjMHqunlfwkqhTbP2ubuDOeOSh4N1c= | | 3 | 王* | 185.0 | 1994-01-01 | k/0JoQCSarJg9ATJ5tyVnhQf1jIBxHXRbB+cvUm4OmE= | +------------+------------+------------+------------+--------------+
默认对所有用户和角色脱敏
下述实例为您展示当用户或角色同时命中多种敏感策略时,优先级较高的敏感策略将生效。
对默认用户采用MASKED_SHA256(5)的masking策略。
CREATE DATA MASKING POLICY default_hash_policy
TO DEFAULT
USING MASKED_SHA256(5);
对特殊用户A,B采用UNMASKED的策略。
CREATE DATA MASKING POLICY ab_unmask_policy
TO USER (A, B)
USING UNMASKED;
结果:用户A,B可以访问明文数据,其他用户只能访问SHA256散列脱敏的数据。
A,B用户命中MASKED_SHA256(5),UNMASKED策略,因此执行优先级较高的脱敏策略UNMASKED(详情请参见预定义脱敏策略优先级)。其他用户命中MASKED_SHA256(5)策略。
附录
预定义脱敏策略优先级
当用户访问敏感数据时有多条脱敏策略生效时,将执行较高优先级的脱敏策略对敏感数据进行脱敏。
例如用户A访问列col_string同时匹配到2条脱敏策略,分别是优先级3级MASKED_REPLACE_RANDOM(3)和优先级4级MASKED_SM3,系统将执行较高优先级的脱敏策略即MASKED_REPLACE_RANDOM(3),用户A将看到随机字符替换的脱敏结果。
优先级 | 预定义脱敏策略 |
0(高) | UNMASKED |
1 | MASKED_POINT_RESERVE(num) |
2 | MASKED_DATE_YEAR |
3 | MASKED_STRING_MASKED_BA(before, after) |
MASKED_STRING_UNMASKED_BA(before, after) | |
MASKED_REPLACE_RANDOM(position) | |
MASKED_REPLACE_RANDOM_BA(before, after) | |
MASKED_REPLACE_FIXED(position) | |
4 | MASKED_SHA256 |
MASKED_SHA512 | |
MASKED_MD5 | |
MASKED_SM3 | |
5 | MASKED_DV |
6(低) | MASKED_NULLIFY |
赋默认值脱敏策略(MASKED_DV)的赋值参考
数据类型 | 默认值 |
bigint | 0 |
double | 0.0 |
decimal | 0 |
string | "" |
datetime | DATETIME'1970-01-01 00:00:00'(UTC时间) |
boolean | false |
tinyint | 0 |
smallint | 0 |
int | 0 |
binary | '' |
float | 0.0 |
double | 0.0 |
decimal | 0 |
varchar(n) | "" |
char(n) | " " (填充n个空格) |
date | DATE'1970-01-01' |
timestamp | TIMESTAMP'1970-01-01 00:00:00'(UTC时间) |
timestamp_ntz | TIMESTAMP'1970-01-01 00:00:00'(UTC时间) |
array | {子类型的默认值} |
map | {key:value} (key, value分别对应子类型的默认值) |
json | "" |
struct | (子类型的默认值) |