雪花掩蔽策略:输入可以是恒定的字符串变量吗?

发布于 2025-01-21 11:23:05 字数 825 浏览 3 评论 0原文

我正在尝试创建带有标签的掩蔽策略:

CREATE OR REPLACE MASKING POLICY TAGS_MASKING
AS (val VARCHAR, col_name STRING) RETURNS VARCHAR ->
CASE        
   WHEN CURRENT_ROLE() IN ('ADMIN_ROLE') THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SELECT SYSTEM$GET_TAG('TAG_NAME', col_name , 'COLUMN') = 'PUBLIC') THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SELECT SYSTEM$GET_TAG('TAG_NAME', col_name , 'COLUMN') IN ('PROTECTED')) THEN '****MASKED****'
 END; 

在这里,col_name是字符串(例如'mytable.col1'),以便我可以将此掩码策略分配给我想要的任何列。但是,当我使用以下查询将其分配给一张表的一列时,它失败了:

ALTER TABLE IF EXISTS db.masking.mytable MODIFY COLUMN col1
SET MASKING POLICY TAGS_MASKING using (col1, 'mytable.col1');

错误消息是:

语法错误:意外的“ mytable.col1”

我应该如何解决这个问题?谢谢!

I am trying to create a masking policy with tagging:

CREATE OR REPLACE MASKING POLICY TAGS_MASKING
AS (val VARCHAR, col_name STRING) RETURNS VARCHAR ->
CASE        
   WHEN CURRENT_ROLE() IN ('ADMIN_ROLE') THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SELECT SYSTEM$GET_TAG('TAG_NAME', col_name , 'COLUMN') = 'PUBLIC') THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SELECT SYSTEM$GET_TAG('TAG_NAME', col_name , 'COLUMN') IN ('PROTECTED')) THEN '****MASKED****'
 END; 

Here, col_name is a string (e.g. 'mytable.col1'), so that I can assign this masking policy to any columns I want to. But when I used the following query to assign it to one column of one table, it failed:

ALTER TABLE IF EXISTS db.masking.mytable MODIFY COLUMN col1
SET MASKING POLICY TAGS_MASKING using (col1, 'mytable.col1');

The error message is:

Syntax error: unexpected "mytable.col1"

How should I figure this out? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

娇纵 2025-01-28 11:23:05

我尚未找到一种参数化列名称(将其作为可选的第二个参数传递)的方法,因此我使用了不同的方法。

它会使用雪花脚本自动创建每个colum的掩蔽策略。

设置:

CREATE OR REPLACE TAG TAG_NAME;

CREATE OR REPLACE TABLE mytable(col1 STRING); 
ALTER TABLE mytable SET TAG TAG_NAME='PUBLIC';

INSERT INTO mytable(col1) VALUES ('Test');

SELECT * FROM mytable;
-- Test

过程:

 CREATE OR REPLACE PROCEDURE test(schema_name STRING, tab_name STRING, col_name STRING)
 RETURNS STRING
 LANGUAGE SQL
 AS
 $
 DECLARE 
   sql_masking_policy   STRING;
   sql_alter_table      STRING;
   masking_policy_name  STRING := CONCAT_WS('_', 'TAGS_MASKING_', SCHEMA_NAME, TAB_NAME, COL_NAME);
 BEGIN
 sql_masking_policy := '
 CREATE OR REPLACE MASKING POLICY <masking_policy_name>
 AS (val VARCHAR) RETURNS VARCHAR ->
 CASE        
    WHEN CURRENT_ROLE() IN (''ADMIN_ROLE'') THEN val
    WHEN CURRENT_ROLE() IN (''ANALYST_ROLE'') AND (SYSTEM$GET_TAG(''TAG_NAME'', ''<col_name>'', ''COLUMN'') = ''PUBLIC'') THEN val
    WHEN CURRENT_ROLE() IN (''ANALYST_ROLE'') AND (SYSTEM$GET_TAG(''TAG_NAME'', ''<col_name>'', ''COLUMN'') IN (''PROTECTED'')) THEN ''****MASKED****''
 END;';
                             
sql_alter_table := 'ALTER TABLE IF EXISTS <tab_name> MODIFY COLUMN <col_name>
SET MASKING POLICY <masking_policy_name>;';

sql_masking_policy := REPLACE(sql_masking_policy, '<masking_policy_name>', :masking_policy_name);
sql_masking_policy := REPLACE(sql_masking_policy, '<col_name>', CONCAT_WS('.', schema_name, tab_name, col_name));
sql_alter_table    := REPLACE(sql_alter_table,    '<masking_policy_name>', :masking_policy_name);
sql_alter_table    := REPLACE(sql_alter_table,    '<tab_name>', CONCAT_WS('.', schema_name, tab_name));
sql_alter_table    := REPLACE(sql_alter_table,    '<col_name>', col_name);

EXECUTE IMMEDIATE :sql_masking_policy;
EXECUTE IMMEDIATE :sql_alter_table;
    
RETURN sql_masking_policy || CHR(10) || sql_alter_table;
END;
$;

呼叫:

CALL test('public', 'mytable', 'col1');

输出:

CREATE OR REPLACE MASKING POLICY TAGS_MASKING__public_mytable_col1
AS (val VARCHAR) RETURNS VARCHAR ->                 
CASE                         
WHEN CURRENT_ROLE() IN ('ADMIN_ROLE') THEN val                 
WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SYSTEM$GET_TAG('TAG_NAME', 'public.mytable.col1', 'COLUMN') = 'PUBLIC') THEN val
WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SYSTEM$GET_TAG('TAG_NAME', 'public.mytable.col1', 'COLUMN') IN ('PROTECTED')) THEN '****MASKED****'
END; 
  
ALTER TABLE IF EXISTS public.mytable MODIFY COLUMN col1 SET MASKING POLICY TAGS_MASKING__public_mytable_col1; 

检查:

SHOW MASKING POLICIES;

输出:

​“ rel =“ nofollow noreferrer”> policy_context :

execute using policy_context(current_role => 'PUBLIC')
AS
SELECT * FROM public.mytable;
-- NULL

execute using policy_context(current_role => 'ADMIN_ROLE')
AS
SELECT * FROM public.mytable;
-- Test

execute using policy_context(current_role => 'ANALYST_ROLE')
AS
SELECT * FROM public.mytable;
-- Test

ALTER TABLE mytable SET TAG TAG_NAME='PROTECTED';

execute using policy_context(current_role => 'ANALYST_ROLE')
AS
SELECT * FROM public.mytable;
-- ****MASKED****

I have not found a way to parametrize the column name(passing it as optional second parameter) so I have used a differnt approach.

It automatically creates a masking policy per colum using Snowflake Scripting.

Setup:

CREATE OR REPLACE TAG TAG_NAME;

CREATE OR REPLACE TABLE mytable(col1 STRING); 
ALTER TABLE mytable SET TAG TAG_NAME='PUBLIC';

INSERT INTO mytable(col1) VALUES ('Test');

SELECT * FROM mytable;
-- Test

Procedure:

 CREATE OR REPLACE PROCEDURE test(schema_name STRING, tab_name STRING, col_name STRING)
 RETURNS STRING
 LANGUAGE SQL
 AS
 $
 DECLARE 
   sql_masking_policy   STRING;
   sql_alter_table      STRING;
   masking_policy_name  STRING := CONCAT_WS('_', 'TAGS_MASKING_', SCHEMA_NAME, TAB_NAME, COL_NAME);
 BEGIN
 sql_masking_policy := '
 CREATE OR REPLACE MASKING POLICY <masking_policy_name>
 AS (val VARCHAR) RETURNS VARCHAR ->
 CASE        
    WHEN CURRENT_ROLE() IN (''ADMIN_ROLE'') THEN val
    WHEN CURRENT_ROLE() IN (''ANALYST_ROLE'') AND (SYSTEM$GET_TAG(''TAG_NAME'', ''<col_name>'', ''COLUMN'') = ''PUBLIC'') THEN val
    WHEN CURRENT_ROLE() IN (''ANALYST_ROLE'') AND (SYSTEM$GET_TAG(''TAG_NAME'', ''<col_name>'', ''COLUMN'') IN (''PROTECTED'')) THEN ''****MASKED****''
 END;';
                             
sql_alter_table := 'ALTER TABLE IF EXISTS <tab_name> MODIFY COLUMN <col_name>
SET MASKING POLICY <masking_policy_name>;';

sql_masking_policy := REPLACE(sql_masking_policy, '<masking_policy_name>', :masking_policy_name);
sql_masking_policy := REPLACE(sql_masking_policy, '<col_name>', CONCAT_WS('.', schema_name, tab_name, col_name));
sql_alter_table    := REPLACE(sql_alter_table,    '<masking_policy_name>', :masking_policy_name);
sql_alter_table    := REPLACE(sql_alter_table,    '<tab_name>', CONCAT_WS('.', schema_name, tab_name));
sql_alter_table    := REPLACE(sql_alter_table,    '<col_name>', col_name);

EXECUTE IMMEDIATE :sql_masking_policy;
EXECUTE IMMEDIATE :sql_alter_table;
    
RETURN sql_masking_policy || CHR(10) || sql_alter_table;
END;
$;

Call:

CALL test('public', 'mytable', 'col1');

Output:

CREATE OR REPLACE MASKING POLICY TAGS_MASKING__public_mytable_col1
AS (val VARCHAR) RETURNS VARCHAR ->                 
CASE                         
WHEN CURRENT_ROLE() IN ('ADMIN_ROLE') THEN val                 
WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SYSTEM$GET_TAG('TAG_NAME', 'public.mytable.col1', 'COLUMN') = 'PUBLIC') THEN val
WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') AND (SYSTEM$GET_TAG('TAG_NAME', 'public.mytable.col1', 'COLUMN') IN ('PROTECTED')) THEN '****MASKED****'
END; 
  
ALTER TABLE IF EXISTS public.mytable MODIFY COLUMN col1 SET MASKING POLICY TAGS_MASKING__public_mytable_col1; 

Check:

SHOW MASKING POLICIES;

Output:

enter image description here

Test of select using POLICY_CONTEXT:

execute using policy_context(current_role => 'PUBLIC')
AS
SELECT * FROM public.mytable;
-- NULL

execute using policy_context(current_role => 'ADMIN_ROLE')
AS
SELECT * FROM public.mytable;
-- Test

execute using policy_context(current_role => 'ANALYST_ROLE')
AS
SELECT * FROM public.mytable;
-- Test

ALTER TABLE mytable SET TAG TAG_NAME='PROTECTED';

execute using policy_context(current_role => 'ANALYST_ROLE')
AS
SELECT * FROM public.mytable;
-- ****MASKED****
初心 2025-01-28 11:23:05

以前的答案可以通过使用新功能来改进:基于标签的掩蔽策略

基于标签的掩码策略结合了对象标签和掩盖策略功能,以允许使用Alter标记命令在标签上设置屏蔽策略。当屏蔽策略签名中的数据类型和列匹配的数据类型时,标记的列会自动受到掩盖策略中条件的保护。这简化了数据保护工作,因为应该保护的列数据不再需要手动应用于列的掩盖策略来保护数据。可以通过直接分配给列的掩蔽策略和基于标签的掩蔽策略

保护列的列

系统$ get_tag_on_current_column

 系统$ get_tag_on_current_column('&lt; tag_name&gt;')
 

,如果未分配给指定列的标签,则根据指定的标签分配给列的标签字符串值。


对于这种情况:

CREATE OR REPLACE TAG TAG_NAME;

CREATE OR REPLACE MASKING POLICY TAGS_MASKING
AS (val VARCHAR) RETURNS VARCHAR ->
CASE        
   WHEN CURRENT_ROLE() IN ('ADMIN_ROLE') THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') 
    AND SYSTEM$GET_TAG_ON_CURRENT_COLUMN('TAG_NAME') = 'PUBLIC' THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') 
    AND SYSTEM$GET_TAG_ON_CURRENT_COLUMN('TAG_NAME') IN ('PROTECTED') THEN '****MASKED****'
 END; 

ALTER TAG TAG_NAME SET MASKING POLICY TAGS_MASKING;

表:

CREATE OR REPLACE TABLE mytable(col1 STRING); 
INSERT INTO mytable(col1) VALUES ('Test');
SELECT * FROM mytable;
-- COL1
-- Test

分配标签:

ALTER TABLE mytable ALTER COLUMN col1 SET TAG TAG_NAME='PROTECTED';

actry_role/admis Analyst_role:

SELECT * FROM mytable;
-- COL1
-- null

切换到Analyst_role(用preectected值标记的列):

USE ROLE ANALYST_ROLE;

SELECT * FROM mytable;
-- COL1
-- ****MASKED****

The previous answer could be improved by using new feature: Tag-based Masking Policies:

A tag-based masking policy combines the object tagging and masking policy features to allow a masking policy to be set on a tag using an ALTER TAG command. When the data type in the masking policy signature and the data type of the column match, the tagged column is automatically protected by the conditions in the masking policy. This simplifies the data protection efforts because column data that should be protected no longer needs a masking policy manually applied to the column to protect the data. A column can be protected by a masking policy directly assigned to a column and a tag-based masking policy

SYSTEM$GET_TAG_ON_CURRENT_COLUMN:

SYSTEM$GET_TAG_ON_CURRENT_COLUMN( '<tag_name>' )

Returns the tag string value assigned to the column based upon the specified tag or NULL if a tag is not assigned to the specified column.


For this scenario:

CREATE OR REPLACE TAG TAG_NAME;

CREATE OR REPLACE MASKING POLICY TAGS_MASKING
AS (val VARCHAR) RETURNS VARCHAR ->
CASE        
   WHEN CURRENT_ROLE() IN ('ADMIN_ROLE') THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') 
    AND SYSTEM$GET_TAG_ON_CURRENT_COLUMN('TAG_NAME') = 'PUBLIC' THEN val
   WHEN CURRENT_ROLE() IN ('ANALYST_ROLE') 
    AND SYSTEM$GET_TAG_ON_CURRENT_COLUMN('TAG_NAME') IN ('PROTECTED') THEN '****MASKED****'
 END; 

ALTER TAG TAG_NAME SET MASKING POLICY TAGS_MASKING;

Table:

CREATE OR REPLACE TABLE mytable(col1 STRING); 
INSERT INTO mytable(col1) VALUES ('Test');
SELECT * FROM mytable;
-- COL1
-- Test

Assigning tag:

ALTER TABLE mytable ALTER COLUMN col1 SET TAG TAG_NAME='PROTECTED';

Role outside ADMIN_ROLE/ANALYST_ROLE:

SELECT * FROM mytable;
-- COL1
-- null

Switching to ANALYST_ROLE(column tagged with PROTECTED value):

USE ROLE ANALYST_ROLE;

SELECT * FROM mytable;
-- COL1
-- ****MASKED****
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文