Dynamic Data Masking 사용하기¶
이 항목에서는 Snowflake에서 Dynamic Data Masking을 구성 및 사용하는 방법에 대한 지침을 제공합니다.
태그와 함께 마스킹 정책을 사용하는 방법에 대해 자세히 알아보려면 태그 기반 마스킹 정책 섹션을 참조하십시오.
Dynamic Data Masking 사용하기¶
Snowflake에서 Dynamic Data Masking을 구성 및 사용하기 위한 간략한 단계는 다음과 같습니다.
- 보안 또는 개인정보보호 담당자를 위한 사용자 지정 역할에 마스킹 정책 관리 권한을 부여합니다. 
- 알맞은 사용자에게 사용자 지정 역할을 부여합니다. 
- 보안 또는 개인정보보호 담당자는 마스킹 정책을 생성 및 정의하고 민감한 데이터가 있는 열에 마스킹 정책을 적용합니다. 
- Snowflake에서 쿼리를 실행합니다. 다음 사항을 참고하십시오. - Snowflake는 마스킹 정책 SQL 식을 열에 적용하여 쿼리를 동적으로 다시 작성합니다. 
- 열 재작성은 마스킹 정책에 지정된 열이 쿼리에서 나타나는 모든 위치(예: 프로젝션, Join 조건자, Where 절 조건자, order by 및 group by)에서 발생합니다. 
- 마스킹 정책에 정의된 실행 컨텍스트 조건에 따라 마스킹된 데이터가 사용자에게 표시됩니다. Dynamic Data Masking 정책에서의 실행 컨텍스트에 대한 자세한 내용은 고급 열 수준 보안 항목 을 참조하십시오. 
 
1단계: 사용자 지정 역할에 마스킹 정책 권한 부여¶
보안 또는 개인정보보호 담당자 는 마스킹 정책 관리자(즉, 사용자 지정 역할: MASKING_ADMIN)의 역할을 수행해야 하며 마스킹 정책을 정의, 관리 및 열에 적용할 수 있는 권한이 있어야 합니다.
Column-level Security 마스킹 정책과 관련하여 보안 또는 개인정보보호 담당자에게 부여할 수 있도록 Snowflake에서 제공하는 권한은 다음과 같습니다.
| 권한 | 설명 | 
|---|---|
| CREATE MASKING POLICY | 이 스키마 수준 권한은 마스킹 정책을 생성할 수 있는 사용자를 제어합니다. | 
| APPLY MASKING POLICY | 이 계정 수준 권한은 열에 대한 마스킹 정책을 설정[해제]할 수 있는 사용자를 제어하며 기본적으로 ACCOUNTADMIN 역할에 부여됩니다. . 이 권한에서는 마스킹 정책을 열에 적용하는 것만 가능하며 액세스 제어 권한 에서 설명된 추가 테이블 권한을 제공하지 않습니다. | 
| APPLY ON MASKING POLICY | 선택 사항입니다. 이 정책 수준 권한은 정책 소유자가 열에 대한 지정된 마스킹 정책의 설정[해제] 작업을 오브젝트 소유자(즉, 오브젝트에 대한 OWNERSHIP 권한을 보유한 역할)로 분산시키기 위해 사용할 수 있습니다. . Snowflake는 임의 액세스 제어 를 지원하며, 이 경우에는 오브젝트 소유자도 데이터 관리자로 간주됩니다. . 정책 관리자가 오브젝트 소유자를 보호된 열의 데이터 관리자로 신뢰하는 경우 정책 관리자는 이 권한을 사용하여 정책 설정[해제] 작업의 적용을 분산시킬 수 있습니다. | 
다음 예에서는 MASKING_ADMIN 역할을 생성하고 마스킹 정책 권한을 해당 역할에 부여합니다.
다음과 같이 마스킹 정책 관리자 사용자 지정 역할 생성:
use role useradmin; CREATE ROLE masking_admin;
masking_admin 역할에 권한 부여:
use role securityadmin; GRANT CREATE MASKING POLICY on SCHEMA <db_name.schema_name> to ROLE masking_admin; GRANT APPLY MASKING POLICY on ACCOUNT to ROLE masking_admin;
table_owner 역할이 ssn_mask 마스킹 정책을 설정하거나 설정 해제하도록 허용(선택 사항):
GRANT APPLY ON MASKING POLICY ssn_mask to ROLE table_owner;
여기서:
- db_name.schema_name
- 권한이 부여되어야 하는 스키마의 식별자를 지정합니다. 
 
자세한 내용은 다음을 참조하십시오.
2단계: 사용자에게 사용자 지정 역할 부여¶
보안 책임자 또는 개인정보 보호 책임자 역할을 하는 사용자에게 MASKING_ADMIN 사용자 지정 역할을 부여합니다.
GRANT ROLE masking_admin TO USER jsmith;
3단계: 마스킹 정책 만들기¶
MASKING_ADMIN 역할을 사용하여 마스킹 정책을 생성한 후 열에 적용합니다.
이 대표적인 예에서 ANALYST 역할의 사용자에게는 마스크되지 않은 값이 표시됩니다. ANALYST 역할이 없는 사용자에게는 전체 마스크가 표시됩니다.
CREATE OR REPLACE MASKING POLICY email_mask AS (val string) RETURNS string ->
  CASE
    WHEN CURRENT_ROLE() IN ('ANALYST') THEN val
    ELSE '*********'
  END;
팁
기존 마스킹 정책을 업데이트하고 정책의 현재 정의를 확인해야 할 경우 GET_DDL 함수를 호출하거나 DESCRIBE MASKING POLICY 명령을 실행합니다.
4단계: 테이블 또는 뷰 열에 마스킹 정책 적용¶
이런 예에서는 테이블 생성 시에는 테이블 열에, 뷰 생성 시에는 뷰 열에 마스킹 정책이 적용되지 않는 것으로 가정합니다. CREATE TABLE 문이 포함된 테이블 또는 CREATE VIEW 문이 포함된 뷰 열을 만들 때 마스킹 정책을 테이블 열에 선택적으로 적용할 수 있습니다.
다음 문을 실행하여 테이블의 열 또는 뷰의 열에 정책을 적용합니다.
-- apply masking policy to a table column
ALTER TABLE IF EXISTS user_info MODIFY COLUMN email SET MASKING POLICY email_mask;
-- apply the masking policy to a view column
ALTER VIEW user_info_v MODIFY COLUMN email SET MASKING POLICY email_mask;
5단계: Snowflake의 데이터 쿼리¶
Snowflake에서 ANALYST 역할의 쿼리와 다른 역할의 쿼리를 실행하여 ANALYST 역할이 없는 사용자에게 전체 마스크가 표시되는지 확인합니다.
-- using the ANALYST role
USE ROLE analyst;
SELECT email FROM user_info; -- should see plain text value
-- using the PUBLIC role
USE ROLE PUBLIC;
SELECT email FROM user_info; -- should see full data mask
메모이제이션 가능 함수가 있는 마스킹 정책¶
이 예제에서는 메모이제이션 가능 함수 를 사용하여 역할이 PII 데이터를 볼 수 있는 권한이 있는지 여부를 결정하는 쿼리 결과를 매핑 테이블에 캐시합니다. 데이터 엔지니어는 마스킹 정책을 사용하여 테이블의 열을 보호합니다.
다음 프로시저에서는 이러한 오브젝트를 참조하십시오.
- PII 데이터 - employee_data가 포함된 테이블:- +----------+-------------+---------------+ | USERNAME | ID | PHONE_NUMBER | +----------+-------------+---------------+ | JSMITH | 12-3456-89 | 1555-523-8790 | | AJONES | 12-0124-32 | 1555-125-1548 | +----------+-------------+---------------+ 
- 특정 역할이 데이터를 볼 수 있는 권한이 있는지 여부를 결정하는 매핑 테이블, - auth_role_t:- +---------------+---------------+ | ROLE | IS_AUTHORIZED | +---------------+---------------+ | DATA_ENGINEER | TRUE | | DATA_STEWARD | TRUE | | IT_ADMIN | TRUE | | PUBLIC | FALSE | +---------------+---------------+ 
인자를 사용하여 메모이제이션 가능 함수를 호출하는 마스킹 정책을 만들려면 다음 단계를 완료합니다.
- 매핑 테이블을 쿼리하는 메모이제이션 가능 함수를 만듭니다. 이 함수는 - is_authorized열의 값에 따라 역할 배열을 반환합니다.- CREATE FUNCTION is_role_authorized(arg1 VARCHAR) RETURNS BOOLEAN MEMOIZABLE AS $$ SELECT ARRAY_CONTAINS( arg1::VARIANT, (SELECT ARRAY_AGG(role) FROM auth_role WHERE is_authorized = TRUE) ) $$; 
- 메모이제이션 가능 함수를 호출하여 쿼리 결과를 캐시합니다. 이 예제에서는 결과 배열이 마스킹 정책으로 보호되는 데이터에 액세스할 수 있는 허용된 역할의 소스 역할을 하므로 인자 값으로 - TRUE를 전달합니다.- SELECT is_role_authorized(IT_ADMIN); - +---------------------------------------------+ | is_role_authorized(IT_ADMIN) | +---------------------------------------------+ | TRUE | +---------------------------------------------+ 
- id열을 보호하는 마스킹 정책을 만듭니다. 정책은 보호된 열의 데이터를 볼 수 있는 권한이 테이블을 쿼리하는 데 사용된 역할에 있는지 확인하기 위해 메모이제이션 가능 함수를 호출합니다.- CREATE OR REPLACE MASKING POLICY empl_id_mem_mask AS (val VARCHAR) RETURNS VARCHAR -> CASE WHEN is_role_authorized(CURRENT_ROLE()) THEN val ELSE NULL END; 
- ALTER TABLE … ALTER COLUMN 명령으로 테이블에 마스킹 정책을 설정합니다. - ALTER TABLE employee_data MODIFY COLUMN id SET MASKING POLICY empl_id_mem_mask; 
- 정책을 테스트하기 위해 테이블을 쿼리합니다. - USE ROLE data_engineer; SELECT * FROM employee_data; - 이 쿼리는 마스크되지 않은 데이터를 반환합니다. - 그러나 PUBLIC 역할로 역할을 전환하고 이 단계에서 쿼리를 반복하면 - id의 값이- NULL로 대체됩니다.
추가 마스킹 정책 예시¶
Dynamic Data Masking 정책의 본문에서 사용할 수 있는 추가적인 대표적인 예는 다음과 같습니다.
프로덕션 계정 이 마스킹되지 않은 값과 다른 모든 계정(예: 개발, 테스트)을 보고 마스킹된 값을 볼 수 있도록 허용합니다.
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 를 사용하는 해시 값을 반환합니다. 마스킹 정책에서 해싱 함수를 사용하면 충돌이 발생할 수 있으므로, 이 접근 방식을 사용할 때는 주의하십시오. 자세한 내용은 고급 열 수준 보안 항목 섹션을 참조하십시오.
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_PARTS 및 CAST , :: 섹션을 참조하십시오.
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 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;
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) | ---+----------------------+
다른 컨텍스트 함수 및 역할 계층 구조를 사용하는 예는 고급 열 수준 보안 항목 을 참조하십시오.
다음 항목: