【问题标题】:Snowflake Data Masking雪花数据屏蔽
【发布时间】:2022-06-30 20:15:57
【问题描述】:

我们希望在 Snowflake 环境中屏蔽与团队成员相关的某些 PII,目前我们的屏蔽设置为屏蔽我们在屏蔽策略中定义的列中的每一行。

我们想要实现的只是在单独的表中仅屏蔽包含会员编号的行。这有可能实现吗?或者我将如何去做?

member name
A acds
B asdas
C asdeqw
member
B

例如,在上面的表中,我们只想屏蔽成员 B。此时,第一个表中的所有 3 行都将被屏蔽。

我们有一个可能的解决方法,可以在额外视图的逻辑中执行此操作,但这实际上会更改数据,而我们希望我们可以使用动态数据屏蔽,然后为其设置异常处理。

【问题讨论】:

  • 您可以将存储过程与 Javascript UDF 结合使用。 Javascript UDF 的一个示例是 here

标签: snowflake-cloud-data-platform


【解决方案1】:

准备数据:

create or replace table member (member_id varchar, name varchar);
insert into member values ('A', 'member_a'),('B', 'member_b'),('C', 'member_c');

create or replace table member_to_be_masked(member_id varchar);
insert into member_to_be_masked values ('B');

如果要屏蔽成员列:

create or replace masking policy member_mask as (val string) returns string ->
  case
  when exists
    (
        select 
            member_id 
        from 
            member_to_be_masked 
        where member_id = val
    ) 
    then '********'
  else val
end;

alter table if exists member 
modify column member_id 
set masking policy member_mask;

select * from member;

+-----------+----------+
| MEMBER_ID | NAME     |
|-----------+----------|
| A         | member_a |
| ********  | member_b |
| C         | member_c |
+-----------+----------+

但是,如果您想屏蔽名称列,我看不到一个简单的方法。我已尝试将策略链接回表本身以找出当前列名值的 member_id 是否为当前列名值,但它失败并显示以下错误消息:

策略正文包含引用附加到另一个策略的表的 UDF 或 Select 语句。

在策略中,我们似乎无法引用回源表。并且由于策略只会获取定义的列值的值,它不知道其他列值,所以我们无法决定是否应用掩码。

如果您也将“名称”连同member_id一起存储到映射表中,如果可以工作,如下所示:

create or replace table member (member_id varchar, name varchar);
insert into member values ('A', 'member_a'),('B', 'member_b'),('C', 'member_c');

create or replace table member_to_be_masked(member_id varchar, name varchar);
insert into member_to_be_masked values ('B', 'member_b');

create or replace masking policy member_mask as (val string) returns string ->
  case
  when exists
    (
        select member_id 
        from member_to_be_masked 
        where name = val
    )
    then '********'
  else val
end;

alter table if exists member 
modify column name 
set masking policy member_mask;

select * from member;
+-----------+----------+
| MEMBER_ID | NAME     |
|-----------+----------|
| A         | member_a |
| B         | ******** |
| C         | member_c |
+-----------+----------+

这种方法的缺点是,如果不同的成员同名,那么所有同名的成员都会被屏蔽,不管这个成员的id是否在映射表中。

【讨论】:

  • 谢谢你,因为它确实让我更接近了一点。第二个版本并没有真正起作用,因为名称并不像您提到的那样是唯一的。是否可以将多个值而不是一个值传递到屏蔽策略中,以便将成员 ID 和名称带入其中。我知道根据文档似乎不支持子查询,所以没有尝试过类似的事情。或者 Sergiu 的方法是否可以使用存储过程或 UDF(示例似乎指向将其用于半结构化数据)
  • 如果您可以更改数据结构,我已经更新了一个新答案。
【解决方案2】:

保留我之前的答案,以防它仍然有用。

我能想到的另一种解决方法是使用变体数据,然后在其之上创建一个视图。

  1. 准备 JSON 格式的数据:
create or replace table member_json (member_id varchar, data variant);
insert into member_json
select 
'A', parse_json('{"member_id": "A", "name" : "member_a"}')
union
select 
'B', parse_json('{"member_id": "B", "name" : "member_b"}')
union
select 
'C', parse_json('{"member_id": "C", "name" : "member_c"}')
;

create or replace table member_to_be_masked(member_id varchar);
insert into member_to_be_masked values ('B');

数据如下:

select * from member_json;

+-----------+----------------------+
| MEMBER_ID | DATA                 |
|-----------+----------------------|
| A         | {                    |
|           |   "member_id": "A",  |
|           |   "name": "member_a" |
|           | }                    |
| B         | {                    |
|           |   "member_id": "B",  |
|           |   "name": "member_b" |
|           | }                    |
| C         | {                    |
|           |   "member_id": "C",  |
|           |   "name": "member_c" |
|           | }                    |
+-----------+----------------------+

select * from member_to_be_masked;

+-----------+
| MEMBER_ID |
|-----------|
| B         |
+-----------+
  1. 创建一个 JS UDF:
create or replace function json_mask(mask boolean, v variant)
returns variant
language javascript
as
$$
    if (MASK) {
        V["member_id"] = '******'
        V["name"] = '******';
    }
    return V;
$$;
  1. 使用 UDF 创建屏蔽策略:
create or replace masking policy member_mask 
as (val variant) 
returns variant ->
  case
  when exists
    (
        select 
            member_id 
        from 
            member_to_be_masked 
        where member_id = val['member_id']
    ) 
    then json_mask(true, val)
  else val
end;
  1. 将策略应用到 member_json 表:
alter table if exists member_json 
modify column data 
set masking policy member_mask;
  1. 查询表会看到成员 B 被屏蔽:
select * from member_json;

+-----------+--------------------------+
| MEMBER_ID | DATA                     |
|-----------+--------------------------|
| A         | {                        |
|           |   "member_id": "A",      |
|           |   "name": "member_a"     |
|           | }                        |
| B         | {                        |
|           |   "member_id": "******", |
|           |   "name": "******"       |
|           | }                        |
| C         | {                        |
|           |   "member_id": "C",      |
|           |   "name": "member_c"     |
|           | }                        |
+-----------+--------------------------+
  1. 在其上创建一个视图:
create or replace view member_view
as
select 
    data:"member_id" as member_id,
    data:"name" as name
from member_json;
  1. 查询视图也会看到被屏蔽的数据:
select * from member_view;
+-----------+------------+
| MEMBER_ID | NAME       |
|-----------+------------|
| "A"       | "member_a" |
| "******"  | "******"   |
| "C"       | "member_c" |
+-----------+------------+

不确定这是否有助于您的案例使用。

【讨论】:

    【解决方案3】:

    据我了解,您希望根据另一列屏蔽表中的一列并进行查找。 在这种情况下,我们可以使用条件屏蔽 - https://docs.snowflake.com/en/sql-reference/sql/create-masking-policy.html#conditional-masking-policy

    创建或替换屏蔽策略 name_mask 为 (val string, member_id string) 返回字符串 -> 案子 何时存在 ( 选择 1 从 member_to_be_masked m 其中 m.member_id ) 然后 '********' 其他值 结束;

    在查询配置文件中,它将作为安全功能提供。请评估性能。根据必须应用此功能的总记录,性能差异可能很大

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2023-01-03
      • 2022-06-23
      • 1970-01-01
      • 1970-01-01
      • 2022-07-02
      • 2023-03-22
      相关资源
      最近更新 更多