CREATE MASKING POLICY

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

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

참고 항목:

중앙 집중식, 하이브리드 또는 분산형 방식 선택하기, 고급 열 수준 보안 항목

마스킹 정책 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> -> <body>
[ COMMENT = '<string_literal>' ]
[ EXEMPT_OTHER_POLICIES = { TRUE | FALSE } ]
Copy

필수 매개 변수

name

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

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

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

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

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

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

arg_name_to_mask arg_type_to_mask

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

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

[ , arg_1 arg_type_1 ... ]

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

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

RETURNS arg_type_to_mask

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

body

arg_name_to_mask 로 지정된 열의 데이터를 변환하는 SQL 식입니다.

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

UDF 및 외부 함수의 경우:

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

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

정책 body 에서 컨텍스트 함수의 경우:

정책이 CURRENT_DATABASE 또는 CURRENT_SCHEMA 함수를 호출할 경우 함수는 USE <오브젝트> 명령으로 지정하거나 Snowsight 의 컨텍스트 선택기로 선택하는 세션에 대한 데이터베이스나 스키마가 아니라 보호된 테이블이나 뷰가 포함된 데이터베이스나 스키마로 평가합니다.

선택적 매개 변수

COMMENT = 'string_literal'

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

EXEMPT_OTHER_POLICIES = TRUE | FALSE

사용량에 따라 다음 중 하나입니다.

  • 행 액세스 정책 또는 조건부 마스킹 정책이 이 마스킹 정책으로 이미 보호된 열을 참조할 수 있는지 여부를 지정합니다.

  • 가상 열에 할당된 마스킹 정책이 가상 열이 VALUE 열에서 상속하는 마스킹 정책을 재정의하는지 여부를 지정합니다. 외부 테이블로 작업할 때 VALUE 열을 보호하는 마스킹 정책에 이 속성을 지정합니다.

TRUE

다른 정책이 마스킹된 열을 참조하도록 허용하거나 가상 열에 설정된 마스킹 정책이 가상 열이 외부 테이블의 VALUE 열에서 상속하는 마스킹 정책을 재정의하도록 허용합니다.

FALSE

다른 정책이 마스킹된 열을 참조하도록 허용하지 않거나 가상 열이 외부 테이블의 VALUE 열에서 상속하는 마스킹 정책을 허용하지 않습니다.

다음 사항을 참고하십시오.

  • 마스킹 정책에서 이 속성의 값은 테이블 또는 뷰에 마스킹 정책을 설정한 후에는 바뀔 수 없습니다. 이 속성 설정의 값을 업데이트하려면 마스킹 정책에서 CREATE OR REPLACE MASKING POLICY 문을 실행하십시오.

  • 속성이 true로 설정되면 정책에서 GET_DDL 함수 호출의 출력에 속성이 포함됩니다.

액세스 제어 요구 사항

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

권한

오브젝트

참고

CREATE MASKING POLICY

스키마

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

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

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

마스킹 정책에서 EXEMPT_OTHER_POLICIES 속성을 지정할 때 마스킹 정책을 소유한 역할(즉, 정책에 대한 OWNERSHIP 권한이 있는 역할)은 행 액세스 정책 또는 조건부 마스킹 정책을 소유한 역할의 역할 계층 구조에 있어야 합니다.

예를 들어 정책 관리자 사용자 지정 역할은 다음과 같이 역할 계층 구조 를 형성할 수 있습니다.

masking_admin » rap_admin » SYSADMIN

masking_admin » cond_masking_admin » SYSADMIN

여기서

masking_admin

행 액세스 정책 또는 조건부 마스킹 정책의 서명에 지정될 열에 설정된 마스킹 정책을 소유하는 사용자 지정 역할을 지정합니다.

rap_admin

행 액세스 정책을 소유하는 사용자 지정 역할을 지정합니다.

cond_masking_admin

조건부 마스킹 정책을 소유하는 사용자 지정 역할을 지정합니다.

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

사용법 노트

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

  • For masking policies that include a subquery in the masking policy body, use EXISTS in the WHEN branch of the CASE function. 대표적인 예는 이 항목에서 일반 마스킹 정책 섹션의 사용자 지정 권리 테이블 예를 참조하십시오.

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

    자세한 내용은 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;
Copy

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

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

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

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

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

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

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

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

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

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

타임스탬프 사용.

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;
Copy

중요

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

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

UDF 사용:

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

베리언트 데이터에서:

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

사용자 지정 권리 유형 테이블 사용. 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;
Copy

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

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

JSON에서 <JavaScript UDF 사용하기(VARIANT):

이 예에서 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;
Copy

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;
Copy

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;
Copy

Snowflake는 다음을 반환합니다.

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

열 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) |
---+----------------------+
Copy

다른 컨텍스트 함수 및 역할 계층 구조를 사용하는 예는 고급 열 수준 보안 항목 을 참조하십시오.

예: 조건부 마스킹 정책

다음 예는 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;
Copy

다음 예는 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;
Copy

예: 행 액세스 정책 또는 조건부 마스킹 정책에서 마스킹된 열 허용

이메일 주소 보기, 이메일 주소 도메인만 보기 또는 마스킹된 고정 값 보기를 허용하는 마스킹 정책을 바꿉니다.

create or replace masking policy governance.policies.email_mask
as (val string) returns string ->
case
  when current_role() in ('ANALYST') then val
  when current_role() in ('SUPPORT') then regexp_replace(val,'.+\@','*****@')
  else '********'
end
comment = 'specify in row access policy'
exempt_other_policies = true
;
Copy

이제 열에 이 정책을 설정할 수 있으며 행 액세스 정책 또는 조건부 마스킹 정책은 필요에 따라 이 마스킹 정책으로 보호되는 열을 참조할 수 있습니다.