카테고리:

테이블, 뷰 및 시퀀스 DDL

CREATE MASKING POLICY

현재/지정된 스키마에서 새 마스킹 정책을 생성하거나 기존 마스킹 정책을 대체합니다.

마스킹 정책을 생성한 후, ALTER TABLE … ALTER COLUMN 명령을 사용하여 테이블의 열에 마스킹 정책을 적용하거나 ALTER VIEW 명령을 사용하여 뷰에 적용합니다.

참고 항목:

중앙 집중식, 하이브리드 또는 분산형 방식 선택하기, 고급 Column-level Security 항목

마스팅 정책 DDL

이 항목의 내용:

구문

CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] <name> AS
( <arg_name_to_mask> <arg_type_to_mask> [ , <arg_1> <arg_type_1> ... ] )
RETURNS <arg_type_to_mask> -> <expression_on_arg_name>
[ COMMENT = '<string_literal>' ];

매개 변수

name

마스킹 정책의 식별자로, 스키마에 고유한 식별자여야 합니다.

식별자 값은 알파벳 문자로 시작해야 하며 전체 식별자 문자열을 큰따옴표(예: "My object")로 묶지 않는 한 공백이나 특수 문자를 포함할 수 없습니다. 큰따옴표로 묶인 식별자도 대/소문자를 구분합니다.

자세한 내용은 식별자 요구 사항 섹션을 참조하십시오.

AS ( arg_name_to_mask arg_type_to_mask [ , arg_1 arg_type_1 ... ] )

마스킹 정책에 대한 서명입니다. 쿼리 런타임에 평가할 입력 열 및 데이터 타입을 지정합니다.

자세한 내용은 데이터 타입 섹션을 참조하십시오.

arg_name_to_mask arg_type_to_mask

첫 번째 열 및 해당 데이터 타입은 후속 정책 조건에서 마스킹하거나 토큰화할 열 데이터 타입 값을 항상 나타냅니다.

조건부 마스킹 정책에서는 가상 열을 첫 번째 열 인자로 지정할 수 없습니다.

[ , arg_1 arg_type_1 ... ]

정책 조건이 쿼리 결과의 각 행에 있는 첫 번째 열의 데이터를 마스킹하거나 토큰화해야 하는지 여부를 결정하기 위해 평가할 조건부 열 및 해당 데이터 타입을 지정합니다.

이러한 추가 열 및 데이터 타입이 지정되지 않은 경우 Snowflake는 정책을 일반 마스킹 정책으로 평가합니다.

RETURNS arg_type_to_mask

반환 데이터 타입은 입력 열로 지정된 첫 번째 열의 입력 데이터 타입과 일치해야 합니다.

expression_on_arg_name

데이터를 변환하는 SQL 식입니다.

이 식은 조건부 논리의 내장 함수를 나타내는 조건식 함수 또는 데이터를 변환하는 UDFs를 포함할 수 있습니다.

UDF 또는 외부 함수가 마스킹 정책 본문 내부에 사용되는 경우, 정책 소유자는 UDF 또는 외부 함수에 대한 USAGE이 있어야 합니다. UDF 또는 외부 함수에 대한 USAGE 권한은 마스킹 정책이 적용된 열을 쿼리하는 데 사용되는 역할에 필요하지 않습니다.

UDF 또는 외부 함수가 조건부 마스킹 정책 본문 내에서 사용되는 경우 정책 소유자는 UDF 또는 외부 함수에 대한 OWNERSHIP이 있어야 합니다. 조건부 마스킹 정책이 적용된 열을 쿼리하는 사용자는 UDF 또는 외부 함수에 USAGE가 필요하지 않습니다.

COMMENT = 'string_literal'

마스킹 정책에 대해 설명을 추가하거나 기존 설명을 덮어씁니다.

액세스 제어 요구 사항

이 SQL 명령을 실행하는 데 사용되는 역할 에는 최소한 다음 권한 이 있어야 합니다.

권한

오브젝트

참고

CREATE MASKING POLICY

스키마

스키마의 모든 오브젝트에 대해 작업하려면 상위 데이터베이스 및 스키마에 대한 USAGE 권한도 필요합니다.

지정된 권한 세트로 사용자 지정 역할을 만드는 방법에 대한 지침은 사용자 지정 역할 만들기 섹션을 참조하십시오.

보안 오브젝트 에 대해 SQL 작업을 수행하기 위한 역할과 권한 부여에 대한 일반적인 정보는 Snowflake에서의 액세스 제어 섹션을 참조하십시오.

마스킹 정책 DDL 및 권한에 대한 추가적인 세부 사항은 Column-level Security 관리하기 섹션을 참조하십시오.

사용법 노트

  • 기존 마스킹 정책을 바꾸고 싶은데 정책의 현재 정의를 확인해야 할 경우 GET_DDL 함수를 호출하거나 DESCRIBE MASKING POLICY 명령을 실행하십시오.

  • 마스킹 정책 본문에 하위 쿼리를 포함하는 마스킹 정책의 경우 WHEN 절에서 EXISTS 를 사용하십시오. 대표적인 예는 일반 마스킹 정책 섹션의 사용자 지정 권리 테이블 예를 참조하십시오.

  • 마스킹 정책 서명 또는 행 액세스 정책 서명에서 주어진 테이블 또는 뷰 열을 지정할 수 있습니다. 다시 말해, 마스킹 정책 서명과 행 액세스 정책 서명에 모두 동시에 같은 열을 지정할 수 없습니다.

    자세한 내용은 CREATE ROW ACCESS POLICY 섹션을 참조하십시오.

  • 데이터 공유 공급자는 독자 계정 에서 마스킹 정책을 만들 수 없습니다.

  • 마스킹 정책에서 UDF 를 사용하는 경우 열의 데이터 타입, UDF, 마스킹 정책이 일치하는지 확인하십시오. 자세한 내용은 마스킹 정책의 사용자 정의 함수 섹션을 참조하십시오.

  • 메타데이터 관련:

    주의

    고객은 Snowflake 서비스를 사용할 때 개인 데이터(사용자 오브젝트 제외), 민감한 데이터, 수출 통제 대상 데이터 또는 기타 규제 데이터가 메타데이터로 입력되지 않도록 해야 합니다. 자세한 내용은 Snowflake의 메타데이터 필드 섹션을 참조하십시오.

  • CREATE OR REPLACE <오브젝트> 문은 원자성입니다. 즉, 오브젝트가 바뀔 때 이전 오브젝트 삭제와 새 오브젝트 생성이 단일 트랜잭션으로 처리됩니다.

일반 마스킹 정책

조건식 함수, 컨텍스트 함수, UDFs를 사용하여 SQL 식을 작성할 수 있습니다.

다음은 다양한 SQL 식, 함수, 데이터 타입을 사용하여 마스킹 정책 조건을 만드는 방법을 보여주는 정책 본문의 대표적인 예입니다.

이들 예제에서는 주로 CURRENT_ROLE 컨텍스트 함수를 사용합니다. 정책 조건에서 역할 활성화 및 역할 계층 구조가 필요한 경우 IS_ROLE_IN_SESSION 을 사용합니다.

전체 마스크:

analyst 사용자 지정 역할은 일반 텍스트 값을 볼 수 있습니다. analyst 사용자 지정 역할이 없는 사용자에게는 전체 마스크가 표시됩니다.

CREATE OR REPLACE MASKING POLICY email_mask AS (val string) returns string ->
  CASE
    WHEN current_role() IN ('ANALYST') THEN VAL
    ELSE '*********'
  END;

프로덕션 계정 이 마스킹되지 않은 값과 다른 모든 계정(예: 개발, 테스트)을 보고 마스킹된 값을 볼 수 있도록 허용합니다.

case
  when current_account() in ('<prod_account_identifier>') then val
  else '*********'
end;

권한이 없는 사용자에 대해 NULL 반환:

case
  when current_role() IN ('ANALYST') then val
  else NULL
end;

권한이 없는 사용자에 대한 정적 마스킹 값 반환:

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE '********'
END;

권한이 없는 사용자에 대해 SHA2 , SHA2_HEX 를 사용하는 해시 값을 반환합니다. 마스킹 정책에서 해싱 함수를 사용하면 충돌이 발생할 수 있으므로, 이 접근 방식을 사용할 때는 주의하십시오. 자세한 내용은 고급 Column-level Security 항목 섹션을 참조하십시오.

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE sha2(val) -- return hash of the column value
END;

부분 마스크 또는 전체 마스크 적용:

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  WHEN current_role() IN ('SUPPORT') THEN regexp_replace(val,'.+\@','*****@') -- leave email domain unmasked
  ELSE '********'
END;

타임스탬프 사용.

case
  WHEN current_role() in ('SUPPORT') THEN val
  else date_from_parts(0001, 01, 01)::timestamp_ntz -- returns 0001-01-01 00:00:00.000
end;

중요

현재, Snowflake는 타임스탬프를 대상으로 하고 문자열(예: ***MASKED***)을 반환하는 마스킹 정책을 정의하는 것과 같이, 마스킹 정책에서 다양한 입력 및 출력 데이터 타입을 지원하지 않으며, 입력 및 출력 데이터 타입이 일치해야 합니다.

해결 방법은 실제 타임스탬프 값을 생성된 타임스탬프 값으로 캐스팅하는 것입니다. 자세한 내용은 DATE_FROM_PARTSCAST , :: 섹션을 참조하십시오.

UDF 사용:

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE mask_udf(val) -- custom masking function
END;

베리언트 데이터에서:

CASE
   WHEN current_role() IN ('ANALYST') THEN val
   ELSE OBJECT_INSERT(val, 'USER_IPADDRESS', '****', true)
END;

사용자 지정 권리 유형 테이블 사용. WHEN 절에서 EXISTS 의 사용에 유의하십시오. 마스킹 정책 본문에 하위 쿼리를 포함할 때 EXISTS를 항상 사용합니다. Snowflake가 지원하는 하위 쿼리에 대한 자세한 내용은 하위 쿼리 관련 작업하기 을 참조하십시오.

CASE
  WHEN EXISTS
    (SELECT role FROM <db>.<schema>.entitlement WHERE mask_method='unmask' AND role = current_role()) THEN val
  ELSE '********'
END;

암호화된 데이터에서 암호 구문과 함께 ENCRYPT 또는 ENCRYPT_RAW 를 사용해 이전에 암호화된 데이터에 DECRYPT 사용:

case
  when current_role() in ('ANALYST') then DECRYPT(val, $passphrase)
  else val -- shows encrypted value
end;

JSON에서 JavaScript UDFs 사용(베리언트):

이 예에서 JavaScript UDF는 JSON 문자열의 위치 데이터를 마스킹합니다. UDF 및 마스킹 정책에서 VARIANT와 같은 데이터 타입을 설정하는 것이 중요합니다. 테이블 열의 데이터 타입 UDF와 마스킹 정책 서명이 일치하지 않을 경우, Snowflake는 SQL을 확인할 수 없으므로 오류 메시지를 반환합니다.

-- Flatten the JSON data

create or replace table <table_name> (v variant) as
select value::variant
from @<table_name>,
  table(flatten(input => parse_json($1):stationLocation));

-- JavaScript UDF to mask latitude, longitude, and location data

CREATE OR REPLACE FUNCTION full_location_masking(v variant)
  RETURNS variant
  LANGUAGE JAVASCRIPT
  AS
  $$
    if ("latitude" in V) {
      V["latitude"] = "**latitudeMask**";
    }
    if ("longitude" in V) {
      V["longitude"] = "**longitudeMask**";
    }
    if ("location" in V) {
      V["location"] = "**locationMask**";
    }

    return V;
  $$;

  -- Grant UDF usage to ACCOUNTADMIN

  grant ownership on function FULL_LOCATION_MASKING(variant) to role accountadmin;

  -- Create a masking policy using JavaScript UDF

  create or replace masking policy json_location_mask as (val variant) returns variant ->
    CASE
      WHEN current_role() IN ('ANALYST') THEN val
      else full_location_masking(val)
      -- else object_insert(val, 'latitude', '**locationMask**', true) -- limited to one value at a time
    END;

GEOGRAPHY 데이터 타입 사용:

이 예에서 마스킹 정책은 CURRENT_ROLE이 ANALYST 가 아닌 사용자에 대해 열의 모든 GEOGRAPHY 데이터를 고정 소수점, 즉 캘리포니아 샌머테이오에 있는 Snowflake의 경도와 위도로 변환하는 TO_GEOGRAPHY 함수를 사용합니다.

create masking policy mask_geo_point as (val geography) returns geography ->
  case
    when current_role() IN ('ANALYST') then val
    else to_geography('POINT(-122.35 37.55)')
  end;

GEOGRAPHY 데이터 타입이 있는 열에 마스킹 정책을 설정하고 세션의 GEOGRAPHY_OUTPUT_FORMAT 값을 GeoJSON 으로 설정합니다.

alter table mydb.myschema.geography modify column b set masking policy mask_geo_point;
alter session set geography_output_format = 'GeoJSON';
use role public;
select * from mydb.myschema.geography;

Snowflake는 다음을 반환합니다.

---+--------------------+
 A |         B          |
---+--------------------+
 1 | {                  |
   |   "coordinates": [ |
   |     -122.35,       |
   |     37.55          |
   |   ],               |
   |   "type": "Point"  |
   | }                  |
 2 | {                  |
   |   "coordinates": [ |
   |     -122.35,       |
   |     37.55          |
   |   ],               |
   |   "type": "Point"  |
   | }                  |
---+--------------------+

열 B의 쿼리 결과 값은 세션의 GEOGRAPHY_OUTPUT_FORMAT 매개 변수 값에 따라 다릅니다. 예를 들어 매개 변수 값이 WKT 로 설정된 경우 Snowflake는 다음을 반환합니다.

alter session set geography_output_format = 'WKT';
select * from mydb.myschema.geography;

---+----------------------+
 A |         B            |
---+----------------------+
 1 | POINT(-122.35 37.55) |
 2 | POINT(-122.35 37.55) |
---+----------------------+

다른 컨텍스트 함수 및 역할 계층 구조를 사용하는 예는 고급 Column-level Security 항목 을 참조하십시오.

조건부 마스킹 정책

다음 예는 CURRENT_ROLEadmin 사용자 지정 역할이거나, 가시성 열의 값이 Public 인 사용자에 대해 마스킹되지 않은 데이터를 반환합니다. 다른 모든 조건은 고정된 마스킹 값을 생성합니다.

-- Conditional Masking

create masking policy email_visibility as
(email varchar, visibility string) returns varchar ->
  case
    when current_role() = 'ADMIN' then email
    when visibility = 'Public' then email
    else '***MASKED***'
  end;

다음 예는 CURRENT_ROLEadmin 사용자 지정 역할이고, 다른 열의 값이 Public 인 사용자에 대해 토큰화된 데이터를 반환합니다. 다른 모든 조건은 토큰화된 값을 생성합니다.

-- Conditional Tokenization

create masking policy de_email_visibility as
 (email varchar, visibility string) returns varchar ->
   case
     when current_role() = 'ADMIN' and visibility = 'Public' then de_email(email)
     else email -- sees tokenized data
   end;
맨 위로 이동