Dynamic Data Masking 사용하기

이 항목에서는 Snowflake에서 Dynamic Data Masking을 구성 및 사용하는 방법에 대한 지침을 제공합니다.

태그와 함께 마스킹 정책을 사용하는 방법에 대해 자세히 알아보려면 태그 기반 마스킹 정책 섹션을 참조하십시오.

Dynamic Data Masking 사용하기

Snowflake에서 Dynamic Data Masking을 구성 및 사용하기 위한 간략한 단계는 다음과 같습니다.

  1. 보안 또는 개인정보보호 담당자를 위한 사용자 지정 역할에 마스킹 정책 관리 권한을 부여합니다.

  2. 알맞은 사용자에게 사용자 지정 역할을 부여합니다.

  3. 보안 또는 개인정보보호 담당자는 마스킹 정책을 생성 및 정의하고 민감한 데이터가 있는 열에 마스킹 정책을 적용합니다.

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

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

table_owner 역할이 ssn_mask 마스킹 정책을 설정하거나 설정 해제하도록 허용(선택 사항):

GRANT APPLY ON MASKING POLICY ssn_mask to ROLE table_owner;
Copy

여기서:

  • db_name.schema_name

    권한이 부여되어야 하는 스키마의 식별자를 지정합니다.

자세한 내용은 다음을 참조하십시오.

2단계: 사용자에게 사용자 지정 역할 부여

보안 책임자 또는 개인정보 보호 책임자 역할을 하는 사용자에게 MASKING_ADMIN 사용자 지정 역할을 부여합니다.

GRANT ROLE masking_admin TO USER jsmith;
Copy

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

기존 마스킹 정책을 업데이트하고 정책의 현재 정의를 확인해야 할 경우 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;
Copy

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
Copy

추가 마스킹 정책 예시

Dynamic Data Masking 정책의 본문에서 사용할 수 있는 추가적인 대표적인 예는 다음과 같습니다.

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

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

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

다음 항목: