행 액세스 정책 사용하기

이 항목에서는 행 액세스 정책의 구현에 대해 소개합니다.

이 항목의 내용:

행 액세스 정책 구현하기

다음 하위 섹션에서는 행 액세스 정책 구현 방법에 대한 예를 제시합니다.

  • 매핑 테이블 조회를 사용하는 일반적인 행 액세스 정책을 사용합니다.

  • 쿼리 성능을 높이기 위해 기존 행 액세스 정책 하위 쿼리를 메모이제이션 가능 함수로 바꿉니다.

  • 행 액세스 정책으로 보호되는 매핑 테이블을 다른 행 액세스 정책에서 참조합니다.

예: 매핑 테이블 조회

행 액세스 정책 권한을 구성하고 테이블 및 뷰에 행 액세스 정책을 추가하는 대표적인 지침은 다음과 같습니다.

이러한 단계에서는 다음을 가정합니다.

  • 관리 방식은 중앙 집중식입니다.

    행 액세스 정책 사용 사례에 하이브리드 또는 분산형 관리 방식이 포함된 경우, 행 액세스 정책 관리하기 에서 역할 및 권한의 대표적인 배포를 참조하십시오.

  • 대표적인 사용 사례: 매핑 테이블을 사용하여 쿼리 결과 필터링 에서와 유사하게, 매핑 테이블이 필요합니다.

    다음 단계에서는 CURRENT_ROLE 컨텍스트 함수를 사용하여 사용자가 쿼리 결과에서 행을 볼 수 있는지 여부를 확인하며, 대표적인 사용 사례에서는 사용자의 이름(즉, CURRENT_USER)에 대해 중점적으로 알아봅니다.

    역할 활성화와 역할 계층 구조가 중요한 경우 정책 조건이 계정 역할에 IS_ROLE_IN_SESSION 함수를 사용하고 데이터베이스 역할에 IS_DATABASE_ROLE_IN_SESSION 함수를 사용하는 것이 좋습니다. 자세한 내용은 활성 역할 계층 구조 및 매핑 테이블 섹션을 참조하십시오.

    컨텍스트 함수가 다른 경우에도 매핑 테이블을 사용하여 행 액세스 정책을 구현하는 전체 프로세스는 동일하게 유지됩니다.

  • SECURITYADMIN 시스템 역할은 행 액세스 정책을 관리 및 구현하도록 사용자 지정 역할에 권한을 부여합니다.

    프로덕션 환경에서 낮은 권한의 사용자 지정(즉, database_admin 또는 finance_admin)을 위해 더 높은 권한의 역할(즉, SECURITYADMIN 또는 ACCOUNTADMIN)을 사용하지 않으려면, 낮은 권한의 역할에 행 액세스 정책을 관리 및 구현하기 위한 권한이 있는지 확인하십시오.

    자세한 내용은 행 액세스 정책 권한DDL 명령, 작업 및 권한 요약 섹션을 참조하십시오.

  • 행 액세스 정책으로 보호할 테이블을 만드는 단계(1단계)와 테이블에 행 액세스 정책을 추가하는 단계(5단계)가 따로 있습니다. 행 액세스 정책이 이미 존재한다고 가정하고 테이블 생성 시 테이블에 행 액세스 정책을 추가할 수 있습니다. 구문에 대한 자세한 내용은 CREATE TABLE 섹션을 참조하십시오.

예:

  1. 판매 데이터를 위한 테이블을 생성합니다.

    CREATE TABLE sales (
      customer   varchar,
      product    varchar,
      spend      decimal(20, 2),
      sale_date  date,
      region     varchar
    );
    
    Copy
  2. 대표적인 예 에서와 같이 security 스키마에서 매핑 테이블을 생성합니다. 이 테이블은 sales 테이블에서 영업 관리자가 볼 수 있는 행을 정의합니다.

    CREATE TABLE security.salesmanagerregions (
      sales_manager varchar,
      region        varchar
    );
    
    Copy
  3. 다음으로, 보안 관리자는 mapping_role 사용자 지정 역할을 생성하고 사용자 지정 역할에 SELECT 권한을 부여합니다. 이 권한을 통해 사용자 지정 역할을 보유한 사용자는 매핑 테이블을 쿼리할 수 있습니다.

    USE ROLE SECURITYADMIN;
    
    CREATE ROLE mapping_role;
    
    GRANT SELECT ON TABLE security.salesmanagerregions TO ROLE mapping_role;
    
    Copy
  4. 스키마 소유자 역할로, 다음 조건 2개가 적용된 행 액세스 정책을 생성합니다.

    • sales_executive_role 사용자 지정 역할을 보유한 사용자는 모든 행을 볼 수 있습니다.

    • sales_manager 사용자 지정 역할을 보유한 사용자는 salesmanagerregions 매핑 테이블에 따라 행을 볼 수 있습니다.

    스키마 소유자 역할에는 자동으로 CREATE ROW ACCESS POLICY 권한이 부여됨에 유의하십시오. 다른 역할이 행 액세스 정책을 생성할 수 있어야 하는 경우, 스키마 소유자 역할은 다른 역할에 CREATE ROW ACCESS 정책 권한을 부여할 수 있습니다.

    USE ROLE schema_owner_role;
    
    CREATE OR REPLACE ROW ACCESS POLICY security.sales_policy
    AS (sales_region varchar) RETURNS BOOLEAN ->
      'sales_executive_role' = CURRENT_ROLE()
        OR EXISTS (
          SELECT 1 FROM salesmanagerregions
            WHERE sales_manager = CURRENT_ROLE()
            AND region = sales_region
        )
    ;
    
    Copy

    여기서

    security.sales_policy

    security 스키마에서 행 액세스 정책의 이름입니다.

    AS (sales_region varchar)

    행 액세스 정책을 위한 서명입니다.

    서명은 매핑 테이블 속성 및 데이터 타입을 지정합니다. 반환된 값에 따라 행 액세스 정책이 추가된 테이블 또는 뷰에서 지정된 행에 대한 액세스 권한이 사용자에게 있는지 여부가 결정됩니다.

    'sales_executive_role' = CURRENT_ROLE()

    행 액세스 정책에서 body 의 시작입니다.

    sales_executive_role 사용자 지정 역할을 보유한 사용자가 데이터를 볼 수 있도록 허용하는 행 액세스 정책 식의 첫 번째 조건입니다.

    OR EXISTS (select 1 from salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region)

    하위 쿼리를 사용하는 행 액세스 정책 식의 두 번째 조건입니다.

    {salesmanagerregions} 매핑 테이블에 나열된 리전을 지정하려면 하위 쿼리에서 CURRENT_ROLE이 데이터에 대해 실행된 쿼리가 있는 sales_manager 사용자 지정 역할이어야 합니다.

    정책으로 보호되는 테이블에서 쿼리 성능을 높이려면 EXISTS 절의 매핑 테이블 조회 하위 쿼리를 메모이제이션 가능 함수 로 바꾸십시오.

    자세한 내용은 (이 항목에서) 메모이제이션 가능 함수 예 를 참조하십시오.

  5. SECURITYADMIN 시스템 역할을 사용하여 다음 문 2개를 실행합니다.

    GRANT OWNERSHIP ON ROW ACCESS POLICY security.sales_policy TO mapping_role;
    
    GRANT APPLY ON ROW ACCESS POLICY security.sales_policy TO ROLE sales_analyst_role;
    
    Copy

    이러한 두 GRANT <권한> 문의 효과는 다음과 같습니다.

    • 정책의 소유권이 SECURITYADMIN 시스템 역할에 없습니다. 쿼리 런타임 시점에는 더 많은 권한을 보유한 SECURITYADMIN 시스템 역할이 아닌 소유자 권한 으로 정책이 실행되기 때문에 Snowflake는 사용자 지정 역할에 부여된 권한을 사용합니다. 이러한 방식은 Principle of Least Privilege를 지원합니다.

    • sales_analyst_role 사용자 지정 역할은 필요에 따라 테이블에 행 액세스 정책을 추가하거나 삭제할 수 있습니다.

  6. sales 데이터 테이블의 리전 열에 행 액세스 정책을 추가(바인딩)합니다.

    USE ROLE SECURITYADMIN;
    
    ALTER TABLE sales ADD ROW ACCESS POLICY security.sales_policy ON (region);
    
    Copy
  7. 보호되는 sales 데이터에 대한 SELECT 권한을 sales_manager_role 사용자 지정 역할에 부여합니다.

    GRANT SELECT ON TABLE sales TO ROLE sales_manager_role;
    
    Copy
  8. 판매 데이터가 sales 데이터로 채워지면, 행 액세스 정책을 테스트합니다.

    USE ROLE sales_manager_role;
    SELECT product, SUM(spend)
    FROM sales
    WHERE YEAR(sale_date) = 2020
    GROUP BY product;
    
    Copy

예: 정책 하위 쿼리를 메모이제이션 가능 함수로 바꾸기

이 예에 나와 있는 단계에 따라 행 액세스 정책 조건에서 각 매핑 테이블 조회에 대해 메모이제이션 가능 함수 를 생성합니다. 각 EXISTS 절의 하위 쿼리는 테이블 이름이 각각 regions, customers, products 인 매핑 테이블 조회를 지정합니다.

CREATE OR REPLACE ROW ACCESS POLICY rap_NO_memoizable_function
  AS (region_id number, customer_id number, product_id number)
  RETURNS BOOLEAN ->
    EXISTS(SELECT 1 FROM regions WHERE id = region_id) OR
    EXISTS(SELECT 1 FROM customers WHERE id = customer_id) OR
    EXISTS(SELECT 1 FROM products WHERE id = product_id)
  ;
Copy

이후의 단계에서는 rap_admin 사용자 지정 역할이 행 액세스 정책을 생성할 수 있다고 가정합니다(즉, SCHEMA에서 CREATE ROW ACCESS POLICY 권한이 있음).

각각의 행 액세스 정책 매핑 테이블 조회를 메모이제이션 가능 함수로 바꾸려면 다음 단계를 완료하십시오.

  1. 메모이제이션 가능 함수를 관리하기 위해 functions_admin 이라는 사용자 지정 역할을 만듭니다.

    USE ROLE USERADMIN;
    
    CREATE ROLE functions_admin;
    
    Copy
  2. functions_admin 역할에 다음 권한을 부여하여 governance.functions 라는 기존 스키마에서 메모이제이션 가능 함수를 만들 수 있도록 합니다.

    USE ROLE SECURITYADMIN;
    
    GRANT USAGE ON DATABASE governance TO ROLE functions_admin;
    
    GRANT USAGE ON SCHEMA governance.functions TO ROLE functions_admin;
    
    GRANT CREATE FUNCTION ON SCHEMA governance.functions TO ROLE functions_admin;
    
    Copy
  3. 행 액세스 정책의 각 EXISTS 하위 쿼리 절에 대해 메모이제이션 가능 함수를 만듭니다. 각각의 메모이제이션 가능 함수 정의는 동일한 형식을 취합니다. 간결성을 위해 함수 예는 하나만 표시됩니다.

    USE ROLE functions_admin;
    
    USE SCHEMA governance.functions;
    
    CREATE OR REPLACE function allowed_regions()
      RETURNS array
      memoizable
      AS 'SELECT ARRAY_AGG(id) FROM regions';
    
    Copy
  4. CREATE ROW ACCESS POLICY 문을 사용하여 하위 쿼리를 메모이제이션 가능 함수로 바꾸는 새로운 행 액세스 정책을 정의합니다.

    새로운 행 액세스 정책을 사용하면 정책에서 메모이제이션 가능 함수를 사용하거나 사용하지 않을 때 보호된 테이블에서 쿼리를 테스트하여 정책 조건에 메모이제이션 가능 함수를 사용할 때 성능에 미치는 영향을 정량화할 수 있습니다.

    USE ROLE rap_admin;
    
    CREATE OR REPLACE ROW ACCESS POLICY rap_with_memoizable_function
      AS (region_id number, customer_id number, product_id number)
      RETURNS BOOLEAN ->
        ARRAY_CONTAINS(region_id, allowed_regions()) OR
        ARRAY_CONTAINS(customer_id, allowed_customers()) OR
        ARRAY_CONTAINS(product_id, allowed_products())
      ;
    
    Copy

예: 행 액세스 정책으로 매핑 테이블 보호하기

이 예에서는 행 액세스 정책으로 보호되는 매핑 테이블을 다른 행 액세스 정책에서 참조하는 방법을 보여줍니다. 매핑 테이블을 보호하는 행 액세스 정책은 역할 계층 구조를 설명하는 IS_ROLE_IN_SESSION 컨텍스트 함수를 호출합니다. 다른 행 액세스 정책은 사용자가 쿼리하는 테이블을 보호합니다. 이 행 액세스 정책에서는 하위 쿼리를 사용하여 매핑 테이블 조회를 수행합니다. 예:

  1. 지리적 판매 리전을 기반으로 허용되는 역할을 정의하는 매핑 테이블을 만들고 테이블에 데이터를 삽입합니다.

    CREATE OR REPLACE TABLE sales.tables.regional_managers (
      allowed_regions varchar
      allowed_roles varchar
    );
    
    Copy
    INSERT INTO sales.tables.regional_managers
    (allowed_regions, allowed_roles)
    VALUES
    ('na', 'NA_MANAGER'),
    ('eu', 'EU_MANAGER'),
    ('apac', 'APAC_MANAGER');
    
    Copy
  2. 매핑 테이블에서 ALLOWED_ROLES 열을 지정하는 행 액세스 정책을 만듭니다.

    CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_exempt
    AS (allowed_roles varchar) RETURNS BOOLEAN ->
    IS_ROLE_IN_SESSION(allowed_roles);
    
    Copy
  3. ALTER TABLE 문을 사용하여 매핑 테이블에 대한 행 액세스 정책을 추가합니다.

    ALTER TABLE sales.tables.regional_managers
      ADD ROW ACCESS POLICY governance.policies.rap_map_exempt
      ON (allowed_roles);
    
    Copy
  4. 보호된 매핑 테이블에서 매핑 테이블 조회를 지정하는 새 행 액세스 정책을 생성합니다.

     CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_lookup
     AS (allowed_regions varchar) RETURNS BOOLEAN ->
     EXISTS (
       SELECT * FROM sales.tables.regional_managers
       WHERE
         REGION = allowed_regions
    );
    
    Copy
  5. ALTER TABLE 문을 사용하여 sales.tables.data 라는 테이블에 governance.policies.rap_map_lookup 이라는 행 액세스 정책을 추가합니다.

    ALTER TABLE sales.tables.data
      ADD ROW ACCESS POLICY governance.policies.rap_map_lookup
      ON (allowed_regions);
    
    Copy
  6. 이러한 역할을 가진 사용자가 보호된 데이터를 쿼리할 수 있도록 매핑 테이블의 역할에 권한을 부여합니다. 예를 들어 다음과 같은 권한 부여는 na_manager 사용자 지정 역할에 대한 것입니다.

    USE ROLE SECURITYADMIN;
    GRANT USAGE ON DATABASE sales TO ROLE na_manager;
    GRANT USAGE ON SCHEMA sales.tables TO ROLE na_manager;
    GRANT SELECT ON TABLE sales.tables.regional_managers TO ROLE na_manager;
    GRANT SELECT ON TABLE sales.tables.data TO ROLE na_manager;
    
    Copy

    필요에 따라 매핑 테이블의 각 역할에 대해 이 단계의 명령을 반복합니다.