Tableau Onlineのログインユーザーごとにデータ参照先を変更する方法

Tableau Online でログインユーザーごとにそのユーザーの権限に応じてデータ参照範囲を動的に制御するという実装を行った。
Tabluau 用語で言う行レベルセキュリティというやつ。

日本語でわかりやすく説明ドキュメントがなくて意外と困ったのでメモ。

実現したいこと

丁寧に説明しなくても伝わると思うが、要は一つのテーブルに部署コードごとに複数部署のデータが格納されておりそれを Tableau で参照させる際に、ログインユーザーの所属部署以外のデータは見させたくないよというお話。

スクリーンショット 2021-05-17 21.40.02

方式は2つ

いろいろ調べた結果、方式は以下の2つ。

1. ユーザーフィルタを使ってログインユーザー(もしくはグループ)と参照データ範囲を紐付ける
2. フィルタ用のセキュリティフィールド(参照範囲を制御するテーブル)を使って制御

それぞれの参考URLは以下。

ユーザー フィルターを作成し、パブリッシュ用にセキュリティで保護する

データでセキュリティ フィールドを使用して動的フィルターを作成する

ユーザーフィルタを使った方式

Tableau にはユーザーフィルタという専用機能があって、これでTableau Online(もしくは Server )のログインユーザーと参照データをぽちぽち手動で紐づけることでログインユーザーごとのデータ参照範囲を動的に制御できる。

画像1

今回の場合は、

・総務部ユーザー ===> somu-bu にチェック
・経理課ユーザー ===> keiri-ka にチェック

したユーザーフィルタを作成(フィルタを2つ作るのではなく一つのユーザーフィルタでそれぞれのユーザーごとに設定する)し、そのユーザーフィルタをフィルタペインに配置すればOK。

この方式のメリットとしては、ユーザー/グループで制御が可能な点だろうか。
デメリットとしてとにかくメンテナンス性が悪いということだろう。
また、移行性についても、テスト環境と本番とでユーザー情報を完全一致させないとそのまま移行もできないため、ある一定規模を超えると現実的に適用は難しい。

フィルタ用のセキュリティフィールドを使った方式

今回の実装でもこちらの方式を採用したが、データを参照するテーブルとは別に参照範囲を制御するテーブルを用意してフィルタするという方法。

スクリーンショット 2021-05-17 21.40.13

上記が参照範囲制御用のテーブルの例。
これを元テーブルに左外部結合する(当然ですが JOIN KEY の設計は元テーブルに合わせて都度ちゃんとやる必要があります。)

スクリーンショット 2021-05-17 21.40.20

次に、Tableau 側で計算フィールドを作成します。

USERNAME() = [ユーザーネーム]

わざわざ説明しなくてもわかると思いますが、USERNAME()関数はログインユーザー名を返す関数です。
よってログインユーザーと [ユーザーネーム] カラムの値が一致していれば、この計算フィールドは True を返します。

参考までに「somu-bu.user1@******.jp」でログインした時の各行の真偽の値は以下のようになります。

スクリーンショット 2021-05-17 21.40.27

あとはこの計算フィールドをフィルターペインに追加して True でフィルタすれば、「somu-bu.user1@******.jp」でログインした時には1番上の行しか表示されなくなります。

メンテナンス性に対する考察

長々と2つの方式について説明してきましたが、ぶっちゃけ方式について書きたかった訳ではありません。

今回悩んだのはメンテナンス性(保守性)でした。(というか大体そうだと思いますが。)

部署異動とか普通に起こるので、その度にメンテ依頼がきたら発狂しそうになりますし、GUIで手動でぽちぽちとかマジ勘弁。
そう考えると、ユーザーフィルタの方式は選択肢にはなり得ませんでした。

一応ユーザー部門でもメンテできるように良心的なUIを備えた運用ツールを作って上げて、バックエンドでAPI叩いてメンテするかとかも考えたのですが、そもそもユーザーフィルタをメンテするAPIが無いようです。(Tableau のDeveloper Community で確認済み)
そうなってくると、事前にグループとデータ参照範囲の関係を定義したユーザーフィルタを作って、部署異動の度にユーザーとグループの紐付けだけメンテするかとかも考えましたが、結局新規の部署ができたりするとめんどくさかったり、万一ユーザーフィルタ自体をメンテする時には手メンテとなり作業ミスが怖いのでやめました。

で、セキュリティフィールドを使った方式を採用した訳ですが、こっちはこっちでユーザー単位の制御になるのでテーブルメンテ大変だなーと思い悩みました。
(まぁユーザー部門にExcelかなんかでやってもらった奴を一括インポートするだけなんですが)

うまいことユーザーをグループにまとめて、ログインユーザーのグループに応じてセキュリティフィールドで制御できないかと調べたんですができなさそうです。
この記事ができそうな雰囲気を醸し出しているのですが、"<group name>"のところがリテラル文字列しか設定できず、「動的フィルタじゃないじゃん!」と思い「???」ってなりました。
ここ「ホントか!?」って思っているのでもっと詳しい方いたら教えて欲しいです。

で、参照ユーザーが増える度にテーブルメンテ依頼がくるのもうざいので、Gドライブに配置したスプシを日次バッチで取り込んでテーブル洗い変えるバッチ処理を組んでユーザー部門にメンテを丸投げしました。(一応なんかあった時のためにバックアップとかの対応はちゃんとした上で)

そんなこんなでそれぞれの方式のメリデメまとめるとこんな感じですかねー。


この記事が気に入ったらサポートをしてみませんか?