데이터 원본 및 통합 문서에 대한 RLS 최상의 방법

Tableau에서 RLS(행 수준 보안)는 통합 문서에서 특정 사용자가 볼 수 있는 데이터 행을 제한합니다. 이것은 콘텐츠 및 기능에 대한 액세스를 제어하는 Tableau 사용 권한과 다릅니다. 예를 들어 사용 권한은 사용자가 통합 문서에 댓글을 달거나 통합 문서를 편집할 수 있는지 여부를 제어하지만 행 수준 보안은 동일한 대시보드를 보는 두 사용자가 각 사용자에게 보도록 허용된 데이터만 볼 수 있게 합니다.

Tableau에서는 여러 가지 방법으로 RLS를 구현할 수 있습니다. 예를 들어 데이터 원본 또는 통합 문서 수준에서 RLS를 설정하거나 연결 수준에서 가상 연결과 데이터 정책(Data Management 필요)을 사용하여 RLS를 설정할 수 있습니다. 대안에 대한 자세한 내용은 Tableau의 행 수준 보안 옵션에 대한 개요를 참조하십시오.

참고: 이 항목에서는 데이터 원본 및 통합 문서에 대한 RLS 최상의 방법을 중점적으로 다룹니다. 이 항목에 설명되어 있는 개념의 보다 심층적인 예제를 보려면 자격 테이블을 사용하는 행 수준 보안을 위한 최상의 방법(영문)(링크가 새 창에서 열림) 백서나 Tableau and Behold 블로그에서 Tableau의 행 수준 보안을 위해 데이터베이스를 설정하는 방법(영문)(링크가 새 창에서 열림)을 참조하십시오.

RLS 워크플로우

라이브 연결 및 다중 테이블 추출의 경우 기본적인 RLS 워크플로우는 다음과 같습니다.

  1. 사용자는 Tableau Server 또는 Tableau Cloud에 로그인함으로써 식별됩니다.
    • 여기에는 사용자별로 고유한 사용자 이름과 보안 SSO(Single Sign-On)가 필요합니다.
    • Active Directory, LDAP 또는 Tableau REST API를 사용하여 사용자 이름을 동기화하고 사용 권한을 설정할 수 있습니다.
  2. 사용자의 데이터 자격 집합이 모든 가능한 데이터 자격에서 검색됩니다.
    • 이렇게 하려면 자격을 Tableau 사용자 이름에 연결할 수 있는 데이터 구조가 필요합니다.
  3. 데이터는 해당 사용자의 자격을 사용하여 필터링됩니다.
    • 이렇게 하려면 계산된 필드에서 사용자 함수를 사용해야 하는 경우가 많습니다.
  4. 게시되고 필터링된 데이터가 콘텐츠를 작성하는 데 사용됩니다.
    • 게시된 데이터 원본(내장된 데이터 원본 아님)과 데이터 원본 필터를 함께 사용하여 통합 문서를 다운로드하거나 웹 편집하여 RLS를 수정할 수 없게 합니다.

조인, 계산된 필드 및 필터를 설정하는 방법은 데이터 구조와 사용자 관리 방식에 따라 달라집니다.

자격 테이블

데이터를 필터링하는 데 사용할 수 있는 모든 고유한 특성 조합이 자격입니다. 일반적으로 자격 자체를 지정하고 해당 자격을 사용자 또는 사용자 역할에 매핑하기 위한 별도의 테이블이 있습니다. 조인은 비용이 많이 드는 작업이기 때문에 성능 관점에서 비정규화가 권장됩니다.

사용자 또는 역할에 매핑된 자격으로 구성되는 자격 뷰는 데이터와 조인됩니다. 그런 다음 사용자 기반 데이터 원본 필터가 적용되며, 이 필터는 관련 사용자의 자격, 즉 적절한 데이터 행만 가져오는 WHERE 절로 작동합니다. (쿼리가 처리될 때 데이터 중복을 최소화하기 위해 쿼리 최적화를 통해 조인 이전에 필터링이 실행되도록 해야 합니다. 자세한 내용은 성능 및 작업 처리 순서를 참조하십시오.)

자격 테이블 모델

일반적으로, 자격을 나타내기 위한 두 가지 모델이 있습니다.

가장 깊은 세부 수준까지 전체 매핑

  • 자격이 모든 열에 대해 완전하게 정의됩니다.
  • 매핑 테이블에 사용자가 가질 수 있는 자격마다 하나씩 행이 있습니다.
  • 이 모델에 필요한 조인 절 수가 더 적습니다.

스파스 자격

  • 자격은 모든 계층 수준에서 정의되며, "모든" 상태를 나타내는 데 NULL이 사용됩니다.
  • 매핑 테이블에 자격 계층의 특정 수준에 대한 행 하나가 있으므로 계층에서 높은 수준에 있는 사용자에 대한 자격 행의 수가 크게 줄어듭니다.
  • 이 모델에는 더 복잡한 조인 및 필터가 필요합니다.

사용자 및 역할

자격의 조합은 일반적으로 역할로 나타나며, 이러한 역할은 다대다 매핑 테이블에서 사용자에게 연결됩니다. 이를 통해 역할과 해당 자격의 기록을 계속 유지하면서 역할에서 쉽게 사용자를 변경하거나 제거할 수 있습니다.

또한, 역할 테이블을 조인하는 것과 달리 자격에 사용자를 직접 할당하는 다대다 매핑 테이블을 만들 수 있습니다. 이렇게 하면 테이블에서 더 직접적으로 값을 매핑해야 하지만 조인이 제거됩니다.

참고: Tableau Desktop에서 사용자 함수를 활용하려면 역할 또는 자격과 연결된 사용자 값이 Tableau 사이트에서 사용자 이름 또는 전체 이름과 일치해야 합니다.

조인

자격을 나타내는 데 사용되는 모델과 관계없이 모든 자격 및 매핑 테이블을 비정규화된 단일 자격 뷰로 조인하는 것이 좋습니다. 처음에는 이로 인해 자격의 버전이 “폭증”(상당히 중복됨)하지만 사용자에 대한 데이터 원본 필터가 이를 축소합니다. 추출을 사용할 예정인 경우에도 이 뷰가 필요합니다.

가장 깊은 세부 수준 방법은 모든 것이 계층적일 때 성능을 향상시킬 수 있습니다. 계층의 가장 깊은 수준에서 단일 조인만 수행하면 됩니다. 이 방법은 가장 낮은 수준의 모든 특성이 고유한 경우에만 작동합니다. 중복의 가능성이 있는 경우(예: 둘 이상의 지역에 Central 하위 지역이 있는 경우), 고유 키 값의 효과를 얻으려면 모든 열에서 조인을 수행해야 합니다.

실제 세부 정보와 해당 성능 특성은 데이터 시스템에 따라 달라지며 테스트가 필요합니다. 예를 들어 단일 키를 사용하면 한 열에서만 조인이 실행되므로 성능이 향상될 수 있지만 다른 요소를 고려할 경우 모든 열을 올바르게 인덱싱하면 동일한 성능을 얻을 수 있습니다.

행 수준 보안 구현

가장 깊은 세부 수준

매핑된 자격의 비정규화된 뷰를 만든 후 Tableau 데이터 연결 대화 상자에서 뷰와 데이터 사이에 내부 조인을 설정합니다. 데이터는 전통적인 스타 스키마 상태를 유지할 수 있습니다. 또한, 차원 및 팩트 테이블을 두 개의 뷰로 구체화할 수 있습니다. 다중 테이블 추출은 조인을 일치시키는 추출 테이블을 작성하므로 두 뷰를 만들어 결과 추출을 간소화합니다. SQL은 다음과 같은 기본 패턴을 따릅니다.

SELECT * 
FROM data d INNER JOIN entitlements e ON
d.attribute_a = e.attribute_a AND 
d.attribute_b = e.attribute_b AND ... 
WHERE e.username = USERNAME()

스파스 자격

자격이 스파스 자격 모델과 더 유사한 경우 NULL 값 때문에 데이터를 자격에 조인하는 사용자 지정 SQL이 조금 더 복잡해질 수 있습니다. 개념적으로는 다음과 같은 형태입니다. 

SELECT *
FROM data d 
INNER JOIN entitlements e ON
(e.region_id = d.region_id OR ISNULL(e.region_id) AND
(e.sub_region_id = d.sub_region_id OR ISNULL(e.sub_region_id) AND
(e.country_id = d.country_id OR ISNULL(e.country_id)

사용자 지정 SQL을 사용하지 않고 Tableau Desktop에서 크로스 조인과 추가 필터를 사용하여 이 작업을 수행할 수 있습니다. 조인 대화 상자의 양쪽에서 간단히 정수 1로 구성되고 이들을 동등하게 설정하는 조인 계산을 만듭니다. 이렇게 하면 데이터 테이블의 모든 행이 자격 테이블의 모든 행과 조인됩니다.

그런 다음 계층의 수준을 고려하는 계산(또는 개별 계산)이 필요합니다. 예를 들어 [region_id] = [region_id (Entitlements View)] OR ISNULL([region_id (Entitlements View)] 형식을 따르는 여러 계산을 사용할 수 있습니다.

또는 다음과 같이 모든 수준에 대한 조합된 계산 하나를 사용할 수 있습니다.

([region_id] = [region_id (Entitlements View)] OR ISNULL([region_id (Entitlements View)])
AND
([sub_region_id] = [sub_region_id (Entitlements View)] OR ISNULL([sub_region_id (Entitlements View)])
AND
([country_id] = [country_id (Entitlements View)] OR ISNULL([country_id (Entitlements View)])

ISNULL 함수는 모든 자격 열을 다른 열의 모든 항목에 일치시킵니다. RLS에서는 항상 이러한 계산을 데이터 원본 필터로 추가해야 합니다.

데이터 원본 필터

두 접근 방식 모두에서 자격이 데이터와 올바르게 조인된 후 특정 사용자에 대한 데이터를 제한하는 필터를 설정해야 합니다. 사용자 함수를 사용하여 계산된 필드를 만들어야 합니다. 예를 들어 Username(사용자 이름) 필드에 나열된 사용자가 Tableau 사이트에 로그인한 사용자의 사용자 이름과 같은지 여부에 대한 간단한 부울 비교는 [Username] = USERNAME()입니다.

이 계산을 데이터 원본 필터(TRUE를 선택한 상태)로 사용해야 합니다.

데이터 원본이 내장되어 있고 사용자에게 통합 문서를 웹 편집하거나 다운로드하는 사용 권한이 있는 경우 RLS가 존재하지 않으며, 이는 이를 적용하는 필터를 쉽게 제거할 수 있기 때문입니다. Tableau 데이터 원본은 통합 문서에 내장된 상태로 두는 것이 아니라 별도로 게시해야 합니다.

가장 깊은 세부 수준의 모든 액세스

또한, 조직 내에 두 가지 액세스 수준, 즉 모든 것을 볼 수 있는 사람("모든 액세스")과 일부 합리적으로 정의 가능한 자격 하위 집합이 있는 사람이 있는 일반적인 시나리오가 있습니다. 이 시나리오는 데이터를 호스팅하는 조직은 모든 것을 볼 수 있지만 클라이언트는 자신의 데이터만 볼 수 있는 내장된 응용 프로그램에서 일반적인 볼 수 있습니다. 이 경우 다른 모든 사용자에 대해 가장 깊은 세부 수준을 유지하면서 “모든 액세스”가 있는 사용자에게 전체 데이터를 반환하는 방법이 필요합니다.

이 기법의 경우 Tableau 그룹을 사용하여 조인 조건의 계산을 통해 재정의를 만듭니다.

  1. 모든 데이터를 볼 수 있는 사용자의 그룹을 만듭니다(All Access라고 함). 
  2. 팩트 뷰에서 조인 조건 두 개가 있는 왼쪽 조인을 만듭니다.
    • 첫 번째 조인 조건은 가장 깊은 세부 수준을 나타내는 열에 기반해야 합니다.
    • 두 번째 조인 조건은 두 계산이어야 합니다.
      • 계산의 좌변(팩트 뷰)에는 True를 입력합니다.
      • 우변(자격 뷰)의 계산은 IF ISMEMBEROF('All Access') THEN False ELSE True END여야 합니다.
  3. 시트에서 [Username] = USERNAME() OR ISMEMBEROF(['All Access'] ([Entitlements View)])로 구조화된 계산을 만듭니다.
  4. 사용자 이름 계산에 대한 데이터 원본 필터를 만듭니다.

사용자가 All Access 그룹의 멤버인 경우 조인은 True = False에 대한 왼쪽 조인이 됩니다. 이것은 자격 뷰에 일치 항목이 전혀 없다는 의미이므로 전체 팩트 뷰가 자격 뷰의 열에 대해 NULL로 반환됩니다(0 중복). 사용자가 All Access 그룹에 속하지 않는 경우 True = True 조인 조건은 아무것도 변경하지 않으며 조인이 예상대로 작동합니다.

데이터 원본 필터로 사용되는 사용자 계산은 그룹 재정의가 작동하는 경우 모든 행에 대해 true이며, 그렇지 않은 경우 계층에서 사용자만 가장 깊은 세부 수준까지 필터링됩니다.

성능 및 작업 처리 순서

Tableau Desktop, Tableau Server 또는 Tableau Cloud에서 비주얼리제이션을 볼 경우 Tableau는 RDBMS로 최적화된 쿼리를 전송하고, RDBMS는 쿼리를 처리한 다음 결과 데이터로 비주얼리제이션을 렌더링할 수 있도록 결과를 Tableau로 다시 전송합니다. 조인, 계산 및 필터가 실행되는 경우 연산 순서는 쿼리 최적화기와 쿼리 실행 방식에 따라 다릅니다.

라이브 연결

Tableau에서 데이터 원본에 대한 라이브 연결을 사용하는 경우 쿼리 실행 성능은 들어오는 SQL을 데이터를 검색하기 위한 효율적인 계획으로 변환하는 쿼리 최적화기에 따라 결정됩니다.

쿼리를 처리할 수 있는 방법에는 두 가지가 있습니다.

  1. 자격 행을 사용자에 대해 필터링한 다음 팩트 테이블에 조인
  2. 자격을 팩트 테이블에 조인한 다음 사용자의 행에 대해 필터링

이상적인 상황에서 쿼리 최적화기는 데이터베이스가 필터링한 다음 조인하는 방식으로 쿼리를 처리하게 합니다. 사용자에게 모든 항목에 대한 자격이 있는 경우 처리되는 최대 행 수가 데이터 테이블의 행 수라는 의미입니다.

데이터베이스가 조인한 다음 필터링하는 방식으로 쿼리를 처리하는 경우 데이터가 중복될 수 있습니다. 처리되는 최대 행 수는 특정 행을 볼 수 있는 자격이 있는 사용자 수와 데이터 테이블의 각 행을 곱한 값이 됩니다.

이 두 번째 시나리오가 발생할 경우 명백한 것은, 쿼리를 마치는 데 오랜 시간이 걸리거나, 오류가 발생하거나, 데이터베이스에 성능 문제가 나타난다는 것입니다. 총 데이터 볼륨이 기하급수적으로 확대되므로 백엔드에서 비정상적인 시스템 부하가 발생할 수 있습니다.

추출

Tableau의 데이터 원본이 라이브 연결인 경우 Tableau는 특정 비주얼리제이션이나 대시보드를 렌더링하는 데 필요한 모든 쿼리를 RDBMS로 전송합니다. 데이터 원본이 추출인 경우 기초 데이터 원본에서 데이터를 쿼리하는 프로세스가 추출을 만들고 새로 고칠 때에만 발생합니다. 비주얼리제이션에 대한 모든 개별 쿼리는 추출 파일에서 추출 엔진에 의해 처리됩니다.

단일 테이블 추출을 작성할 때 동일한 연산 순서 문제가 존재합니다. 하지만 “폭증”이 기초 데이터 원본과 결과 추출 자체 내에서 모두 발생합니다.

추출 관련 고려 사항

Tableau 2018.3부터 데이터 엔진은 다중 테이블 추출을 만들 수 있고 위에 설명된 대로 RLS를 구현할 수 있습니다. 다중 테이블 추출을 사용하면 조인을 구체화하지 않고 다대다 관계를 사용하여 추출을 생성하므로 시간이 단축됩니다.

추출은 데이터 개체자격 개체를 사용하여 작성해야 합니다. 이것이 추출의 가장 단순한 저장소이며 최고의 성능을 나타냅니다.

  • 데이터 개체는 팩트와 필요한 차원 테이블의 비정규화된 조합을 나타내는 테이블, 뷰 또는 사용자 지정 SQL 쿼리입니다.
  • 자격 개체는 가장 세부적인 수준에서 데이터를 필터링하는 데 필요한 자격으로 구성된 비정규화된 테이블, 뷰 또는 사용자 지정 SQL 쿼리이며, 여기에는 다음이 필요합니다.
    • Tableau Server 또는 Tableau Cloud에서 정확한 사용자 이름과 일치하는 사용자 이름에 대한 열
    • 데이터 개체에 대한 가장 세부적인 자격 각각에 대한 행

이 형식은 위 가장 깊은 세부 수준 방법에 설명되어 있습니다. 다중 테이블 추출은 동일한 방법을 사용하지만 두 데이터 개체만 조인되고 모든 필드 관련 필터링은 개체 내에서 이미 적용된다는 것에 주의해야 합니다.

다중 테이블 추출은 추출 필터를 사용하지 않기 때문에 데이터 원본에서 연결하는 뷰 또는 테이블에서 필터링하거나 Tableau 데이터 연결 대화 상자에서 사용자 지정 SQL 개체에 필터를 정의할 수 있습니다.

참고: 라이브 연결과 마찬가지로, 데이터 원본이 내장되어 있고 사용자에게 통합 문서를 웹 편집하거나 다운로드하는 사용 권한이 있는 경우 RLS가 존재하지 않으며, 이는 이를 적용하는 필터를 쉽게 제거할 수 있기 때문입니다. 추출은 통합 문서에 내장된 상태로 두는 것이 아니라 별도로 게시해야 합니다.

단일 테이블 추출

다음 방법은 Tableau 2018.3 이전 버전을 사용하는 경우에만 권장됩니다. 사용할 수 있는 경우 다중 테이블 추출을 사용하는 것이 좋습니다.

단일 테이블 추출은 Tableau 데이터 원본을 구성할 때 작성한 모든 조인을 구체화하고 단일 쿼리를 통해 모든 항목을 단일 테이블로 저장하므로, 결과가 추출 파일의 단일 테이블로 변환됩니다. 이 비정규화는 다대다 관계로 인해 둘 이상의 자격 또는 사용자에게 할당된 모든 행이 중복되기 때문에 대량의 데이터 중복이 발생할 위험을 수반합니다.

이 중복을 방지하려면:

  1. 해당 자격에 대한 사용자 이름을 포함하는 Security Users(보안 사용자) 필드를 만듭니다.
    • 예를 들어 값은 “bhowell|mosterheld|rdugger”일 수 있습니다.
  2. Tableau 내에서 CONTAINS() 함수를 사용하여 개별 사용자를 정확하게 식별합니다.
    • 예를 들어 CONTAINS([Security Users Field], USERNAME())를 사용할 수 있습니다.

이 방법에는 명백하게 몇 가지 주의 사항이 있습니다. 이렇게 하려면 여러 행의 자격을 SQL을 사용하여 올바르게 분리된 단일 열로 변환해야 하며 해당 열은 매우 많은 문자를 포함할 수 있습니다. 부분 일치가 문제가 될 수 있으며 ID 자체에서 절대 사용되지 않는 구분 기호를 사용해야 합니다. Tableau 데이터 엔진 내에서는 성능이 뛰어나지만 문자열 계산이기 때문에 대부분의 데이터베이스에서 매우 느립니다. 이 때문에 라이브 연결로 전환하는 기능이 제한됩니다.

또한, “역할” 또는 자격 수준마다 다른 추출을 가져올 수 있으므로 해당 사용자 또는 수준에 적합한 데이터만 추출에 포함되지만 이렇게 하려면 해당하는 사용 권한에 따른 처리가 필요하며 Tableau Server 내에서 일반적으로 API를 통해 템플릿 게시를 활용해야 합니다.

데이터베이스의 기본 제공 행 수준 보안 사용

많은 데이터베이스에는 RLS를 위한 메커니즘이 기본적으로 포함되어 있습니다. 조직에서 이미 데이터베이스에 행 수준 보안을 구축한 경우라면 기존 RLS를 활용할 수 있습니다. 기본 제공 RLS 모델을 구현하는 것이 항상 Tableau로 작성하는 것보다 쉽거나 나은 것은 아니라는 점을 염두에 두십시오. 이러한 기법은 일반적으로 조직이 이미 이러한 기술에 투자했으며 해당 투자를 활용하고 싶은 경우에 사용됩니다. 기본 제공 RLS를 사용할 경우 주요 이점은 관리자가 자신의 데이터 보안 정책을 한 곳, 즉 데이터베이스에서 구현하고 제어할 수 있다는 점입니다. 자세한 내용은 데이터베이스의 행 수준 보안을 참조하십시오.

피드백을 제공해 주셔서 감사합니다!귀하의 피드백이 제출되었습니다. 감사합니다!