보안 뷰 관련 작업하기

이 항목에서는 뷰 및 구체화된 뷰를 보안 항목으로 정의하기 위한 개념과 구문에 대해 설명합니다.

이 항목의 내용:

보안 뷰의 정의

보안 뷰를 사용해야 하는 이유가 무엇입니까?

  • 비보안 뷰의 경우 내부 최적화로 데이터가 간접적으로 노출될 수 있습니다.

    뷰를 위한 일부 내부 최적화에서는 뷰의 기본 테이블에 포함된 기본 데이터에 액세스해야 합니다. 이러한 액세스를 통해 사용자 정의 함수 또는 기타 프로그래밍 방식과 같은 사용자 코드를 통해 뷰 사용자에게 숨겨진 데이터가 노출될 수 있습니다. 보안 뷰에서는 이러한 최적화가 사용되지 않으므로 사용자가 기본 데이터에 액세스할 수 없습니다.

  • 비보안 뷰의 경우 뷰 정의가 다른 사용자에게 표시됩니다.

    기본적으로, 뷰 정의 또는 텍스트라고도 하는 표준 뷰를 생성하기 위해 사용되는 쿼리 식은 다양한 명령과 인터페이스를 통해 사용자에게 표시됩니다. 자세한 내용은 이 항목의 보안 뷰와 상호 작용하기 섹션을 참조하십시오.

    보안 또는 개인정보보호를 위해 기본 테이블이나 뷰에 대한 내부 구조 세부 정보를 노출하고 싶지 않을 수 있습니다. 보안 뷰를 사용하면 뷰 정의 및 세부 정보가 승인된 사용자(즉, 뷰 소유자 역할이 부여된 사용자)에게만 표시됩니다.

언제 보안 뷰를 사용해야 합니까?

데이터의 개인정보를 보호하기 위해 뷰가 특별하게 지정된 경우(즉, 기본 테이블의 모든 사용자에게 노출되지 않아야 하는 민감한 데이터에 대한 액세스를 제한하기 위해) 뷰를 보안으로 정의해야 합니다.

사용자가 기본 데이터의 표현 방식을 이해할 필요가 없는 쿼리를 단순화하기 위해 생성되는 뷰와 같이 쿼리의 편의성을 위해서만 정의된 뷰에는 보안 보기를 사용하지 않아야 합니다. 보안 뷰는 비보안 뷰보다 느리게 실행할 수 있습니다.

보안 뷰의 사용 여부를 결정하는 경우에는 뷰의 목적을 고려하고 데이터 개인정보보호/보안과 쿼리 성능 사이의 균형을 고려해야 합니다.

비보안 뷰를 사용하여 데이터를 노출하려면 어떻게 해야 합니까?

다음 위젯 예시를 사용할 때 빨간색 위젯에만 액세스할 수 있는 사용자에 대해 생각해 보십시오. 사용자가 보라색 위젯이 있는지를 확인하고 다음 쿼리를 실행하는 상황을 가정해 보겠습니다.

SELECT *
    FROM widgets_view
    WHERE 1/iff(color = 'Purple', 0, 1) = 1;
Copy

보라색 위젯이 있는 경우 IFF() 식은 0을 반환합니다. 그런 다음, 0으로 나누기 오류로 인해 나누기 연산이 실패하여 사용자가 하나 이상의 보라색 위젯이 있다고 추론할 수 있습니다.

보안 뷰 만들기

보안 뷰는 뷰에 대한 표준 DDL와 함께 SECURE 키워드를 사용하여 정의됩니다.

보안 뷰와 상호 작용하기

보안 뷰의 정의 보기

보안 뷰의 정의는 승인된 사용자(즉, 뷰 소유자 역할이 부여된 사용자)에게만 노출됩니다. 권한이 없는 사용자가 다음 명령이나 인터페이스를 사용하는 경우에는 뷰 정의가 표시되지 않습니다.

그러나 SNOWFLAKE 데이터베이스 또는 다른 공유 데이터베이스에 대한 IMPORTED PRIVILEGES 권한이 부여된 사용자는 VIEWS Account Usage 뷰를 통해 보안 뷰 정의에 액세스할 수 있습니다.

ACCOUNTADMIN 역할 또는 SNOWFLAKE.OBJECT_VIEWER 데이터베이스 역할이 부여된 사용자는 이 뷰를 통해 보안 뷰 정의도 볼 수 있습니다. 기본 설정된 최소 권한 액세스 수단은 SNOWFLAKE.OBJECT_VIEWER 데이터베이스 역할입니다.

뷰가 보안인지 결정하기

구체화되지 않은 뷰의 경우 Information Schema 및 Account Usage 뷰의 IS_SECURE 열에서 뷰의 보안 여부를 확인할 수 있습니다. 예를 들어, mydb 데이터베이스에서 MYVIEW 라는 뷰의 경우:

Information Schema:

select table_catalog, table_schema, table_name, is_secure
    from mydb.information_schema.views
    where table_name = 'MYVIEW';
Copy

Account Usage:

select table_catalog, table_schema, table_name, is_secure
    from snowflake.account_usage.views
    where table_name = 'MYVIEW';
Copy

(INFORMATION_SCHEMA 뷰와 ACCOUNT_USAGE 뷰의 차이점에 대한 일반적인 정보는 Account Usage와 Information Schema의 차이점 섹션을 참조하십시오.)

또는 SHOW VIEWS 명령을 사용하여 유사한 정보를 확인할 수 있습니다(뷰의 이름에서는 대/소문자를 구분하지 않음).

SHOW VIEWS LIKE 'myview';
Copy

구체화된 뷰에서는 SHOW MATERIALIZED VIEWS 명령을 사용하여 뷰의 보안 여부를 확인할 수 있습니다. 예:

SHOW MATERIALIZED VIEWS LIKE 'my_mv';
Copy

쿼리 프로필에서 보안 뷰 세부 정보 보기

보안 뷰의 내부는 웹 인터페이스의 쿼리 프로필 에 노출되지 않습니다. 소유자가 아닌 사용자가 소유자의 쿼리 프로필에 액세스할 수 있기 때문에 이러한 규칙은 보안 뷰의 소유자에게도 적용됩니다.

Snowflake액세스 제어를 통해 보안 뷰 사용하기

뷰의 보안성은 상황에 맞는 CURRENT_ROLECURRENT_USER 함수를 사용하여 Snowflake 사용자 및 역할과 통합할 수 있습니다. 역할을 사용하여 테이블 행에 대한 액세스를 제어하는 예시는 다음과 같습니다. 데이터(widgets)가 포함된 테이블뿐만 아니라, 이 예시에서는 액세스 테이블(widget_access_rules)을 사용하여 데이터 테이블의 각 행에 대한 액세스 권한이 있는 역할을 추적합니다.

CREATE TABLE widgets (
    id NUMBER(38,0) DEFAULT widget_id_sequence.nextval, 
    name VARCHAR,
    color VARCHAR,
    price NUMBER(38,0),
    created_on TIMESTAMP_LTZ(9));
CREATE TABLE widget_access_rules (
    widget_id NUMBER(38,0),
    role_name VARCHAR);
CREATE OR REPLACE SECURE VIEW widgets_view AS
    SELECT w.*
        FROM widgets AS w
        WHERE w.id IN (SELECT widget_id
                           FROM widget_access_rules AS a
                           WHERE upper(role_name) = CURRENT_ROLE()
                      )
    ;
Copy

WHERE 절은 각 역할이 어떤 위젯을 볼 수 있는지를 제한합니다.

빨간색 위젯에만 액세스할 수 있는 사용자가 이전에 표시된 쿼리를 실행한다고 가정해 보겠습니다.

SELECT *
    FROM widgets_view
    WHERE 1/iff(color = 'Purple', 0, 1) = 1;
Copy

보안 뷰의 WHERE 절은 사용자 쿼리의 WHERE 절에 앞서 실행됩니다. 보라색 위젯은 뷰에 의해 제외되므로 사용자 쿼리에서는 0으로 나누기 오류가 절대로 발생하지 않습니다.

뷰가 안전하지 않은 경우에는 Snowflake 최적화 프로그램이 WHERE 절에서 조건자를 다시 정렬할 수 있습니다. 그러면 사용자 쿼리의 조건자가 먼저 실행되어 0으로 나누기 오류가 발생할 수 있게 됩니다.

보안 뷰 사용 모범 사례

보안 뷰를 사용하면 뷰에 의해 필터링된 테이블 행의 데이터가 사용자에게 노출되는 것을 방지할 수 있습니다. 그러나 뷰가 신중하게 구성되지 않은 경우에는 실수로 데이터 소유자가 기본 데이터 관련 정보를 노출할 수 있습니다. 이 섹션에서는 방지해야 할 몇 가지 가능성이 있는 위험에 대해 설명합니다.

이러한 위험을 설명하기 위해 이 섹션에서는 이 항목의 이전 예에서 정의된 샘플 widgets 테이블과 뷰를 사용합니다.

시퀀스에 따라 생성된 열

대체 키를 생성하는 일반적인 방법은 시퀀스 또는 자동 증가 열을 사용하는 것입니다. 모든 기본 데이터에 액세스할 수 없는 사용자에게 이러한 키가 노출되면 사용자는 기본 데이터 배포의 세부 정보를 추측할 수 있습니다. 예를 들어, widgets_view 에서는 ID 열이 노출됩니다. 시퀀스에서 ID가 생성되면 widgets_view 사용자는 사용자가 액세스할 수 있는 두 위젯의 생성 타임스탬프 사이에서 총 몇 개의 위젯이 생성되었는지를 추측할 수 있습니다. 다음 쿼리 및 결과를 생각해 보십시오.

select * from widgets_view order by created_on;

------+-----------------------+-------+-------+-------------------------------+
  ID  |         NAME          | COLOR | PRICE |          CREATED_ON           |
------+-----------------------+-------+-------+-------------------------------+
...
 315  | Small round widget    | Red   | 1     | 2017-01-07 15:22:14.810 -0700 |
 1455 | Small cylinder widget | Blue  | 2     | 2017-01-15 03:00:12.106 -0700 |
...
Copy

결과에 따라, 사용자는 1월 7일에서 1월 15일 사이에 1139개의 위젯(1455 - 315)이 생성된 것으로 추측할 수 있습니다. 이러한 정보가 매우 민감하여 뷰 사용자에게 노출되지 않아야 하는 경우에는 다음 대안 중 하나를 사용할 수 있습니다.

  • 시퀀스에 따라 생성된 열을 뷰의 일부로 노출하지 않습니다.

  • 무작위 식별자(예: UUID_STRING 에 의해 생성된 식별자)를 시퀀스에 따라 생성된 값 대신 사용합니다.

  • 프로그래밍 방식으로 식별자를 난독화합니다.

스캔된 데이터 크기

보안 뷰가 포함된 쿼리의 경우 Snowflake는 스캔된 데이터의 양(바이트 또는 마이크로 파티션 단위) 또는 전체 데이터 양을 노출하지 않습니다. 이는 데이터의 하위 세트에만 액세스할 수 있는 사용자로부터 정보를 보호하기 위한 것입니다. 그러나 사용자는 쿼리의 성능 특성에 따라 여전히 기본 데이터의 양을 관찰할 수 있습니다. 예를 들어, 실행 시간이 2배인 쿼리는 2배의 데이터를 처리할 수 있습니다. 이러한 관찰은 근사치이지만, 일부 경우에는 이러한 수준의 정보가 노출되는 것도 바람직하지 않을 수 있습니다.

그러한 경우에는 기본 데이터에 대한 뷰를 사용자에게 노출하는 대신, 사용자/역할별로 데이터를 구체화하는 것이 가장 좋습니다. widgets 테이블의 경우 위젯에 대한 액세스 권한이 있는 각 역할에 대해 테이블이 생성되며, 여기에는 해당 역할이 액세스할 수 있는 위젯만 포함되고 역할에는 해당 테이블에 대한 액세스 권한이 부여됩니다. 이렇게 하는 것은 단일 뷰를 사용하는 것보다 훨씬 번거롭지만 매우 높은 수준의 보안이 요구되는 경우에 적합합니다.

보안 뷰 및 데이터 공유

Secure Data Sharing 과 함께 보안 뷰를 사용하는 경우에는 CURRENT_ACCOUNT 함수를 사용하여 특정 계정의 사용자에게 기본 테이블의 행에 대한 액세스 권한을 부여합니다.

참고

다른 Snowflake 계정과 공유할 보안 뷰와 함께 CURRENT_ROLECURRENT_USER 함수를 사용할 때 Snowflake는 이러한 함수에 대해 NULL 값을 반환합니다. 왜냐하면 공유되는 데이터의 소유자가 일반적으로 뷰가 공유되는 계정의 사용자 또는 역할을 관리하지 않기 때문입니다.