データ ソースとワークブックの RLS のベスト プラクティス

Tableau の行レベル セキュリティ (RLS) は、特定のユーザーがワークブックに表示できるデータの行数を制限します。これは、コンテンツや機能へのアクセスを制御する Tableau パーミッションとは異なります。たとえば、パーミッションはユーザーがワークブックにコメントしたり、ワークブックを編集したりできるかどうかを制御しますが、行レベルのセキュリティでは、同じダッシュボードを表示している 2 人のユーザーが、それぞれ表示可能なデータのみを表示することができるようにします。

Tableau ではさまざまな方法で RLS を実装することができます。たとえば、RLS をデータ ソース レベルまたはワークブック レベルで設定したり、データ ポリシーを使用した仮想接続を使用して接続レベルで RLS を設定 (データ管理 が必要です) したりできます。代替案の詳細については、「Tableau の行レベルのセキュリティ オプションの概要」参照してください。

: このトピックでは、データ ソースとワークブックの RLS のベストプラクティスに焦点を当てています。注: このトピックで概説する概念の詳細な例については、ブログ Tableau and Behold にあるホワイトペーパー「資格テーブルによる行レベル セキュリティのベスト プラクティス(新しいウィンドウでリンクが開く)」と「Tableau の行レベル セキュリティ用にデータベースを設定する方法(新しいウィンドウでリンクが開く)」を参照してください。

RLS のワークフロー

ライブ接続および複数テーブル抽出の場合、基本的な RLS ワークフローは次のとおりです。

  1. ユーザーは、Tableau Server または Tableau Cloud にログインすることで識別されます。
    • これには、ユーザーごとの個別のユーザー名とセキュリティで保護されたシングル サインオン (SSO) が必要です。
    • Active Directory、LDAP、または Tableau REST API を使用してユーザー名を同期し、パーミッションを確立できます。
  2. ユーザーのデータ資格のセットは、すべての可能なデータ資格から取得されます。
    • これには、資格を Tableau ユーザー名にリンクできるデータ構造が必要です。
  3. データは、そのユーザーの資格によってフィルターリングされます。
    • 多くの場合、計算フィールドでユーザー関数を使用する必要があります。
  4. パブリッシュ済で、フィルター処理されたデータは、コンテンツの構築に使用されます。
    • データ ソース フィルターでパブリッシュされた (埋め込みではなく) データ ソースを使用すると、ワークブックをダウンロードまたは Web 編集して RLS を変更できなくなります。

結合、計算フィールド、およびフィルターの設定方法は、データの構造とユーザーの管理方法によって異なります。

資格テーブル

データをフィルター処理できる属性の一意の組み合わせは、資格です。通常、資格自体を指定し、それらの資格をユーザーまたはユーザー ロールにマップするための個別の表があります。結合は負荷の高い操作であるため、パフォーマンスの観点からは非正規化をお勧めします。

ユーザーまたはロールにマップされた資格で構成される資格ビューは、データと結合されます。次に、ユーザー ベースのデータ ソース フィルターが適用され、関連するユーザーの権利 (したがって適切なデータ行) のみを取り込む WHERE 句として機能します。(クエリの最適化では、データの重複を最小限に抑えるためにクエリが処理されるときに、結合する前にフィルター処理が行われるようにする必要があります。詳細については、操作のパフォーマンスと処理順序を参照してください。)

資格表モデル

一般に、資格を表すためのモデルは 2 つあります。

最も深い粒度への完全なマッピング

  • 資格は、すべての列に対して完全に定義されます。
  • マッピング テーブルには、ユーザーが持つ可能性のある資格ごとに 1 つの行があります。
  • このモデルでは、必要な結合句が少なくなります。

スパース資格

  • 資格は階層のすべてのレベルに対して定義され、NULL は "すべて" 状態を表すために使用されます。
  • 資格階層内の特定のレベルのマッピング表には 1 つの行があり、階層内の上位レベルのユーザーの資格行の数が大幅に減少します。
  • このモデルには、より複雑な結合とフィルターが必要です。

ユーザーと ロール

権利の組み合わせは、一般にロールとして表され、多対多マッピング表のユーザーにリンクされます。 これにより、ロールとその資格の記録を維持しながら、ロールのユーザーを簡単に変更または削除できます。

または、ロール表の結合ではなく、ユーザーを資格に直接割り当てる多対多マッピング表を作成することもできます。テーブル内の値をより直接的に管理する必要がありますが、結合は削除されます。

注:ロールまたは資格に関連付けられたユーザー値は、Tableau Desktop のユーザー機能を利用するために、Tableau サイトのユーザー名またはフル ネームと一致する必要があります。

結合

資格を表すために使用されるモデルに関係なく、すべての資格とマッピング表を 1 つの非正規化された資格ビューに結合することをお勧めします。最初は、資格の"ブローアップ"(非常に重複した)バージョンを引き起こしますが、ユーザーのデータソースフィルターはそれを減らします。抽出の使用を計画している場合も、このビューが必要になります。

最も粒度の深い方法では、すべてが階層的である場合にパフォーマンス上の利点を得ることができます。階層の最も深いレベルで単一結合をすればよいだけです。これは、最下位レベルのすべての属性が異なる場合にのみ機能します。重複の可能性がある場合 (たとえば、複数のリージョンの中央サブリージョン)、個別のキー値の効果を得るには、すべての列で結合する必要があります。

実際の詳細とそのパフォーマンス特性は、データ システムによって異なっており、テストが必要です。たとえば、1 つのキーを使用すると、結合が 1 つの列に対してのみ実行されるため、パフォーマンスが向上する可能性がありますが、すべての列に正しくインデックスを付けると、他の要因が考慮された場合に同等のパフォーマンスが得られる可能性があります。

行レベルのセキュリティを実装する

最も深い粒度

マッピングされた資格の非正規化ビューが作成されると、ビューと Tableau データ接続ダイアログのデータの間に内部結合が設定されます。データは従来のスター スキーマに残すことができます。または、ディメンション表とファクト表を 2 つのビューにマテリアライズすることもできます。複数表の抽出では、結合に合わせて抽出表が作成されるため、2 つのビューを作成すると、結果の抽出が簡略化されます。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)]

または、すべてのレベルを 1 つにまとめて計算することもできます。

([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 と同様に、これらの計算はデータ ソース フィルターとして追加する必要があります。

データ ソース フィルター

どちらの方法でも、資格がデータと正しく結合されたら、特定のユーザーのデータを制限するようにフィルターを設定する必要があります。計算フィールドは、ユーザー関数を使用して作成する必要があります。たとえば、[ユーザー名] フィールドに表示されるユーザーが Tableau サイトにログインしているユーザーのユーザー名と同じかどうかの単純なブール比較を行います。 [Username] = USERNAME()

この計算は、データ ソース フィルターとして使用する必要があります (TRUE が選択されている場合)。

データ ソースが埋め込まれており、ユーザーがブックを Web 編集またはダウンロードするパーミッションを持っている場合、RLS は存在しません。Tableau データ ソースは、ワークブックに埋め込まれたままになるのではなく、個別にパブリッシュする必要があります。

最も深い粒度を持つすべてのアクセス

また、組織内に 2 つのアクセス レベル ("すべてのアクセス") を表示できるユーザーと、合理的に定義できる権利のサブセットを持つユーザーという 2 つのアクセス レベルがある一般的なシナリオもあります。これは、データをホストする組織がすべてを表示できるが、各クライアントは独自のデータしか表示できない、組み込みアプリケーションで最もよく見られます。この場合、他のすべてのユーザーの最も深い細分性結合を維持しながら、"すべてのアクセス" ユーザーの完全なデータを返す方法が必要です。

この手法では、Tableau グループを使用して、結合条件の計算を使用してオーバーライドを作成します。

  1. すべてのデータを表示するユーザーのグループを作成する (ここでは[すべてのアクセス] と呼ばれます) 
  2. ファクト ビューから、2 つの結合条件を持つ左結合を作成します。
    • 最初の結合条件は、最も深い粒度レベルを表す列に置く必要があります。
    • 2 番目の結合条件は、次の 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 の左結合になります。つまり、資格ビューには一致するものがまったく存在しないため、権利ビューの列に対してファクト ビュー全体が UL と共に返されます (重複ゼロ)。ユーザーが All Access グループに参加していない場合、 True = True 結合条件は何も変更されず、結合は期待どおりに機能します。

データ ソース フィルターとして使用されるユーザー計算は、グループの上書きが機能している場合はすべての行に当てはまります。または、階層内にあるユーザーの最も深い粒度にまでフィルターされます。

操作のパフォーマンスと処理順序

ビジュアライゼーションが Tableau Desktop、Tableau Server、または Tableau Cloud で表示されると、Tableau は最適化されたクエリを RDBMS に送信し、クエリを処理して Tableau に結果を送信し、結果データを使用してビジュアライゼーションをレンダリングします。結合、計算、およびフィルターが実行される操作の順序は、クエリ オプティマイザとクエリの実行方法によって異なります。

ライブ接続

Tableau でデータ ソースへのライブ接続を使用する場合、クエリ実行のパフォーマンスは、受信 SQL をデータ取得の効率的なプランに変換するクエリ オプティマイザに依存します。

クエリを処理するには、次の 2 つの方法があります。

  1. ユーザーの資格行をフィルター処理し、ファクト表に結合する
  2. 資格をファクト表に結合し、ユーザーの行にフィルターを適用します。

理想的な状況では、クエリ オプティマイザは、データベースが フィルター処理してから結合 することによってクエリを処理することを保証します。ユーザーがすべてに対して資格を持っている場合、処理される最大行数はデータ テーブル内の行数になります。

データベースが 結合してからフィルター処理してクエリを処理する場合、データが重複している可能性があります。 処理される行の最大数は、データ表の各行にその特定の行の回数を表示する権利を持つユーザーの数になります。

この 2 番目のシナリオが発生するかどうかは明らかです: クエリの完了に時間がかかる、エラーが発生する、またはデータベースのパフォーマンスの問題を示しています。データ量の合計が指数関数的に拡大し、バックエンドでシステムの負担が大きくなる可能性があります。

抽出

Tableau のデータ ソースがライブ接続の場合、Tableau は特定の viz またはダッシュボードを RDBMS にレンダリングするために必要なすべてのクエリを送信します。データ ソースが抽出の場合、基になるデータ ソースからデータをクエリするプロセスは、抽出の作成と更新時にのみ行われます。ビジュアライゼーションに対するすべての個々のクエリは、抽出ファイルから抽出エンジンによって応答されます。

単一の表抽出を作成する場合も、同じ順序の操作の問題が存在します。ただし、"ブローアップ" は、基になるデータ ソースと結果の抽出自体の両方で発生します。

抽出に関する考慮事項

Tableau 2018.3 以降、データ エンジンは複数テーブルの抽出を作成でき、RLS は上記のように実装できます。複数表抽出を使用すると、結合を具体化しないことで、多対多リレーションシップを持つ抽出の生成にかかる時間が短縮されます。

抽出は、 データ オブジェクト資格オブジェクト を使用して構築する必要 があります。 これは抽出の中で最も単純なストレージであり、最高のパフォーマンスを得ることができます。

  • データ オブジェクトは、ファクト表と必要なディメンション表の非正規化された組み合わせを表す表、ビュー、またはカスタム SQL クエリです。
  • 資格オブジェクトは、最も細かいレベルでデータをフィルターリングするために必要な資格の非正規化された表、ビュー、またはカスタム SQL クエリです。
    • Tableau Server または Tableau Cloud の正確なユーザー名と一致するユーザー名の列
    • データ オブジェクトに対する最も詳細な権利の各行

この形式は、上記の最も深い粒度の方法でレイアウトされています。複数表抽出では同じ方法が使用されますが、2 つのデータ オブジェクトのみが結合され、フィールド固有のフィルター処理が既にオブジェクト内に適用されていることに注意してください。

複数表抽出で抽出フィルターが無効になっているため、データ ソース内の接続先のビューまたは表でフィルター処理するか、[Tableau データ接続] ダイアログでカスタム SQL オブジェクトでフィルターを定義できます。

: ライブ接続の場合と同様に、データ ソースが埋め込まれており、ユーザーがブックを Web 編集またはダウンロードするパーミッションを持っている場合、RLS は存在しません。抽出は、ワークブックに埋め込まれたままになるのではなく、個別にパブリッシュする必要があります。

単一の表の抽出

次の方法は、2018.3 より前のバージョンの Tableau を使用している場合にのみ推奨されます。使用可能な場合、複数表抽出が好ましいです。

単一の表の抽出は、Tableau データ ソースの構築時に作成した結合を具体化し、1 つのクエリを通じてすべてを 1 つの表として格納します。この非正規化は、複数の資格またはユーザーに割り当てられたすべての行が多対多リレーションシップの結果として重複するため、大量のデータ重複を引き起こすリスクを伴います。

この重複を防ぐには、次の手順を実行します。

  1. その資格のユーザー名を含むセキュリティ ユーザー フィールドを作成する
    • たとえば、値は "bhowell|Mosterheld|rdugger"
  2. Tableau 内で CONTAINS() 関数を使用して個々のユーザーを正しく識別する
    • たとえば、CONTAINS([Security Users Field], USERNAME())

この方法には明らかにいくつかの注意事項があります。行内の資格から、SQL を使用して正しく区切られた単一の列に移動する必要があり、その列には非常に多くの文字しか含めることができない必要があります。部分一致が問題になる可能性があり、ID 自体では決して有効でない区切り記号を使用する必要があります。Tableau データ エンジン内ではパフォーマンスが向上しますが、文字列の計算はほとんどのデータベースで非常に低速になります。これにより、ライブ接続に切り替える機能が制限されます。

または、「ロール」レベルまたは資格レベルごとに異なる抽出を使用して、その個人またはレベルに適したデータのみが抽出に含まれるようにすることもできますが、これには適切なパーミッションを付与してテンプレートを活用するプロセスが必要になります。通常は API を介して Tableau Server 内でパブリケーションを行います。

組み込みの行レベル セキュリティをデータベースで使用する

多くのデータベースには、RLS のメカニズムが組み込まれています。組織が既にデータベースの行レベル セキュリティの構築に力を入れている場合は、既存の RLS を利用できる場合があります。組み込みの RLS モデルを実装する方が Tableau を念頭に置いて構築するよりも容易であるとは限りません。なぜなら、これらの技術は一般的に、組織がすでにこうした技術に投資していて、その投資を活用しようとするときに利用できるものだからです。組み込まれている RLS を使用する主な利点は、管理者がデータ セキュリティ ポリシーを 1 か所、つまりデータベースに実装して制御できることです。詳細については、「データベースの行レベル セキュリティ」を参照してください。

フィードバックをありがとうございます。フィードバックは正常に送信されました。ありがとうございます!