雪花动态屏蔽屏蔽底层表:派生表未屏蔽,视图为空?
Posted
技术标签:
【中文标题】雪花动态屏蔽屏蔽底层表:派生表未屏蔽,视图为空?【英文标题】:Snowflake dynamic masking masks underlying table: the derivative tables are not masked and views become empty? 【发布时间】:2020-08-24 17:01:07 【问题描述】:我有一个原始表,其中包含 json 数据的变体列。 有一些普通视图(不是物化视图)和表是使用原始表中的 json 事件创建的。
当角色为bi_analyst
时,在原始表的变体列上应用了使用UDF的屏蔽策略后,我发现了两个问题:
-
从基础表派生的表未使用
bi_analyst
角色屏蔽;
使用基础表派生的视图变为空,角色为bi_analyst
;
有人知道为什么会这样吗?这个动态屏蔽功能不支持基础表上的视图吗?
我想做的是屏蔽底层数据,并且来自它的所有表和视图也被指定的角色屏蔽。 处理这些表很容易,因为我也可以对它们应用屏蔽策略。
但是,我不知道这些观点。我如何仍然可以访问具有该角色的视图,它应该能够看到数据但不能看到敏感列?
UDF 是:
-- javascript UDF to mask pii data --
use role ACCOUNTADMIN;
CREATE OR REPLACE FUNCTION full_address_masking(V variant)
RETURNS variant
LANGUAGE JAVASCRIPT
AS
$$
if ("detail" in V)
if ("latitude" in V.detail)
V.detail.latitude = "******";
if ("longitude" in V.detail)
V.detail.longitude = "******";
if ("customerAddress" in V.detail)
V.detail.customerAddress = "******";
return V;
$$;
屏蔽政策是:
-- Create a masking policy using JavaScript UDF --
create or replace masking policy json_address_mask as (val variant) returns variant ->
CASE
WHEN current_role() IN ('ACCOUNTADMIN') THEN val
WHEN current_role() IN ('BI_ANALYST') THEN full_address_masking(val)
ELSE full_address_masking(val)
END;
对原始数据设置屏蔽策略的sql命令是:
-- Set masking policy --
use role ACCOUNTADMIN;
alter table DB.PUBLIC.RAW_DATA
modify column EVERYTHING
set masking policy json_address_mask;
屏蔽策略应用于变量列EVERYTHING
,其数据结构如下:
"detail":
"customAddress": "******",
"id": 1,
"latitude": "******",
"longitude": "******"
,
"source": "AAA"
派生表是:
create or replace table DB.SCHEMA_A.TABLE_A
as
select * from DB.PUBLIC.RAW_DATA
where everything:source='AAA';
grant select on table DB.schema_A.table_A to role bi_analyst;
一个视图是:
create or replace view DB.SCHEMA_A.VIEW_A as (
select
everything:account::string as account,
everything:detail:latitude::float as detail_latitude,
everything:detail:longitude::float as detail_longitude,
from
DB.PUBLIC.RAW_DATA
where
everything:source::string = 'AAA'
grant select on view DB.SCHEMA_A.VIEW_A to role bi_analyst;
结果是RAW_DATA
被屏蔽,TABLE_A
根本没有被屏蔽,VIEW_A
用BI_ANALYST
角色查询数据时返回0行。
【问题讨论】:
如果您共享您的表结构、视图定义和数据屏蔽 UDF,将会有所帮助 您使用什么 UDF 来应用屏蔽策略?如果屏蔽策略正确应用于基表,则引用该表的所有视图也将被屏蔽。 @demircioglu 你好,我用代码和更多数据细节更新了问题,希望它有助于了解我的问题 @MikeWalton 嗨,我刚刚更新了问题的更多细节。是的,我期待所有的观点也被掩盖,但真的无法弄清楚为什么它不起作用 【参考方案1】:#1 - 当您从具有掩码数据的表创建表时,您将获得创建新表的角色可以在掩码表中访问的数据。因此,在您的示例中, TABLE_A 具有未屏蔽的数据,因为它是由有权访问它的角色创建的。屏蔽策略不会自动应用于新表。
#2 - 至于#2,我相信您唯一的问题是您示例中的 JSON 格式不正确,这就是您获得 NULL 值的原因。当我将此 json 修复为以下内容时,它可以使用您发布的相同功能和屏蔽策略正常工作:
"detail":
"latitude": 132034034.00,
"longitude": 12393438583732,
"id": 1,
"customAddress" : "XXX Road, XXX city, UK"
,
"source": "AAA"
屏蔽结果:
"detail":
"customAddress": "XXX Road, XXX city, UK",
"id": 1,
"latitude": "******",
"longitude": "******"
,
"source": "AAA"
【讨论】:
对不起,我帖子中的json格式不正确,我现在已经更正了!我可以确认它在雪花中的格式正确 您的解释没有掩盖表格是有道理的!但对于视图,情况并非如此,因为实际的 json 在实际数据集中的格式正确【参考方案2】:@Mike 在他的回答中很好地解释了表格未被掩盖的问题。解决方案可以只是使用受屏蔽策略限制的角色创建派生表。
视图的问题是关于掩码值“******”的类型,它是一个字符串类型,而字段latitude
和longitude
的实际类型是float。
创建视图时,我仍然将latitude
和longitude
字段转换为浮点类型:
create or replace view DB.SCHEMA_A.VIEW_A as (
select
everything:account::string as account,
everything:detail:latitude::float as detail_latitude,
everything:detail:longitude::float as detail_longitude,
from
DB.PUBLIC.RAW_DATA
where
everything:source::string = 'AAA'
将“******”转换为浮动时存在隐藏错误,但雪花仍会继续创建视图。但是当我使用BI_ANALYST
角色查询数据时,它返回0 行。
因此解决方法是将这些字段转换为变体类型:
create or replace view DB.SCHEMA_A.VIEW_A as (
select
everything:account::string as account,
everything:detail:latitude::variant as detail_latitude,
everything:detail:longitude::variant as detail_longitude,
from
DB.PUBLIC.RAW_DATA
where
everything:source::string = 'AAA'
这并不完美,因为它完全改变了视图的定义,没有一个角色可以获取数据的实际浮点/数字类型,甚至包括accountadmin
【讨论】:
这很好地说明了问题的数据类型。如果 OP 想要在视图上保持浮动,他们也可以插入0.0
作为掩码值...或 NULL
这也可以工作,无需将数据类型更改为一个变种。以上是关于雪花动态屏蔽屏蔽底层表:派生表未屏蔽,视图为空?的主要内容,如果未能解决你的问题,请参考以下文章