• 沒有找到結果。

搜索路径

SHOW SEARCH_PATH;

7.1.9 数据脱敏

id | operation

1 | -> Streaming (type: GATHER) 2 | -> Seq Scan on all_data

Predicate Information (identified by plan id) 2 --Seq Scan on all_data

Filter: ((role)::name = 'peter'::name)

Notice: This query is influenced by row level security feature (10 rows)

7.1.9 数据脱敏

GaussDB(DWS)提供列级别的数据脱敏(Dynamic Data Masking)功能。针对某些敏感 信息(如身份证号、手机号、银行卡号等),通过应用脱敏函数进行原始数据的变形 改写,实现敏感隐私数据的可靠保护,从而增强产品在数据安全和隐私保护方面的能 力。

● 用户可以在指定表对象创建脱敏策略,并限定策略生效范围。详细内容请参见

《SQL语法参考》中“CREATE REDACTION POLICY”章节。

● 提供脱敏策略的修改语法,包括修改脱敏策略生效表达式、重命名脱敏策略,以 及新增、修改、删除脱敏列信息。详细内容请参见《SQL语法参考》中“ALTER REDACTION POLICY”章节。

● 删除脱敏策略,可以一键式删除脱敏策略在表的所有列字段上的脱敏函数信息。

详细内容请参见《SQL语法参考》中“DROP REDACTION POLICY”章节。

● GaussDB(DWS)提供MASK_NONE、MASK_FULL、MASK_PARTIAL三种内置脱敏 函数,也支持使用PL/PGSQL语言创建的用户自定义脱敏函数。详细内容请参见

《SQL语法参考》中“数据脱敏函数”章节。

● 脱敏策略信息存储在系统表PG_REDACTION_POLICY,脱敏列信息存储在系统表

PG_REDACTION_COLUMN。

● 用户可以通过系统视图REDACTION_POLICIES和REDACTION_COLUMNS,更加 方便地查看脱敏策略及脱敏列信息。

说明

● 通常,用户可以执行SELECT语句查看敏感信息的脱敏效果。如果语句有如下特征,则可能存 在故意套取敏感数据的可能性,造成语句执行报错。

GROUP BY子句引用与目标列一样含有脱敏列的Target Entry作为分组。

DISTINCT作用在输出的脱敏列上。

带有CTE的语句。

涉及集合操作。

子查询的目标列不是基表的脱敏列,而是基表脱敏列的表达式或者函数调用。

● 支持脱敏数据的COPY TO或者GDS导出功能。由于脱敏数据的不可逆性,针对脱敏数据的二 次运算无任何实际意义。

● 禁止UPDATE、MERGE INTO、DELETE语句的目标列涉及脱敏列。

● UPSERT语句允许通过EXCLUDED更新插入数据。如果引用脱敏列更新基表数据,存在误改 数据的可能,执行会报错。

示例

以员工表emp,管理员用户alice以及普通用户matu、july为例,简要介绍数据脱敏过 程。其中,用户alice是表emp的属主,表emp包含员工的姓名、手机号、邮箱、银行 卡号、薪资等隐私数据。

1. 创建用户alice、matu和july。

CREATE ROLE alice PASSWORD 'password';

CREATE ROLE matu PASSWORD 'password';

CREATE ROLE july PASSWORD 'password';

2. 用户alice创建表emp并插入三条员工信息。

CREATE TABLE emp(id int, name varchar(20), phone_no varchar(11), card_no number, card_string varchar(19), email text, salary numeric(100, 4), birthday date);

INSERT INTO emp VALUES(1, 'anny', '13420002340', 1234123412341234, '1234-1234-1234-1234', '[email protected]', 10000.00, '1999-10-02');

INSERT INTO emp VALUES(2, 'bob', '18299023211', 3456345634563456, '3456-3456-3456-3456', '[email protected]', 9999.99, '1989-12-12');

INSERT INTO emp VALUES(3, 'cici', '15512231233', NULL, NULL, '[email protected]', NULL, '1992-11-06');

3. 用户alice将表emp的读取权限授予用户matu、july。

GRANT SELECT ON emp TO matu, july;

4. 仅用户alice可查看所有员工信息,matu和july对员工所有银行卡号和薪资数据不 可见,于是,对表emp创建脱敏策略,分布为字段card_no、card_string和salary 绑定脱敏函数。

CREATE REDACTION POLICY mask_emp ON emp WHEN (current_user IN ('matu', 'july')) ADD COLUMN card_no WITH mask_full(card_no),

ADD COLUMN card_string WITH mask_partial(card_string, 'VVVVFVVVVFVVVVFVVVV','VVVV-VVVV-VVVV-VVVV','#',1,12),

ADD COLUMN salary WITH mask_partial(salary, '9', 1, length(salary) - 2);

5. 切换到用户matu和july,查看员工表emp。

SET ROLE matu PASSWORD 'password';

SELECT * FROM emp;

id | name | phone_no | card_no | card_string | email | salary | birthday

SET ROLE july PASSWORD 'password';

SELECT * FROM emp;

id | name | phone_no | card_no | card_string | email | salary | birthday 围。ALTER REDACTION POLICY mask_emp ON emp WHEN(current_user = 'july');

7. 切换到用户matu和july,重新查看员工表emp。

SET ROLE matu PASSWORD 'password';

SELECT * FROM emp;

id | name | phone_no | card_no | card_string | email | salary | birthday

----+---+---+---+---

1 | anny | 13420002340 | 1234123412341234 | 1234-1234-1234-1234 | [email protected] | 10000.0000 | 1999-10-02 00:00:00

2 | bob | 18299023211 | 3456345634563456 | 3456-3456-3456-3456 | [email protected] |

9999.9900 | 1989-12-12 00:00:00

3 | cici | 15512231233 | | | [email protected] | | 1992-11-06 00:00:00

(3 rows)

SET ROLE july PASSWORD 'password';

SELECT * FROM emp;

id | name | phone_no | card_no | card_string | email | salary | birthday

ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN phone_no WITH mask_partial(phone_no, '*', 4);

ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN email WITH mask_partial(email, '*', 1, position('@' in email));

ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN birthday WITH mask_full(birthday);

9. 切换到用户july,查看表emp数据。

SET ROLE july PASSWORD 'password';

SELECT * FROM emp;

id | name | phone_no | card_no | card_string | email | salary | birthday

SELECT * FROM redaction_policies;

object_schema | object_owner | object_name | policy_name | expression | enable |

SELECT object_name, column_name, function_info FROM redaction_columns;

object_name | column_name | function_info

---+--- emp | card_no | mask_full(card_no)

emp | card_string | mask_partial(card_string, 'VVVVFVVVVFVVVVFVVVV'::text, 'VVVV-VVVV-VVVV-VVVV'::text, '#'::text, 1, 12)

emp | email | mask_partial(email, '*'::text, 1, "position"(email, '@'::text))

ALTER TABLE emp ADD COLUMN salary_info TEXT;

UPDATE emp SET salary_info = salary::text;

CREATE FUNCTION mask_regexp_salary(salary_info text) RETURNS text AS

$$ SELECT regexp_replace($1, '[0-9]+','*','g');

$$LANGUAGE SQL

STRICT SHIPPABLE;

ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN salary_info WITH mask_regexp_salary(salary_info);

SET ROLE july PASSWORD 'password';

SELECT id, name, salary_info FROM emp;

id | name | salary_info 1 | anny | *.*

2 | bob | *.*

3 | cici | (3 rows)

12. 无需为表emp设置敏感策略,删除脱敏策略mask_emp。

DROP REDACTION POLICY mask_emp ON emp;