Omni のアクセスフィルターを使って行レベルのセキュリティを設定してみた

Omni のアクセスフィルターを使って行レベルのセキュリティを設定してみた

2026.06.02

こんにちは、ikumiです。

複数のブランドが同一プラットフォームを使っている場合、「ブランド A の担当者にはブランド A のデータだけ見せたい」という要件が出てきます。ダッシュボードのフィルターをユーザーが外せない形で強制したい、というケースです。

Omni の アクセスフィルター(Access Filters) を使うと、ユーザーが実行するすべてのクエリの WHERE 句に自動でフィルターを適用し、自分のデータだけを見られる状態をモデルレベルで保証できます。今回はトピックへのアクセスフィルター設定から動作確認まで試してみました。

https://docs.omni.co/modeling/develop/data-access-control#granting-row-level-access-with-access-filters

機能概要

アクセスフィルターは、ユーザー属性の値を SQL の WHERE 句に自動注入する仕組みです。ユーザーが何をしても(フィルターを外そうとしても)、SQL レベルで常にフィルターがかかるため、ダッシュボードのフィルターを隠す方法などと比べてセキュリティ上の信頼性が高い方法です。

設定するパラメーターは3つです。

パラメーター 必須 内容
field フィルター条件として使うフィールド(例: brand_ana__tran.brand
user_attribute フィールドの値と照合するユーザー属性の reference 名(例: brand
values_for_unfiltered この値を持つユーザーはフィルターをスキップできる(例: [is_admin]

設定場所は2つあります。

設定場所 パラメーター 適用範囲
トピックファイル access_filters そのトピックのみ
モデルファイル default_topic_access_filters 全トピックにデフォルト適用

事前準備

アクセスフィルターはユーザー属性と組み合わせて動作します。まずユーザー属性を設定します。

ユーザー属性(User Attributes)を作成する

SettingsAttributes に移動し、New Attribute をクリックして以下の内容でカスタム属性を作成します。

項目 設定値
Name brand_kbn
Reference brand_kbn
Type string
Multiple values No
Default value (空白のまま)

注意点としては、Default value は設定しないことを推奨します。値が未設定のユーザーに意図せずデータが表示されるのを防ぐためです。

2026-06-01_16h34_36

ユーザーに属性値を割り当てる

作成した Brand 属性を選択し、Users タブを開きます。アクセスフィルターを適用したいユーザーに値(ブランド名)を入力して保存します。

2026-06-01_16h35_56

今回は自分のユーザーに Celine を設定します。
2026-06-01_16h36_10

また、フィルターをスキップさせたい管理者ユーザーには、is_adminを設定します。

2026-06-01_16h53_02

試してみた

1. トピックにアクセスフィルターを設定する

今回適用させたい個別のTopic に access_filters を追加します。

access_filters:
  - field: brand_ana__tran.brand
    user_attribute: brand_kbn
    values_for_unfiltered: [ is_admin ]
  • field: フィルターの基準にするフィールド。brand_ana__tran ビューの brand ディメンションを指定します
  • user_attribute: 照合するユーザー属性の reference 名。事前準備で作成した brand_kbn を指定します
  • values_for_unfiltered: brand_kbn ユーザー属性が is_admin のユーザーはフィルターをスキップできます

2. フィルターが SQL に適用されることを確認する

変更を保存し、Celine の属性値を持つユーザーで 先ほどのトピックを開きます。brandsales_sum を選択してクエリを実行します。

2026-06-01_17h08_17

SQL タブを開くと、WHERE 句に brand = 'Celine' が自動で付加されていることが確認できます。ユーザーがフィルターを操作しても、この WHERE 句は外せません。

2026-06-01_17h08_45

3. 管理者ユーザーはフィルターをスキップできることを確認する

is_admin ユーザー属性を true に設定したユーザーで同じクエリを実行します。SQL の WHERE 句にブランドフィルターが含まれていなければ問題ありません。すべてのブランドのデータを確認できる状態になります。

2026-06-01_17h09_12
2026-06-01_17h09_20

4. モデルレベルで全トピックに一括適用する

トピックが複数あり、すべてに同じアクセスフィルターをかけたい場合は、モデルファイルに default_topic_access_filters を設定します。

モデルファイル(model.yaml など)に以下を追加します。

default_topic_access_filters:
  - field: brand_ana__tran.brand
    user_attribute: brand
    values_for_unfiltered: [ is_admin ]

これにより、このフィールドを持つすべてのトピックに対してアクセスフィルターがデフォルトで適用されます。トピックごとに個別設定する手間が省けます。

ただし、default_topic_access_filters で指定したフィールドを持たないトピックが存在すると、そのトピックで以下のエラーが発生します。

No such access filter field "brand_ana__tran.brand" specified in default_topic_access_filters

そのため default_topic_access_filters は、モデル内のすべてのトピックが対象フィールドを持っている場合にのみ安全に使えます。フィールドを持たないトピックが混在する場合は、トピックごとに個別に access_filters を設定する方法を選んでください。

最後に

Omni のアクセスフィルターを使って、ブランドごとに見えるデータを SQL レベルで制限してみました。

ユーザーがフィルターを外せない形でデータを制限できるため、外部向けアプリケーションや、複数の取引先が同一プラットフォームにアクセスするような場面で特に有効です。values_for_unfiltered を使えば管理者や開発者はフィルターをスキップしてすべてのデータを確認できるため、開発・運用上の利便性も確保できます。

アクセスフィルターが行レベルのセキュリティを担うのに対し、列・トピックレベルのセキュリティはアクセス権(Access Grants)で制御できます。こちらについては別記事にまとめます。

この記事をシェアする

関連記事