メインコンテンツまでスキップ

ABACでRBACを使用する

備考

プレビュー

RBACはパブリックプレビューです。ABACは一般公開されています。このページでは、この2つがどのように連携して機能するかについて説明します。

Unity Catalog における役割ベースのアクセス制御(RBAC)と属性ベースのアクセス制御(ABAC)は、互いに連携するように設計された補完的な制御機能です。様々な質問に答えます。

  • RBAC は、ユーザーがセッションのために どのアイデンティティ として振る舞うかを制御します。ユーザーは、自身の権限ではなく、そのロールの権限で操作するためにロールを割り当てます。RBAC を使用して、1 人のユーザーに、明示的に切り替えることができる複数の異なる権限セットを付与します。たとえば、臨床試験、プロジェクト、または機密性レベル全体でアクセスを分離します。
  • ABAC は、アクティブなIDが見ることができる データ を行ごとまたは列ごとに制御します。ポリシーは管理タグを介してデータに紐付けられ、クエリーを実行するIDに適用されます。ABACを使用して、データ属性によって駆動される多くのテーブル全体で一貫したフィルタリングまたはマスキングを行います。

RBAC はセッションのアクティブなIDを設定し、ABAC はそのポリシーをそのIDに対して評価します。このページでは、その相互作用が実際にどのように機能するか、ID関連のSQL関数の動作、および組み合わせ使用パターンについて説明します。

ロールを引き受ける際の ID 機能の動作

Unity Catalog のアイデンティティ関連 SQL 関数は、基になる認証ユーザーではなく、セッションのアクティブなアイデンティティに対して解決されます。ユーザーがロールを割り当てると、アクティブなセッションのアイデンティティがそのロールになります:

関数

ユーザーが自身のユーザー ID として機能する場合

ユーザーがロールを引き受ける場合

current_user()

ユーザーのユーザー名を返します

引き受けたロールの名前を返します

is_member(group)

ユーザーがグループ(ワークスペースローカルグループ、またはワークスペースに割り当てられたアカウントグループ)のメンバーである場合、trueを返します。

引き受けられたロール自体がgroupのメンバーである場合にのみ、trueを返します。基盤となるユーザーがメンバーであるグループに対してfalseを返しますが、引き受けられたロールはメンバーではありません。

is_account_group_member(group)

ユーザーがアカウントレベルのグループのメンバーである場合、true を返します

is_memberと同じです。基になるユーザーのグループメンバーシップではなく、引き受けたロールのグループメンバーシップのみに基づいてtrueを返します。

関数

ユーザーが自身のユーザー ID として機能する場合

ユーザーがロールを引き受ける場合

current_user()

ユーザーのユーザー名を返します

引き受けたロールの名前を返します

is_member(group)

ユーザーがグループ(ワークスペースローカルグループ、またはワークスペースに割り当てられたアカウントグループ)のメンバーである場合、trueを返します。

引き受けられたロール自体がgroupのメンバーである場合にのみ、trueを返します。基盤となるユーザーがメンバーであるグループに対してfalseを返しますが、引き受けられたロールはメンバーではありません。

is_account_group_member(group)

ユーザーがアカウントレベルのグループのメンバーである場合、true を返します

is_memberと同じです。基になるユーザーのグループメンバーシップではなく、引き受けたロールのグループメンバーシップのみに基づいてtrueを返します。

これらの関数を参照するABACポリシーは、ユーザーではなく 引き受けたロール に対して評価されます。引き受けたロールは、ABACポリシー評価、Unity Catalogの許可解決、および監査帰属のアクティブなIDです。結果として、ロールを引き受けることによって、ユーザーごとのIDを中心に構築された既存のポリシーとビューの動作が変更されます。

注記

ロールは自動的にそれ自体のメンバーではありません。ユーザーがロールGを引き受ける場合、current_user()Gを返しますが、Gが明示的にそれ自体のメンバーとして追加されていない限り、is_member('G')is_account_group_member('G')falseを返します。ポリシーで引き受けられたロールに一致させるには、is_memberまたはis_account_group_memberでメンバーシップをテストするのではなく、current_user()と比較します。

よくある落とし穴: 行レベルセキュリティビューの構築 current_user()

ABAC および テーブルレベルの行フィルターに共通するパターンは、current_user() によって返されるユーザー名をキーとしたプロビジョニングテーブル(マッピングテーブルまたはアクセス制御リストとも呼ばれます)に対して結合することによって行をフィルターすることです。例えば:

SQL
CREATE OR REPLACE FUNCTION facility_filter(facility_id STRING)
RETURN EXISTS (
SELECT 1
FROM governance.user_facility_provisioning p
WHERE p.user = current_user()
AND p.facility_id = facility_id
);

同じユーザーがロールを引き受けると、current_user()はユーザー名を返さなくなります。ロールの名前を返します。ロールがプロビジョニングテーブルにないため、フィルターは行を返さず、ユーザーは付与されたデータへのアクセスを失うように見えます。

役割をプロビジョニングテーブルに追加します

役割をプロビジョニングデータ内の別のプリンシパルとして扱います。ロールが表示すべき機能(またはその他の属性)をロールごとに1行挿入します。フィルターは、アクティブなIDがユーザーか、それとも引き受けられたロールかを照合します。

組み合わせ使用パターン

以下は、顧客がRBACとABACを併用して実際のアクセス制御の問題を解決する例です。これらは出発点であり、網羅的なレシピではありません。

プロジェクトごとの行フィルターで、引き受けたロールに基づいてキー付けされたもの

プロジェクト別に列をフィルタリングすることは、臨床試験研究、契約マーケティング、クライアントコンサルティング、および1つのチームが複数の独立したプロジェクトで作業するその他の環境で一般的なニーズです。次の例は臨床試験を使用していますが、このパターンはプロジェクトごとのデータ分離にも一般化されます。

臨床研究組織は、いくつかの並列トライアルを実行しており、それぞれ独自のアクセスロールを使用しています。各テーブルにプロジェクト識別子でタグを付けます。ユーザーは、現在ロールを引き受けているプロジェクトの行のみを表示します。

セットアップ:

  • clinical_trials.* のテーブルには、管理タグキー project でタグ付けされた project_id 列があります。
  • 各プロジェクトには、role-<project> という名前の対応するアクセスロールがあります (例: role-alpharole-beta)。
  • ユーザーは、担当するプロジェクトのロールに対してのみAssume権限を持ちます。

行フィルター UDF:

SQL
CREATE FUNCTION project_match(project_id STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN current_user() = CONCAT('role-', project_id);

ポリシー:

SQL
CREATE POLICY per_project_row_filter
ON CATALOG clinical_trials
ROW FILTER project_match
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('project') AS project
USING COLUMNS (project);

このUDFは、アクティブなIDを各行のprojectタグ値と関連付けます。そのため、TO/EXCEPTのようなプリンシパルをターゲットとする句ではそれを表現できません。それらは行の内容ではなく、プリンシパルをターゲットとしているからです。プリンシパルをターゲットとするガイダンスで説明されているように、シンプルなプリンシパルのスコープ指定にはTO/EXCEPTを優先し、単一のルールがアクティブなIDと行の内容の両方に依存する今回のようなケースでは、UDF内のID関数を予約してください。

単一のポリシーがすべてのプロジェクトをカバーします: USING COLUMNS (project) は各行の project タグ値を UDF に渡し、プロジェクトごとに個別のポリシーは必要ありません。この手法の一般的な形式、つまりロール名による照合ではなくルックアップテーブルから行アクセスを制御する方法については、動的アクセス制御にマッピングテーブルを使用するを参照してください。

動作:

  • ユーザー ID として動作するユーザーは、どの clinical_trialsテーブルでも**行は表示されません**。current_user() はユーザー名を返しますが、それは role-* の命名パターンには決して一致しません。これは意図されたdefault拒否です。
  • role-alpha を想定するユーザーは、project_idalpha に等しい行のみを参照します。role-beta に切り替えると、他のものを再クエリーせずに表示データをスワップします。

指定されたロールとして機能するユーザー向けに PII マスキングが緩和されます

defaultでは、PII列 (SSN、Eメール、電話) は全員に対してマスクされて表示されます。生の値を表示するには、ユーザーは指定されたPIIクリア済みロールを明示的に引き受ける必要があります。監査Logsにはロール引き受けイベントが記録されるため、「I needed to look at real PII」は、環境パーミッションではなく、監査可能なオプトインになります。

セットアップ:

  • 機密列には、管理タグ キー piissnemailphoneなどの許可される値)というタグが付けられています。
  • role-pii-clearedという名前のアクセスロールには、未加工のPIIを表示する許可を与えられたユーザーに引き受け権限が付与されます。

列マスクUDF(静的 — ポリシーはマスクするプリンシパルをターゲットとします):

SQL
CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
DETERMINISTIC
RETURN '***';

ポリシー:

SQL
CREATE POLICY pii_default_mask
ON CATALOG customer_data
COLUMN MASK mask_pii
TO `account users`
EXCEPT `role-pii-cleared`
FOR TABLES
MATCH COLUMNS has_tag('pii') AS pii_col
ON COLUMN pii_col;

EXCEPT句はポリシーからrole-pii-clearedを完全に除外するため、そのロールがアクティブなIDである場合、UDFは呼び出されません。TO/EXCEPTを介したプリンシパルターゲティングに関する一般的なガイダンスについては、プリンシパルターゲティングにはTO/EXCEPTを優先を参照してください。

動作:

  • ユーザーIDとして動作するユーザーは、すべてのPII列で***を確認します。これは、role-pii-clearedに対するAssume権限を持つユーザーを含む、すべての人にとってのdefaultの状態です。
  • role-pii-clearedを引き受けた後、ポリシーはセッションに適用されなくなり、同じユーザーには生の値が表示されます。
  • セッションレコードidentity_metadata.run_as = role-pii-clearedの監査 Logs エントリにより、レビュー担当者はいつ、誰がPIIを非マスク化したかを正確に確認できます。

引き受けられたロールによって異なる感度層ポリシー

データは機密性ティア (internal, confidential, restricted) に分類されます。各ティアには対応するアクセスロールがあり、restrictedconfidentialinternalへのアクセスも意味します。単一の行フィルターUDFは、各行のティアをユーザーの仮定されたロールと比較することで、行の可視性を制御します。

セットアップ:

  • テーブルには、管理タグキーsensitivity(許可されている値:internalconfidentialrestricted)でタグ付けされたsensitivity_level列があります。
  • 3つのアクセスロール: role-sens-internal, role-sens-confidential, role-sens-restricted

行フィルター UDF:

SQL
CREATE FUNCTION sensitivity_allowed(row_sensitivity STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN CASE
WHEN current_user() = 'role-sens-restricted' THEN TRUE
WHEN current_user() = 'role-sens-confidential' THEN row_sensitivity IN ('internal', 'confidential')
WHEN current_user() = 'role-sens-internal' THEN row_sensitivity = 'internal'
ELSE FALSE
END;

ポリシー:

SQL
CREATE POLICY sensitivity_filter
ON CATALOG corp_data
ROW FILTER sensitivity_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('sensitivity') AS sens
USING COLUMNS (sens);

ロールはそれ自身のメンバーではないため、このUDFは is_account_group_member() でメンバーシップをテストするのではなく、current_user() を各ロール名と比較します。メンバーシップテストが引き受けられたロールと一致しない理由については、上記の注記を参照してください。UDFにおけるID関数のパフォーマンス特性については、行フィルターと列マスクポリシーのパフォーマンスに関する考慮事項を参照してください。

動作:

  • ユーザー IDとして機能するユーザーは**行を確認できません**。The ELSE FALSE Branchは、3つのロールのいずれでもないものすべてに一致します。上記のプロジェクトごとの例と同様に、これは意図されたdefault-denyです。
  • role-sens-internalを仮定すると、internal行のみが表示されます。
  • role-sens-confidentialと仮定すると、internalconfidential行が表示されます。
  • role-sens-restrictedですべての行が表示されると仮定します。

ユーザーは、セッションに必要な最上位の階層を引き受けます。フィルターは、ユーザーがどのテーブルがどの分類を保持しているかを知る必要なく、その階層を超えるすべてを自動的に除外します。

監査属性

ABAC ポリシー評価と基になるクエリーはどちらも、RBAC run_as / run_by の属性付けを尊重します。監査ログのエントリーは、評価中にどの ABAC ポリシーが適用されたかに関わらず、identity_metadata.run_by を認証ユーザーとして、identity_metadata.run_as を引き受けたロールとして記録します。監査ログ システムテーブルリファレンスで完全な監査ログスキーマを参照してください。

次のステップ

  • **モデルの排他的アクセス**: アカウントローカルグループまたはIDプロバイダーから同期されたグループのいずれかを使用して、排他的アクセスを設定するためのパターンを適用します。モデルの排他的アクセスを参照してください。
  • ロールの切り替え :ロールスイッチャー、専用アクセスモードのクラスター、CLI、API、またはサードパーティのBIツールを使用してロールを引き受けます。「ロールの切り替え」をご覧ください。
  • Assume権限の管理 :グループに対するAssumeを付与または取り消し、ユーザーが対応するロールを引き受けることができるようにします。グループの権限を管理するを参照してください。
  • **ABAC のコアコンセプトを確認**:管理タグ、ポリシー、およびポリシー評価がどのように機能するかを学びます。Unity Catalog の属性ベースのアクセス制御を参照してください。