データポリシーによる行レベルのセキュリティを使用する #tableau

2024.04.23

データポリシーによる行レベルのセキュリティ機能の概要をまとめておきたく記事としました。

仮想接続とデータポリシー

Tableau Cloud または Tableau Server では、Tableau Data Management アドオンを利用することで、仮想接続とデータポリシーという機能を使用することが可能です。

  • Tableau Cloud

  • Tableau Server

仮想接続

仮想接続は、Tableau コンテンツ タイプの 1 つで、これによりデータソースへの認証情報を一元管理することができます。
具体的なメリットとして、以下が挙げられます。

  • ダッシュボード開発者に認証情報を渡さずにすむ
    • Creator は仮想接続経由でデータソースにアクセスすることが可能となります。サイト管理者が仮想接続を作成し、ある Creator ユーザーに接続を許可することで、Creator ユーザーは、認証情報を知らずにライブ接続であってもデータベースに接続し、ダッシュボードを開発できます
  • 認証情報の管理コスト削減
    • 仮想接続上で認証情報を管理することで、これまでデータソースやワークブックに埋め込んでいた認証情報の管理をこちらに一元化できます。上述の通り、仮想接続の作成者と使用者を分けることができるので、セキュリティの強化につながります
    • この際、一つの仮想接続に複数のデータソースの認証情報を含むことも可能です

仮想接続については、以下の記事でも詳しく解説されていますので、あわせてご覧ください。

データポリシー

仮想接続とあわせて「データポリシー」という行レベルのセキュリティ機能が提供されています。

仮想接続エディターで、データに適用するポリシーを作成することで、任意の条件でユーザーごとに表示するレコードを制限できます。
対応する DB/DWH であれば、データソース側の行レベルのセキュリティ機能を使用することも可能ですが、この場合、ライブ接続が前提となります。
データポリシーを使用することで、抽出の使用やユーザー関数を使用した Tableau 側のユーザー情報も使用できるという特徴があります。

また、データポリシー使用時の関連用語として以下があります。以降、本記事でもこれらの単語を使用します。

  • ポリシーテーブル
    • 行レベルのセキュリティの適用対象となるテーブル
  • ポリシー列
    • データのフィルタに使用する列
      • ユーザー名や所属グループ、プロジェクト、地域など、ユーザーごとに表示するレコードの制御に使用する列
  • ポリシー条件
    • どのようにレコードを表示させるかを定義する条件式
  • 資格テーブル
    • ポリシーテーブルに、フィルタリングに使用する列が含まれていない場合に使用できるテーブル
    • ポリシーテーブルと紐づけることで、資格テーブル上の列をポリシー列として、データテーブルのフィルタが可能となる

前提条件

ここでは、以下の環境で仮想接続の作成、データポリシーによる行レベルのセキュリティを検証しています。

  • Tableau Cloud
  • データソース:Snowflake
  • 行レベルのセキュリティの設定
    • Tableau Cloud 上のユーザーが所属する「グループ」ごとに閲覧可能なレコードを動的に制限する
    • グループの設定
      • Admins
        • ポリシーテーブルの全レコードを閲覧可能
      • ProjectA
        • ポリシーテーブルの ProjectA に関するレコードのみ閲覧可能
      • ProjectB
        • ポリシーテーブルの ProjectB に関するレコードのみ閲覧可能
      • ProjectC
        • ポリシーテーブルの ProjectC に関するレコードのみ閲覧可能
    • Snowflake 上のポリシーテーブルには、Tableau Cloud 上のグループに関する情報はないので、資格テーブルを使用し、ポリシーテーブル上のフィルタに使用するカラムと Tableau Cloud 上のグループを紐づける

事前準備

Snowflake 上にテーブルを作成

以下のコマンドでフィルタの対象となるポリシーテーブルを作成します。

--データベースを作成
CREATE OR REPLACE DATABASE prj_sales;
-- プロジェクトを識別可能コードを含む売上テーブルを作成する
CREATE OR REPLACE TABLE project_sales (
    project_code VARCHAR(50),
    sales_amount DECIMAL(18, 2)
);

-- 売上テーブルにサンプルデータを挿入する
INSERT INTO project_sales (project_code, sales_amount) 
VALUES 
    ('PROJ001', 1500.00),
    ('PROJ001', 2500.00),
    ('PROJ002', 1800.50),
    ('PROJ002', 2700.00),
    ('PROJ002', 2200.00),
    ('PROJ003', 3100.00),
    ('PROJ004', 2800.75),
    ('PROJ004', 2100.50),
    ('PROJ004', 3200.00),
    ('PROJ005', 3200.00),
    ('PROJ006', 2700.50),
    ('PROJ006', 2900.75),
    ('PROJ007', 2600.00),
    ('PROJ008', 3300.25),
    ('PROJ009', 3100.00),
    ('PROJ009', 2000.25),
    ('PROJ010', 3700.50);

データの内容として [project_code] 列にプロジェクトを識別可能なコードが含まれます。この列でデータをフィルタしたいのですが、Tableau Cloud 上の各グループは、直接どのコードが自身のグループに該当するものか、という情報を持ちません。

そこで、資格テーブルとして以下を定義します。

--資格テーブル用のスキーマを作成
CREATE OR REPLACE SCHEMA security;
USE SCHEMA prj_sales.security;

-- マッピングテーブルを作成する
CREATE OR REPLACE TABLE project_mapping (
    project_code VARCHAR(50),
    project_name VARCHAR(100)
);

-- マッピングテーブルにデータを挿入する(サンプルデータ)
INSERT INTO project_mapping (project_code, project_name) VALUES 
    ('PROJ001', 'ProjectA'),
    ('PROJ002', 'ProjectB'),
    ('PROJ003', 'ProjectC'),
    ('PROJ004', 'ProjectA'),
    ('PROJ005', 'ProjectB'),
    ('PROJ006', 'ProjectC'),
    ('PROJ007', 'ProjectA'),
    ('PROJ008', 'ProjectB'),
    ('PROJ009', 'ProjectC'),
    ('PROJ010', 'ProjectA');

資格テーブルには、プロジェクトコードに関する情報と各コードがどのプロジェクトに該当するか、という情報がマッピングされています。
[project_name] 列のプロジェクト名は、Tableau Cloud 上のグループ名と一致します。
ポリシーテーブルと資格テーブルの [project_code] 列を紐づけることで、もとのポリシーテーブルをプロジェクト名([project_name] 列の値)でフィルタできるようになります。

Tableau Cloud 上にグループを作成

下図の通り Tableau Cloud 上に今回の設定とあわせたグループを用意しておきます。

Tableau Cloud 側

仮想接続の作成

仮想接続の作成方法は以下に記載があります。

仮想接続の作成には以下が必要です。

  • 仮想接続が接続するデータベースにサインインするための認証資格情報
  • サイトロール
    • サーバー管理者、サイト管理者、または Creator

権限のあるユーザーで「新規 > 仮想接続」をクリックします。

コネクタとして、ここでは Snowflake を選択し、認証情報を入力します。

認証に成功すると下図の表示となるので、使用するウェアハウスや接続先のデータベースを選択します。

はじめに、ポリシーテーブルをとしてPROJECT_SALES テーブルを追加します。

資格テーブルとして使用するテーブルもここで追加が必要なので、追加しておきます。

データポリシーの作成

画面上部のタブから「データポリシー」を開き、[新しいポリシーを作成] をクリックします。

下図の表示となるので、ポリシーテーブルと資格テーブルをここで追加します。

ポリシーテーブルを追加する際は、対象のテーブルから「ポリシーを使用したテーブルの管理」をクリックします。

資格テーブルとして追加する際は「資格テーブルを使用」を選択します。

エディタ上で、ポリシーテーブルと資格テーブルをマッピングします。ここでは [Project_Code] で下図の通り紐づけを行います。

紐づけができたら、具体的なフィルタ条件としてポリシー条件を定義します。
ポリシー条件記述にあたり、以下の点に注意します。

  • true または false に評価できる必要があります
  • ポリシー条件が true の場合に行を表示します

ここでは、以下の条件を定義しました。

IF (ISMEMBEROF("ProjectA") AND [Project Name] = "ProjectA") OR ISMEMBEROF("Admins")
	THEN TRUE
ELSEIF (ISMEMBEROF("ProjectB") AND [Project Name] = "ProjectB") OR ISMEMBEROF("Admins") 
	THEN TRUE
ELSEIF (ISMEMBEROF("ProjectC") AND [Project Name] = "ProjectC")OR ISMEMBEROF("Admins")
	THEN TRUE
ELSE
 FALSE
END

ダッシュボードを閲覧するユーザーが所属する Tableau Cloud 上のグループを条件にフィルタしたいので、ISMEMBEROF("ProjectA") のような形でユーザー関数を使用しています。
またISMEMBEROF 関数の引数はリテラル文字列である必要がある(フィールドを指定できない)のでAND [Project Name] = "ProjectA" をつなげてポリシーテーブル・資格テーブル上のカラムを指定しています。

管理者グループ(Admins)はすべてのレコードを見せたいので、各グループにOR 条件で繋いでいます。
条件に合致しないその他のグループやプロジェクトグループに所属していないユーザーには、レコードを見せないような設定です。

行レベルのセキュリティをテストする

作成段階のポリシーは、エディタ上で動作を確認することができるようになっています。

下図の赤矢印を選択・チェックを入れ、ユーザーを選択することで、該当のユーザーコンテキストでポリシーが適用された結果を閲覧できます。

下図は「ProjectA」と「ProjectB」グループに所属するユーザーを指定した際の表示です。
マッピングテーブルで紐づけられた ProjectA と B のレコードが表示されます。

下図は「Admins」グループに所属するユーザーでの表示です。全レコードが表示されています。

どのグループにも属していないユーザーを指定すると、レコードが表示されません。

テスト結果が問題なければ、パブリッシュします。この際、ライブ接続・抽出のいずれでもパブリッシュ可能です。

ワークブックの作成

仮想接続からなるデータソースをパブリッシュしたら、この接続を使用するワークブックを作成できます。
他のユーザーが使用できるようにするためには、パーミッションの設定が必要です。

  • デフォルトでは、すべてのユーザーが接続を表示できます
    • Tableau で [仮想接続] の下に接続が表示されます
  • [接続] 機能を許可に設定しない限り、仮想接続を使用できるのはパブリッシュしたユーザーと管理者のみです

ワークブックのパブリッシュ

ここでは、下図のワークブックを作成しパブリッシュします。集約後のプロジェクトコードは10種類で、Admins グループに所属するユーザーは下図の表示になります。
所属プロジェクトグループ(ProjectA, B, C, またはどこにも属しない)ごとに表示される Project Code が資格テーブルとデータポリシーにより制御されます。

ワークブックをパブリッシュする際は「データソースのパスワードの埋め込み」のオプションを選択できます。

こちらについては、以下に記載があります。

「データソースのパスワードの埋め込み」にチェックを入れると、ワークブックで使用する仮想接続の [接続] 機能に対する許可がないユーザーであっても、ワークブックを表示することができます。つまり、仮想接続に対する明示的なアクセス権がない状態でも Viewer にワークブックを表示させるためにはこのオプションにチェックを入れます。

仮想接続は使用されますが、表示されるレコードは、実際にビューを表示するユーザーのコンテキストに基づきポリシーが適用された状態です。
例えば、下図の赤枠の Viewer はこの仮想接続に対する接続の許可はありません。

しかし、ワークブックのパブリッシュ時に「データソースのパスワードの埋め込み」にチェックを入れたので、ワークブックを閲覧することができます。
※このユーザーは「ProjectB」グループに属するので、下図のようにポリシーが適用された状態でレコードが表示されます。

データソースのパスワードの埋め込みを無効にする場合

このオプションにチェック入れずにパブリッシュし、同じユーザーでワークブックを表示すると下図のようになります。

「データソースのパスワードの埋め込み」無しでパブリッシュ

仮想接続への接続許可がないため、ワークブックを表示できません。

この時の仮想接続に対するパーミッションは下図の通りです。

ここで仮想接続に対する接続を許可します。

すると、ビューを表示できるようになります。

行レベルのセキュリティの確認

各グループのユーザーでポリシーが適用された状態でビューが表示されるか確認します。

  • ProjectA グループに所属するユーザー
  • ProjectB グループに所属するユーザー
  • ProjectC グループに所属するユーザー
  • ProjectA、ProjectB の両グループに所属するユーザー
  • Admins グループに所属するユーザー
  • どのグループにも属してないユーザー

各グループで意図する表示となりました。
それぞれグループに所属するユーザーは、資格テーブルでマッピングされたプロジェクトコードのレコードが表示されます。
どのグループにも属していないユーザーは、ポリシー条件に合致するレコードがなく、レコードは返ってきません。

さいごに

Tableau のデータポリシーによる行レベルのセキュリティを試してみました。
こちらの内容が何かの参考になれば幸いです。