数据脱敏

Hologres为您提供数据脱敏功能,支持按照列级别设置脱敏。启用该功能后,如果您查询的数据涉及敏感信息,则在展示结果中,该部分数据会被脱敏展示,提高了对敏感及私密数据的保护。本文为您介绍Hologres如何开启、查询及删除数据脱敏功能。

背景信息

随着大数据时代的来临,大数据、云计算和人工智能等新技术应用不断深化,为数据的深度挖掘及分析提供了强有力的支撑,大数据中蕴含的巨大价值被逐步挖掘出来。与此同时也带来了敏感及私密信息保护方面的棘手难题。

Hologres提供的数据脱敏功能,实现了数据在高效共享、挖掘及分析的同时,使得敏感及隐私信息不被泄露,提高了对敏感及私密数据的保护。

版本对比

HologresV3.1版本开始,优化了数据脱敏行为。如下是V3.1版本以及低版本的功能对比,以便您更好的使用数据脱敏。

功能

V3.1及以上版本

V3.0及以下版本

TEXT类型字段脱敏

支持对INT、FLOAT、数组等类型设置默认脱敏策略,但是仅在设置Default值脱敏策略时生效。详情请参见Default

不支持,但是可以通过CAST TEXT方式绕过脱敏(不建议)。

视图(View)

结果脱敏。

结果不脱敏(不建议)。

JOIN字段或者Where条件有脱敏字段

结果是空。

结果不脱敏(不建议)。

Flink消费脱敏字段的Binlog

  • 如果消费的表对该用户脱敏,所有模式都禁止消费Binlog。

  • 如果消费的表对该用户不脱敏,所有模式都可以消费Binlog。

  • V2.2.38以前以及V3.0.1~V3.0.19版本:

    • Fixed FE模式不支持消费脱敏字段。

    • FE模式支持消费脱敏字段。

  • V3.0.19~V3.0.27版本

    Fixed FEFE模式都禁止Binlog消费,只有为该用户取消掉所有表的数据脱敏,才能消费。

    -- 为此用户关闭脱敏
    ALTER ROLE "<user>" SET hg_anon_enable = OFF;
    -- 为此用户在单个database下关闭脱敏
    ALTER ROLE "<user>" IN DATABASE <database> SET hg_anon_enable = OFF;
  • V3.0.28开始,即使启用了数据脱敏相关的GUC配置,如果用户未对表结果执行脱敏操作,仍然可以在Fixed FEFE上消费Binlog。

MC直读脱敏字段

禁止通过MaxCompute直读Hologres脱敏字段。

支持读取(不建议)。

准备工作

在使用数据脱敏之前,需要Superuser在数据库级别开启如下参数。

--superuser账号执行
CREATE EXTENSION IF NOT EXISTS hg_anon;  
ALTER DATABASE <current_db> SET hg_anon_enable = on;

执行上述代码后,系统将根据Hologres的实例版本使用对应的数据脱敏行为。您还可以根据业务需要选择脱敏行为:

  • V3.1及以上版本的数据脱敏行为中有明显的缺陷导致行为不符合预期,可以通过如下参数回退到V3.0及以下版本数据脱敏行为。

    CALL hologres.set_hg_anon_version(1);
  • V3.0及以下版本的实例不支持set_hg_anon_version存储过程。如果已经使用过脱敏功能的实例升级至V3.1版本,则可以执行以下命令以启用V3.1的脱敏功能。否则,系统将继续使用旧版本的脱敏功能。

    CALL hologres.set_hg_anon_version(2);
    说明
    • 若该语句执行成功,则代表开启V3.1及以上版本的数据脱敏行为。

    • 若该语句执行失败,错误日志显示:"Error: not safe to upgrade to hg_anon version 2",则代表开启失败。原因在于当前DB中为非TEXT/VARCHAR/CHAR的列类型设置了脱敏,V3.1及以上版本的数据脱敏结果不符合预期,需要订正脱敏行为。

使用限制

  • 暂不支持从设置了脱敏规则的表和列向未设置脱敏规则的表和列导入数据,相关报错信息如下。

    错误原因:ERROR: The insert table has not set SECURITY LABEL
  • 暂不支持针对设置了脱敏规则的表进行UNIONDISTINCT查询,相关报错信息如下。

    错误原因:ERROR: UNION is not support on security item
  • 数据脱敏会一定程度的影响查询性能,影响程度和脱敏方式、数据量都有关,性能有10%~20%的下降,极端场景可能存在数倍性能下降。

  • 不支持对外部表设置脱敏规则。

数据脱敏

设置脱敏规则

Hologres支持对目标列或目标用户设置数据脱敏。在进行数据脱敏之前,一定要开启数据脱敏的GUC参数,详情请参见准备工作

  • 语法

    • 对列设置脱敏策略

      对多列数据进行脱敏时,需要多次执行该语句。

      SECURITY LABEL FOR hg_anon ON COLUMN <tablename>.<col_name> IS <label_name>/'default_value';
    • 对用户设置脱敏策略

       SECURITY LABEL FOR hg_anon ON ROLE <user_name> IS '[<label_name>|all]:[masked|unmasked]';
  • 参数说明

    参数

    描述

    hg_anon

    hg_anonHologres内部封装的扩展函数,您需要调用该扩展函数才能开启数据脱敏功能。

    tablename

    需要脱敏的列所在的表名称。

    col_name

    需要脱敏的列名称。

    label_name

    系统预设的脱敏函数,您可以使用SHOW hg_anon_labels;查看当前数据库设置的label_name。

    user_name

    账号ID。请通过用户信息页面获取。

    masked|unmasked

    • masked:使用数据脱敏。

    • unmasked:不使用数据脱敏。

    系统预设的label_name详情如下表所示。

    数据类型

    label_name

    脱敏策略

    脱敏类型

    说明

    脱敏示例

    TEXT

    name

    name

    mask

    姓名脱敏。

    • 脱敏前:李华;脱敏后:*华。

    • 脱敏前:王小强;脱敏后:**强。

    email

    email

    mask

    邮箱地址脱敏。

    脱敏前:lihuang@alibaba.com;脱敏后:lih***@alibaba.com。

    ip

    ip

    mask

    IP地址脱敏。

    脱敏前:1.2.3.4;脱敏后:1.*.*.*。

    id

    id

    mask

    身份证号码脱敏。

    脱敏前:110345188812011234;脱敏后:1****************4。

    phone

    phone

    mask

    电话号码脱敏。

    脱敏前:13900001234;脱敏后:*********34。

    bank_id

    bank_id

    mask

    银行卡、信用卡账号脱敏。

    脱敏前:2349867902834701928;脱敏后:***************1928。

    hash

    md5

    hash

    使用MD5算法进行脱敏。

    脱敏前:浙江省杭州市文一西路;脱敏后:dbf894b409d4a2ef17dfd9c7fdcafcd8。

    first_mask

    first_mask

    mask

    定义了一个first_mask的规则,只显示第一个字符。

    脱敏前:123456789;脱敏后:1********。

    INT、FLOAT等类型

    Default

    default_value

    default_value

    按照默认值脱敏。

    说明
    • 如果在设置数据脱敏时,label_name不存在,将会退化成默认值脱敏。

    • Hologres V3.1及以上版本支持设置。

    数据类型与脱敏默认值映射如下:

    • TEXT/VARCHAR/CHAR:***

    • BOOLEAN:false

    • INT8/INT4/INT2:0

    • TIMESTAMPTZ/TIMESTAMP:2000-01-01 00:00:00

    • FLOAT8/FLOAT4/DECIMAL/NUMERIC:0.0

    • MONEY:0

    • DATE:2000-01-01

    • TIME/TIMETZ:当前时间

    • UUID:00000000-0000-0000-0000-000000000000

查看设置的脱敏规则

  • 查看为列设置的脱敏

    --查看为列设置的脱敏
    SELECT 
    	c.relname
      ,a.attname
      ,provider
      ,label
    FROM pg_seclabel s 
    INNER JOIN pg_catalog.pg_class c ON s.objoid = c.relfilenode 
    INNER JOIN pg_catalog.pg_attribute a ON s.objoid = a.attrelid 
    WHERE a.attnum = objsubid;
  • 查看为用户设置的脱敏

    --查看为用户设置的脱敏规则
    SELECT
        usename,
        label
    FROM
        pg_shseclabel s
        INNER JOIN pg_catalog.pg_user u ON s.objoid = u.usesysid;

修改自定义脱敏规则

设置的脱敏规则如果无法满足需求,您可以通过修改GUChg_anon_lables参数自定义脱敏规则。

  • 语法

    --label_name是您自定义的名称,methodHologres内置的一些方法。
    ALTER DATABASE <db_name> SET hg_anon_labels = '[   
    {"label": <label_name1>, "method":<method1>},  
    {"label": <label_name2>, "method":<method2>}, 
    ...  ]'; 

    执行ALTER DATABASE命令后,当前连接会不生效,需要重建立一个连接。您可使用如下命令查看设置是否生效。

    SHOW hg_anon_enable;
  • 示例

    ALTER DATABASE test_db SET hg_anon_labels = '[
    {"label":"ip", "method":{"desensType":"mask", "type":"ip"}},
    {"label":"email", "method":{"desensType":"mask", "type":"email"}},
    {"label":"name", "method":{"desensType":"mask", "type":"name"}},
    {"label":"first_mask", "method":{"desensType":"mask", "type":"user_define", "before":1, "after":0}},
    {"label":"hash", "method":{"desensType":"hash", "type":"md5", "salt":""}}]';

    参数说明:

    脱敏项

    脱敏内容描述

    脱敏结果示例

    {"desensType":"mask", "type":"ip"}

    IP地址脱敏。

    192.*.*.*

    {"desensType":"mask", "type":"email"}

    邮箱地址脱敏。

    abc***@example.net

    {"desensType":"mask", "type":"name"}

    名称脱敏。

    *五

    {"desensType":"hash", "type":"md5", "salt":""}

    Hash脱敏。

    e086aa137fa19f67d27b39d0eca186103228f322c9c98a125554a24f875f0f7e

    {"label":"first_mask", "method":{"desensType":"mask", "type":"user_define", "before":1, "after":0}}{"label":"last_mask", "method":{"desensType":"mask", "type":"user_define", "before":0, "after":1}}

    自定义内容脱敏。

使用示例

示例数据

准备一张数据源,您也可以使用业务数据。

--创建数据库
CREATE DATABASE hg_anon_demo;
--创建样例数据表
DROP TABLE IF EXISTS personal_basic_information;
CREATE TABLE personal_basic_information  
(
    name TEXT
    ,email TEXT
    ,ip TEXT
    ,id TEXT 
    ,phone TEXT
    ,bank_id TEXT);
--插入样例数据
INSERT INTO personal_basic_information(name,email,ip,id,phone,bank_id) VALUES 
('张三','jiaxi.jx@alibaba-inc.com','127.0.0.1','142732199104050022','18157161223','4514610803067088'),
('李四','wb-hy583084@antgroup.com','127.0.0.1','510622198412248000','15757121834','6252470010027800'),
('李逍遥','wb-hy583084@antgroup.com','172.21.4.234','511025198812271696','18215451832','6252470010027800');

为某列设置脱敏规则

--创建hg_anon扩展函数。
CREATE EXTENSION IF NOT EXISTS hg_anon;

--为数据库hg_anon_demo开启数据脱敏功能。
ALTER DATABASE hg_anon_demo SET hg_anon_enable = on;

--设置每一列的脱敏规则
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.name IS 'name';
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.id IS 'id';
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.phone IS 'phone';
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.email IS 'email';
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.bank_id IS 'bank_id';
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.ip IS 'ip';

新建连接后,使用如下命令,查看脱敏结果。

SELECT * FROM personal_basic_information;

返回结果如下。

name |         email          |      ip      |         id         |    phone    |     bank_id      
------+------------------------+--------------+--------------------+-------------+------------------
 *四  | wb-***@antgroup.com    | 127.*.*.*    | 5****************0 | *********34 | ************7800
 **遥 | wb-***@antgroup.com    | 172.**.*.*** | 5****************6 | *********32 | ************7800
 *三  | jia***@alibaba-inc.com | 127.*.*.*    | 1****************2 | *********23 | ************7088
(3 rows)

取消某列的脱敏

SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.name IS null;
SECURITY LABEL FOR hg_anon ON COLUMN personal_basic_information.id IS null;

使用如下命令,查看取消某列脱敏的结果。

SELECT name,id FROM personal_basic_information;

返回结果如下。

SELECT name,id FROM personal_basic_information;
  name  |         id         
--------+--------------------
 李四   | 510622198412248000
 李逍遥 | 511025198812271696
 张三   | 142732199104050022
(3 rows)

取消某个用户的脱敏规则

--取消basic账号取消所有的脱敏
SECURITY LABEL FOR hg_anon ON ROLE "BASIC$test" IS 'all:unmasked';

使用如下命令,查看取消某个用户脱敏的结果。

SELECT * FROM personal_basic_information;

返回结果如下。

  name  |          email           |      ip      |         id         |    phone    |     bank_id      
--------+--------------------------+--------------+--------------------+-------------+------------------
 李四   | wb-hy583084@antgroup.com | 127.0.0.1    | 510622198412248000 | 15757121834 | 6252470010027800
 李逍遥 | wb-hy583084@antgroup.com | 172.21.4.234 | 511025198812271696 | 18215451832 | 6252470010027800
 张三   | jiaxi.jx@alibaba-inc.com | 127.0.0.1    | 142732199104050022 | 18157161223 | 4514610803067088
(3 rows)

JOIN列设置脱敏

--示例join列设置脱敏
CREATE TABLE tbl1 (
    id text
);
INSERT INTO tbl1
    VALUES ('142732199102290022');

--其中personal_basic_information表的id列已经设置了脱敏
SELECT * FROM personal_basic_information a JOIN tbl1 b ON a.id = b.id;

返回结果如下。

name | email | ip | id | phone | bank_id | id 
------+-------+----+----+-------+---------+----
(0 rows)

使用数据保护伞进行数据脱敏

您不仅可以手工设置脱敏规则,也可以使用数据保护伞进行数据脱敏。

  • 使用限制。

    • Hologres V1.1及以上版本支持使用数据保护伞进行数据脱敏。

      说明

      如果您的实例是V1.1以下版本,请您使用常见升级准备失败报错或加入Hologres钉钉交流群反馈,详情请参见如何获取更多的在线支持?

    • 为了能够检测出敏感数据,保护伞对于主账号设置不脱敏的规则。

    • 目前每天9:00:00,保护伞会抽样数据,识别敏感数据,并对设置的敏感数据列设置脱敏规则。

    • 目前Hologres支持使用数据保护伞进行数据脱敏的地域有:华北2(北京)、华北3(张家口)、华东2(上海)、华东1(杭州)、华南1(深圳)、中国(香港)、新加坡、德国(法兰克福)、马来西亚(吉隆坡)、印度尼西亚(雅加达)、美国(硅谷)。

  • 使用方法。

    • 开启脱敏功能。

      数据脱敏功能默认不开启,需要拥有Superuser权限的用户在对应的数据库中执行如下命令开启该功能。

      --安装数据脱敏EXTENSION
      CREATE EXTENSION IF NOT EXISTS hg_anon;
      --对指定的数据库开启数据脱敏功能,默认为关闭状态 
      ALTER DATABASE <db_name> SET hg_anon_enable = on;  

      db_name为需要开启数据脱敏功能的数据库。

      重要
      • hg_anon_enable是一个GUC,运行ALTER DATABASE命令后当前连接不生效。

      • 您可以使用如下SQL查看设置是否生效。

        SHOW hg_anon_enable;
    • 设置脱敏数据库。

      1. 登录数据保护伞控制台,详情请参见进入数据保护伞

      2. 在左侧导航栏,单击规则配置 > 数据识别规则,进入数据识别规则页面。

      3. 敏感数据识别页面创建一条数据识别规则,详情请参见数据识别规则

      4. 在左侧导航栏,单击数据脱敏管理,进入数据脱敏管理页面。

      5. 脱敏场景下拉列表中,选择Hologres展示脱敏(hologres_display_desense_code),并单击右侧选择脱敏database

      6. 授权账号脱敏对话框,从未脱敏database列表选择需要脱敏的数据库显示在脱敏database列表中,单击我同意授权数据保护伞对该database脱敏,单击确定授权账号脱敏

      7. 数据脱敏管理页面,单击右上方的新建脱敏规则,详情请参见数据脱敏管理,之后系统会对您设置的数据库进行脱敏。

常见问题

按照使用示例发现数据未脱敏

  • 问题现象:按照使用示例执行后发现查询出的数据未进行脱敏。

  • 可能原因:

    • 对部分用户设置了不脱敏的规则。

    • 未设置脱敏标签。

  • 解决方法:

    • 执行如下SQL命令检查是否对于部分用户设置了不脱敏的规则。

      SELECT
        usename,
        label
      FROM pg_shseclabel s
      INNER JOIN pg_catalog.pg_user u on s.objoid = u.usesysid;

      默认情况下该SQL查询结果为空,表示对所有用户均需要进行数据脱敏;若不为空,请对用户设置为脱敏。

    • 使用如下SQL,检查设置的脱敏标签。

      SHOW hg_anon_labels;

      如果结果中并未包含ip等标签,请执行如下SQL命令设置脱敏标签。

      ALTER DATABASE compress_test SET hg_anon_labels = '[
      {"label":"ip", "method":{"desensType":"mask", "type":"ip"}},
      {"label":"email", "method":{"desensType":"mask", "type":"email"}},
      {"label":"name", "method":{"desensType":"mask", "type":"name"}},
      {"label":"id", "method":{"desensType":"mask", "type":"id"}},
      {"label":"phone", "method":{"desensType":"mask", "type":"phone"}},
      {"label":"bank_id", "method":{"desensType":"mask", "type":"bank_id"}},
      {"label":"hash", "method":{"desensType":"hash", "type":"md5", "salt":""}},
      {"label":"first_mask", "method":{"desensType":"mask", "type":"user_define", "before":1, "after":0}}
      ]';

      以上标签对应的规则请参见系统预设的label_name详情