適用対象:
Databricks SQL
Databricks Runtime
SQL ステートメントAzure Databricks実行すると、2 つの異なるユーザーが追跡されます。
- セッション ユーザー: Azure Databricksに接続し、ステートメントを発行したユーザー。 セッション ユーザーは、SQL 接続の有効期間中は固定されています。 ステートメントがビュー、SQL UDF、またはストアド プロシージャに到達しても、ステートメントの実行中は変更されません。
-
承認されたユーザー: 現在実行中のステートメントがオブジェクトの読み取りまたは書き込みを行うときに特権がチェックされるユーザー。 承認されたユーザーは、実行がビュー本体、SQL UDF 本体、または
SQL SECURITY DEFINERプロシージャ本体に交差するにつれて変更できます。
session_user関数はセッション ユーザーを返します。
警告
current_user関数とユーザー関数は、承認されたユーザーではなく、セッション ユーザーも返すエイリアスです。 Standard SQL では、CURRENT_USERは承認されたユーザーを返します。Azure Databricksでは返されません。 セッション ユーザーを明示的に参照するには 、session_user を使用します。
承認されたユーザーの進化
ビュー、SQL UDF、またはストアド プロシージャを呼び出すたびに、呼び出し履歴に新しいエントリがプッシュされます。 ステートメントの許可されたユーザーは、所有者を修正する最上位のスタック エントリによって決定されます。
| Object | 本文内の承認されたユーザー |
|---|---|
| View | ビューの所有者 |
| SQL UDF | 関数の所有者 |
CREATE PROCEDURE ... SQL SECURITY DEFINER |
プロシージャ所有者 (定義子) |
CREATE PROCEDURE ... SQL SECURITY INVOKER |
呼び出し元ステートメントの承認されたユーザー (継承) |
ビュー、SQL UDF、および SQL SECURITY DEFINER プロシージャは、本文内のすべてのステートメントについて、承認されたユーザーを所有者に設定します。
SQL SECURITY INVOKER プロシージャは、承認されたユーザーを呼び出し元から継承します。
本文の実行が完了し、制御が呼び出し元に戻ると、承認されたユーザーは呼び出しサイトにあったものに戻ります。
これに対し、セッション ユーザーは、1 つの接続中に変更されることはありません。
SQL SECURITY DEFINERプロシージャ本体内で、session_user()は元のステートメントを発行したユーザーを引き続き返します。
各レイヤーでチェックされる権限
Azure Databricksは、各実行レイヤーで承認されたユーザーに対する特権をチェックします。
- セッション ユーザーは、最上位レベルのプロシージャまたは関数の
EXECUTEを保持し、最上位ビューでSELECTする必要があります。 セッション ユーザーは、親コンテナーにUSE CATALOGとUSE SCHEMAも必要です。 -
SQL SECURITY INVOKERプロシージャ本体内では、他のルーチンに対する入れ子になったEXECUTE呼び出しを含め、すべてのステートメントでセッション ユーザーの特権が使用されます。 -
SQL SECURITY DEFINERプロシージャ本体、ビュー本文、または SQL UDF 本文内では、すべてのステートメントで所有者の権限が使用されます。 セッション ユーザーは、本体が参照するオブジェクトに対する特権ではなく、外部ルーチンを呼び出す権限のみを必要とします。
Example
この例では、さまざまなユーザーが所有するビュー、SQL UDF、およびストアド プロシージャをチェーンします。 各レイヤーは下のレイヤーから読み取るので、承認は完全なスタックを走査します。 この例では、3 人のユーザー (Athos、Porthos、および Aramis) を使用し、最上位のプロシージャにのみアクセスできる Aramis がチェーンを呼び出すとどうなるかをトレースします。
セットアップ
Athos は 2 列のテーブルを作成し、Porthos に読み取りアクセスを許可します。
-- Run as Athos.
> CREATE TABLE t(a INT, b INT);
> INSERT INTO t VALUES (1, 10), (2, 20), (3, 30);
> GRANT SELECT ON TABLE t TO `porthos@musketeers.fr`;
Porthos は、Athos のテーブルに対するビューを作成し、そのビューに対する Athos の読み取りアクセス権を付与します。
-- Run as Porthos.
> CREATE VIEW v_p AS
SELECT a, b * 100 AS b100 FROM t;
> GRANT SELECT ON VIEW v_p TO `athos@musketeers.fr`;
Athos は Porthos のビューから読み取る SQL UDF を作成し、そのビューに Porthos EXECUTE を付与します。
-- Run as Athos.
> CREATE FUNCTION f_a(p INT) RETURNS INT
RETURN (SELECT b100 FROM v_p WHERE a = p);
> GRANT EXECUTE ON FUNCTION f_a TO `porthos@musketeers.fr`;
Porthos は、Athos の UDF からの結果を集計する SQL UDF と、結果を公開する SQL SECURITY DEFINER プロシージャを作成します。
-- Run as Porthos.
> CREATE FUNCTION f_p() RETURNS INT
RETURN f_a(1) + f_a(2) + f_a(3);
> CREATE PROCEDURE p_def()
LANGUAGE SQL
SQL SECURITY DEFINER
AS BEGIN
SELECT f_p();
END;
Athos は、Porthos のプロシージャを呼び出す SQL SECURITY INVOKER プロシージャを作成します。
-- Run as Athos.
> CREATE PROCEDURE p_inv()
LANGUAGE SQL
SQL SECURITY INVOKER
AS BEGIN
CALL p_def();
END;
最後に、Athos と Porthos はそれぞれ、チェーンを呼び出すために必要なものを Aramis に付与します。
p_invはSQL SECURITY INVOKERプロシージャであるため、本文は呼び出したユーザー (Aramis) として実行されるため、Aramis は個別にEXECUTEにp_defする必要があります。
-- Run as Athos.
> GRANT EXECUTE ON PROCEDURE p_inv TO `aramis@musketeers.fr`;
-- Run as Porthos.
> GRANT EXECUTE ON PROCEDURE p_def TO `aramis@musketeers.fr`;
Aramis には、 t、 f_a、 v_p、または f_pに対する特権はありません。
Aramis がチェーンを呼び出す
Aramis の問題:
-- Run as Aramis.
> CALL p_inv();
呼び出しチェーンは次のように展開され、各矢印が新しい本文に交差します。
Aramis's session
│
│ CALL
▼
p_inv() (Athos, SQL SECURITY INVOKER)
│
│ CALL
▼
p_def() (Porthos, SQL SECURITY DEFINER)
│
│ SELECT
▼
f_p() (Porthos's SQL UDF)
│
│ invokes
▼
f_a(p) (Athos's SQL UDF)
│
│ SELECT
▼
v_p (Porthos's view)
│
│ SELECT
▼
t (Athos's table)
次の表では、ステートメントを実行する方法について説明します。
| Step | ステートメント | これを実行しています。 | 承認されたユーザー | session_user() |
|---|---|---|---|---|
| 1 | CALL p_inv() |
アラミスのセッション | Aramis | Aramis |
| 2 | CALL p_def() |
p_invの本文 (SQL SECURITY INVOKER) |
Aramis (呼び出し元から継承) | Aramis |
| 3 | SELECT f_p() |
p_defの本文 (SQL SECURITY DEFINER) |
Porthos (プロシージャ所有者) | Aramis |
| 4 | RETURN f_a(1) + f_a(2) + f_a(3) |
SQL UDF の本文 f_p |
Porthos (関数所有者) | Aramis |
| 5 | RETURN (SELECT b100 FROM v_p WHERE a = p) |
SQL UDF の本文 f_a |
Athos (関数所有者) | Aramis |
| 6 | SELECT a, b * 100 AS b100 FROM t |
ビューの本文 v_p |
Porthos (ビュー所有者) | Aramis |
実行がアンワインドされると、承認されたユーザーは、手順 1 で Aramis のセッションに制御が戻るまで、レイヤーごとにレイヤーをポップバックします。