고급 열 수준 보안 항목

이 항목에서는 Column-level Security 마스킹 정책과 관련된 두 가지 고급 개념을 소개합니다.

  1. 역할 계층 구조.

  2. 여러 컨텍스트 함수 사용하기.

컨텍스트 함수 및 역할 계층 구조

Column-level Security는 사용자에게 데이터를 볼 수 있는 권한이 있는지 여부를 적용하기 위해 마스킹 정책 본문의 조건에서 컨텍스트 함수 를 사용할 수 있도록 지원합니다. 사용자가 지정된 SQL 문에서 데이터를 볼 수 있는지 여부를 판단하려면 다음을 고려하는 것이 좋습니다.

현재 세션:

CURRENT_ROLE 을 사용한 마스킹 정책 조건의 대상은 현재 세션에서 사용 중인 역할입니다.

실행 중 역할:

INVOKER_ROLE 을 사용한 마스킹 정책 조건의 대상은 SQL 문에서 실행 중인 역할입니다.

역할 계층 구조:

정책 조건에서 역할 계층 구조가 필요한 경우 IS_ROLE_IN_SESSION 을 사용합니다.

마스킹 정책 조건에서 지정된 역할(예: analyst 사용자 지정 역할)이 CURRENT_ROLE 또는 INVOKER_ROLE 역할 계층에서 더 낮은 수준의 권한 역할인지 결정합니다. 그러한 경우, CURRENT_ROLE 또는 INVOKER_ROLE 함수에서 반환되는 역할이 지정된 역할의 권한을 상속합니다. 역할 계층 구조 및 권한 상속에 대한 자세한 내용은 다음을 참조하십시오.

다음 테이블은 현재 세션, 실행 중인 역할 및 역할 계층 구조를 대상으로 하는 마스킹 정책의 일반적인 컨텍스트 함수를 보여줍니다.

컨텍스트 함수

설명

CURRENT_ROLE

현재 세션에 사용 중인 역할의 이름을 반환합니다.

IS_ROLE_IN_SESSION

세션에서 사용자의 현재 역할(CURRENT_ROLE 이 반환한 역할)이 지정된 역할의 권한을 상속하는 경우 TRUE를 반환합니다.

INVOKER_ROLE

실행 중인 역할의 이름을 반환합니다.

IS_GRANTED_TO_INVOKER_ROLE

INVOKER_ROLE 함수에서 반환하는 역할이 함수가 호출되는 컨텍스트를 기반으로 인자에 지정된 역할의 권한을 상속하는 경우 TRUE를 반환합니다.

INVOKER_SHARE

INVOKER_SHARE 함수가 호출된 테이블 또는 뷰에 직접적으로 액세스한 공유의 이름을 반환합니다.

CURRENT_ROLE 및 IS_ROLE_IN_SESSION 사용하기

CURRENT_ROLE을 사용하는 마스킹 정책 조건의 대상은 현재 세션이며 SQL 문의 실행 컨텍스트로부터 영향을 받지 않습니다.

정책 조건에서 역할 활성화 및 역할 계층 구조가 필요한 경우 IS_ROLE_IN_SESSION 을 사용합니다.

다음 마스킹 정책 본문을 고려하십시오.

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN CURRENT_ROLE() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

지정된 사용자에게 이 마스킹 정책이 해당 열에 설정된 열의 데이터를 볼 수 있는 권한이 있는지 판단하려면 다음 단계를 완료하십시오.

  1. 마스킹 정책 조건을 평가합니다.

  2. 지정된 역할이 CURRENT_ROLE 계층 구조에 있는지 판단합니다.

  3. 확인할 테스트 쿼리를 실행합니다.

1단계: 마스킹 정책 조건 평가

다음 테이블은 마스킹 정책 본문 조건의 결과를 요약하여 보여줍니다.

컨텍스트

마스킹되지 않은 데이터를 볼 수 있음

마스킹된 데이터를 볼 수 있음

CURRENT_ROLE = ANALYST 사용자 지정 역할.

CURRENT_ROLE이 계층 구조에서 ANALYST 사용자 지정 역할 내에 있습니다.

CURRENT_ROLE이 ANALYST 사용자 지정 역할 계층 구조 내에 있지 않습니다.

다음으로 역할 계층 구조를 평가합니다.

2단계: 지정된 역할이 CURRENT_ROLE 계층 구조에 있는지 판단

CURRENT_ROLE이 ANALYST 사용자 지정 역할이 아니라고 가정하고, CURRENT_ROLE이 ANALYST 사용자 지정 역할에 부여된 권한을 상속하는지 확인합니다.

다음 문 실행:

SELECT IS_ROLE_IN_SESSION('ANALYST');
Copy
+-------------------------------+
| IS_ROLE_IN_SESSION('ANALYST') |
+-------------------------------+
| FALSE                         |
+-------------------------------+

Snowflake에서 FALSE가 반환되므로, CURRENT_ROLE은 ANALYST 사용자 지정 역할에 부여된 권한을 상속하지 않습니다. 그러므로 이 예에서 제공되는 마스킹 정책 본문을 기반으로 사용자는 고정 마스크 값을 확인해야 합니다.

3단계: 확인할 테스트 쿼리 실행

이 예의 마스킹 정책이 해당 열에 적용된 열에서 쿼리를 실행하여, 사용자에게 고정 마스킹 값이 표시되는지 확인합니다.

USE ROLE analyst;

SELECT * FROM mydb.mysch.mytable;
Copy

INVOKER_ROLE 사용하기

INVOKER_ROLE을 사용하는 마스킹 정책 조건의 대상은 SQL 문의 실행 컨텍스트입니다.

다음 테이블은 마스킹 정책 조건에서 INVOKER_ROLE이 반환하는 실행 컨텍스트와 값을 요약하여 보여줍니다.

컨텍스트

평가되는 역할

사용자

CURRENT_ROLE

테이블

CURRENT_ROLE.

뷰 소유자 역할.

UDF

UDF 소유자 역할입니다.

호출자의 권한이 있는 저장 프로시저

CURRENT_ROLE.

소유자의 권한이 있는 저장 프로시저

저장 프로시저 소유자 역할.

작업

작업 소유자 역할.

스트림

지정된 스트림 을 쿼리하는 역할입니다.

테이블의 단일 뷰에 적용되는 다음 마스킹 정책 본문을 생각해 보십시오.

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN INVOKER_ROLE() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

열에 대해 쿼리를 실행하는 지정된 사용자에게 데이터를 볼 수 있는 권한이 있는지 판단하려면 다음 단계를 완료하십시오.

  1. 마스킹 정책 조건을 평가합니다.

  2. 지정된 역할이 뷰를 소유하는지 판단합니다.

  3. 확인할 테스트 쿼리를 실행합니다.

1단계: 마스킹 정책 조건 평가

다음 테이블은 뷰 열에 적용된 마스킹 정책 본문 조건의 결과를 요약하여 보여줍니다.

컨텍스트

마스킹되지 않은 데이터를 볼 수 있음

마스킹된 데이터를 볼 수 있음

analyst 사용자 지정 역할이 뷰 소유자 역할입니다.

analyst 사용자 지정 역할이 뷰 소유자 역할이 아닙니다.

다음으로 ANALYST 사용자 지정 역할이 뷰를 소유하는지 판단합니다.

2단계: ANALYST 역할이 뷰를 소유하는지 판단

ANALYST 사용자 지정 역할이 뷰를 소유하는지 판단하려면 다음 문을 실행합니다.

SHOW GRANTS OF ROLE analyst;
Copy

analyst 사용자 지정 역할이 뷰를 소유하는 경우 뷰 열에 대한 쿼리의 결과는 마스킹되지 않은 데이터가 표시되어야 합니다.

analyst 사용자 지정 역할이 뷰를 소유하지 않는 경우 마스킹된 데이터가 표시되어야 합니다.

3단계: 확인할 테스트 쿼리 실행

뷰 열에서 쿼리를 실행하여 ANALYST 사용자 지정 역할이 마스킹되거나 마스킹되지 않은 데이터를 볼 수 있는지 여부를 판단합니다.

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

IS_GRANTED_TO_INVOKER_ROLE 사용하기

조건의 일부로 IS_GRANTED_TO_INVOKER_ROLE 함수를 마스킹 정책 본문에 전달할 수 있습니다. 함수의 결과가 TRUE이면 함수 인자의 역할이 INVOKER_ROLE 계층 구조에 있는 것입니다.

소셜 시큐리티 번호(SSNs)의 뷰 열에 적용되는 다음 마스킹 정책 본문을 생각해 보겠습니다.

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN IS_GRANTED_TO_INVOKER_ROLE('PAYROLL') THEN val
  WHEN IS_GRANTED_TO_INVOKER_ROLE('ANALYST') THEN REGEXP_REPLACE(val, '[0-9]', '*', 7)
  ELSE '*******'
END;
Copy

뷰 열에서 쿼리를 실행하는 지정된 사용자에게 데이터를 볼 수 있는 권한이 있는지 판단하려면 다음 단계를 완료합니다.

  1. 마스킹 정책 조건을 평가합니다.

  2. 지정된 역할이 호출자 역할 계층 구조 내에 있는지 판단합니다. 예를 들어 정책이 뷰에 설정된 경우 TRUE를 반환하려면 지정된 역할이 뷰 소유자 역할 계층에 있어야 합니다. 자세한 내용은 사용법 노트 를 참조하십시오.

  3. 확인할 테스트 쿼리를 실행합니다.

1단계: 마스킹 정책 조건 평가

다음 테이블은 뷰 열 및 뷰 열의 보기 데이터에 적용된 마스킹 정책 본문 조건의 결과를 요약하여 보여줍니다.

컨텍스트

마스킹되지 않은 데이터

부분적으로 마스킹된 데이터

마스킹된 데이터

payroll 사용자 지정 역할이 뷰 소유자 역할 계층 구조 내에 있습니다.

analyst 사용자 지정 역할이 뷰 소유자 역할 계층 구조 내에 있습니다.

payrollanalyst 사용자 지정 역할 모두 뷰 소유자 역할 계측 구조 내에 없습니다.

2단계: 지정된 역할이 뷰 소유자 역할 계층 구조 내에 있는지 판단

payroll 또는 analyst 사용자 지정 역할이 뷰 소유자 계층 구조 내에 있는 경우 뷰 소유자 역할에 대해 SHOW GRANTS 명령을 실행하면 역할 계층 구조를 확인할 수 있습니다. 예:

SHOW GRANTS TO ROLE view_owner_role;
Copy

SQL 문의 출력은 뷰 소유자 역할에 payroll 또는 analyst 사용자 지정 역할이 부여되었는지 여부를 나타냅니다.

3단계: 확인할 테스트 쿼리 실행

이 예의 마스킹 정책이 해당 열에 적용된 열에서 쿼리를 실행하여, 사용자가 뷰 열의 데이터를 보는 방법을 확인합니다.

USE ROLE payroll;

SELECT * FROM mydb.mysch.myview;

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

마스킹 정책에서 CURRENT_ROLE 및 INVOKER_ROLE 결합하기

Snowflake는 쿼리를 실행하는 세션(즉, CURRENT_ROLE)과 쿼리를 실행하는 오브젝트 소유자(즉, 뷰 소유자, INVOKER_ROLE)에서 사용 중인 역할을 구분하기 위해 단일 마스킹 정책을 생성하도록 지원합니다. 이러한 타입의 사용 사례는 일반적으로 마스킹할 값 세트와 마스킹되지 않은 값을 볼 수 있는 상대적으로 적은 수의 대상 그룹(예: analyst 사용자 지정 역할이 포함된 사용자)을 단순하게 결정하는 것보다 더 복잡합니다.

마스킹 정책에서의 해싱, 암호화 및 암호화 함수

해싱암호화/체크섬 을 마스킹 정책에서 사용하여 민감한 데이터를 마스킹할 수 있습니다.

마스킹 정책 에서 이러한 함수를 구현하기 전, 이러한 함수의 사용 사례에 JOIN 작업이 포함되는지 여부를 고려하는 것이 중요합니다. 특정 마스킹 정책 구현의 경우, 테이블 및 뷰가 포함되는 창의적인 JOIN 작업은 다음 제한 사항에 따라 마스킹된 값을 실제 값으로 리버스 엔지니어링하는 것이 가능합니다.

  • 실제 값(즉, 입력)과 변환할 총 값 수(즉, 출력, 값 범위)를 기반으로 하는 해시, 암호화 또는 체크섬 값의 1:1 표현이 없기 때문에 충돌이 발생할 수 있습니다.

입력 값의 총 수가 변환할 출력 값의 제곱근에 도달할 때까지 1:1 표현이 발생할 가능성이 더 높습니다.

예를 들어, 해시에 대한 출력 값이 144이면 처음 12개 값(즉, 144^(1/2) – 144의 제곱근)이 고유하고 나머지 132개의 값에서 충돌이 발생할 수 있다고 예상하는 것은 합리적입니다. 이러한 제한 및 해당 결과가 가능하기 때문에, JOIN 작업에서 값이 사용될 수 있는 마스킹 정책에서는 해시, 암호화 또는 체크섬 함수를 절대로 사용하지 않는 것이 좋습니다.

마스킹 정책 사용 사례에서 보안 강화를 위한 충돌 방지를 우선 적용하는 경우에는 외부 토큰화 를 구현하십시오. 입력 값과 출력 값은 항상 1:1로 표시되므로 토큰화로 인한 충돌이 발생하지 않습니다.

토큰화를 사용할 수 없는 경우, 이를 해결하기 위한 한 가지 방법은 마스킹 정책을 구현하여 쿼리를 실행하는 세션 역할(즉, CURRENT_ROLE)과 쿼리를 실행하는 오브젝트 소유자(즉, INVOKER_ROLE)를 구분하는 것입니다.

예를 들어, 다음 마스킹 정책에서는 직원 정보에 대한 액세스를 규정하기 위해 2개의 사용자 지정 역할인 CSR_EMPL_INFO 및 DBA_EMPL_INFO를 가정합니다.

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
    WHEN CURRENT_ROLE() IN ('CSR_EMPL_INFO') THEN HASH(val)
    WHEN INVOKER_ROLE() IN ('DBA_EMPL_INFO') THEN val
    ELSE null
END;
Copy

정책이 테이블에 적용되면 정책은 테이블에서 생성된 모든 뷰에 상속됩니다. 사용자 지정 역할 dba_empl_info 가 이 테이블에서 생성된 뷰를 소유하면(즉, 뷰에 대한 OWNERSHIP 권한을 보유) 이 사용자 지정 역할을 보유한 사용자만 뷰를 쿼리할 때 실제 값을 볼 수 있습니다. csr_empl_info 사용자 지정 역할을 보유한 사용자는 쿼리가 테이블 또는 뷰에서 수행되는지 여부에 관계없이 항상 해시된 값을 볼 수 있습니다. 기타 모든 사용자에는 NULL 이 표시됩니다.