ABAC で RBAC を使用する

Unity カタログのロールベースのアクセス制御 (RBAC) と 属性ベースのアクセス制御 (ABAC) は、連携するように設計された補完的な制御です。 彼らはさまざまな質問に答えます:

  • RBAC は、ユーザーがセッション中に どの ID として振る舞うかを制御します。 ユーザーはロールを引き受け、自身のアクセス許可ではなく、そのロールのアクセス許可に基づいて行動します。 RBAC を使用して、1 人のユーザーに明示的に切り替える複数の個別のアクセス許可セットを付与します。たとえば、臨床試験、プロジェクト、秘密度レベル間でアクセスを分離します。
  • ABAC は、アクティブ ID が表示できる データ を、行単位または列単位で制御します。 ポリシーは 、管理されたタグ を介してデータにアタッチされ、クエリを実行する ID に適用されます。 データ属性によって駆動される多くのテーブルで一貫したフィルター処理またはマスクを行うには、ABAC を使用します。

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

ロールを想定するときの ID 関数の動作

Unity カタログ ID 関連の SQL 関数は、基になる認証ユーザーではなく、セッションのアクティブ ID に対して解決されます。 ユーザーがロールを引き受けると、アクティブなセッション ID がロールになります。

Function ユーザーがユーザー ID として機能する場合 ユーザーがロールを引き受けるとき
current_user() ユーザーのユーザー名を返します。 想定されるロールの名前を返します。
is_member(group) ユーザーがグループのメンバー (ワークスペースローカル グループ、またはワークスペースに割り当てられているアカウント グループ) である場合に true を返します。 引き受けたロール自体がtrueのメンバーである場合にのみ、groupを返します。 そのユーザーがメンバーであるグループのうち、割り当てられたロールが適用されないものについて、false を返します。
is_account_group_member(group) ユーザーがアカウント レベルのグループのメンバーである場合は、 true を返します。 is_member と同じ: 元のユーザーではなく、引き受けたロールのグループへの所属のみに基づいて true を返します。

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

Note

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

よくある落とし穴: current_user()に基づいて構築された行レベル セキュリティ ビュー

ABAC とテーブル レベルの行フィルターの共通パターンは、によって返されるユーザー名にキーを設定したcurrent_user() (マッピング テーブルまたはアクセス制御リストとも呼ばれます) に対して結合して行をフィルター処理することです。 例えば次が挙げられます。

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_id という列があり、その列には管理対象タグのキー project が設定されています。
  • 各プロジェクトには、 role-<project> という名前の対応するアクセス ロールがあります (たとえば、 role-alpharole-beta)。
  • ユーザーは、作業中のプロジェクトのロールに対してのみ権限を持つものとします。

行フィルター UDF:

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

ポリシー:

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 のようなプリンシパルを対象とする句ではこれを表現できません。そうした句が対象とするのは、行の内容ではなくプリンシパルだからです。 プリンシパルターゲットのガイダンスで説明されているように、このような場合は、単一のルールがアクティブな ID と行のコンテンツの両方に依存する場合は、UDF 内の単純なプリンシパル スコープと予約 ID 関数のTO / EXCEPTを使用します。

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

動作:

  • 自身のユーザー ID で動作するユーザーには、どのclinical_trialsテーブルにも行が1つも表示されません。 current_user() は、 role-* 名前付けパターンと一致しないユーザー名を返します。 これは、意図された既定の拒否です。
  • ユーザーは、role-alphaproject_idalpha等しい行のみを表示すると仮定します。 role-betaに切り替えると、他のクエリを再度実行することなく、表示されるデータがスワップされます。

指定されたロールのユーザーに対するPIIマスキングの緩和

既定では、PII 列 (SSN、電子メール、電話) は、すべてのユーザーに対してマスクされて表示されます。 生の値を確認するには、ユーザーは指定されたPII閲覧権限付きロールを明示的に引き受ける必要があります。 監査ログにはロール想定イベントが記録されるため、"実際の PII を確認する必要があります" は、アンビエント アクセス許可ではなく監査可能なオプトインになります。

セットアップ:

  • 機密性の高い列には、 管理タグ キー pii ( ssnemailphoneなどの許容値) がタグ付けされます。
  • raw PII の閲覧を許可されたユーザーには、role-pii-cleared という名前のアクセス ロールを引き受ける権限が付与されます。

列マスキング UDF(静的 — どのプリンシパルをマスクするかをポリシーで指定):

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

ポリシー:

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 権限を持つユーザーを含め、すべてのユーザーの既定の状態です。
  • role-pii-clearedを想定した後、ポリシーはセッションに適用されなくなり、同じユーザーに生の値が表示されます。
  • セッション レコード identity_metadata.run_as = role-pii-clearedの監査ログ エントリにより、レビュー担当者は PII がいつ誰によってマスク解除されたかを正確に確認できます。

想定ロールごとに異なる機密性レベルのポリシー

データは、秘密度レベル (internalconfidentialrestricted) に分類されます。 各層には対応するアクセス ロールがあり、restrictedconfidentialinternalへのアクセスも意味します。 1 つの行フィルター UDF は、各行の層をユーザーの想定されたロールと比較することで、行の可視性をゲートします。

セットアップ:

  • テーブルには、governed tagタグキーsensitivityでタグ付けされたsensitivity_level列があります(使用可能な値: internalconfidentialrestricted)。
  • 3 つのアクセス ロール: role-sens-internalrole-sens-confidentialrole-sens-restricted

行フィルター UDF:

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;

ポリシー:

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 は、メンバーシップをcurrent_user()でテストするのではなく、各ロール名とis_account_group_member()を比較します。 メンバーシップ テストが想定されるロールと一致しない理由については、 上記の注 を参照してください。 UDF の ID 関数のパフォーマンス特性については、 行フィルターおよび列マスク ポリシー のパフォーマンスに関する考慮事項を参照してください。

動作:

  • 自身のユーザー ID として動作しているユーザーには 行は表示されませんELSE FALSE ブランチは、3 つのロールの 1 つではないものに一致します。 上記のプロジェクトごとの例と同様に、これは意図された既定の拒否です。
  • role-sens-internalinternal行のみを表示すると仮定します。
  • role-sens-confidential internal行とconfidential行が表示されると仮定します。
  • role-sens-restrictedがすべての行を表示すると仮定します。

ユーザーは、セッションに必要な最も高いレベルを想定しています。フィルターは、どのテーブルがどの分類を保持するかをユーザーに知らなくても、そのレベルを超えるすべてを自動的に除外します。

監査の帰属

ABAC ポリシーの評価と基になるクエリの両方で、RBAC run_as / run_by 属性が尊重されます。 監査ログ エントリは、評価中に適用された ABAC ポリシーに関係なく、認証ユーザーとして identity_metadata.run_by し、 identity_metadata.run_as を想定されたロールとして記録します。 完全 な監査ログ スキーマについては、監査ログ システム テーブル リファレンスを参照してください。

次のステップ

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