Data Engineer Associate — 第 13

誰に何を見せるか — Unity Catalog のアクセス制御とアイデンティティ統制

読了 25確認 12更新 2026-08-09

この章で学ぶこと

  • GRANT と USE CATALOG / USE SCHEMA の連鎖を作る
  • 継承の例外と MANAGE・所有権・DENY 非対応を区別する
  • 行フィルタと列マスクの構文と DBR 要件を覚える
  • ABAC ポリシーの構文とクォータを押さえる
  • アカウントグループとシークレットの前提を確認する

この章に出てくる用語

セキュラブルオブジェクト
権限を付ける単位です。Unity Catalog ではカタログ・スキーマ・テーブル・ビュー・ボリューム・関数などが該当し、GRANT SELECT ON TABLE main.sales.orders のように種別と名前で指定します。
USE CATALOG / USE SCHEMA
子オブジェクトへ到達するための通行許可です。データ自体は読めず、テーブルを SELECT するにはカタログの USE CATALOG、スキーマの USE SCHEMA、テーブルの SELECT が三つ揃う必要があります。
MANAGE 権限
権限の付与、所有権の移譲、名前変更、削除を許す権限です。所有者と違い SELECT や MODIFY は自動では付かず、自分自身へ付与して補います。ALL PRIVILEGES にも含まれない点が要注意です。
行フィルタ (Row Filter)
見せる行を絞るテーブル属性です。BOOLEAN を返す SQL UDF を ALTER TABLE t SET ROW FILTER fn ON (region) で紐づけ、TRUE の行だけを残します。1 テーブルに 1 つだけ設定できます。
列マスク (Column Mask)
列の値を変換して見せる仕組みです。ALTER TABLE t ALTER COLUMN ssn SET MASK mask_ssn で設定し、UDF の戻り型は対象列の型へキャスト可能である必要があります。1 列につき 1 つまでです。
ガバナンスタグ
アカウントレベルで定義され、付与権限が制御されたタグです。ABAC の MATCH COLUMNS で has_tag_value('pii','ssn') のように参照します。通常のタグや TBLPROPERTIES は使えません。
アカウントグループ
アカウントコンソールで管理されるグループです。Unity Catalog のデータ権限を付与できるのはこちらだけで、ワークスペースローカルグループには付与できません。account users は全員を含むシステムグループです。
シークレットスコープ
資格情報の入れ物です。dbutils.secrets.get(scope, key) で取得し、値の表示は [REDACTED] に伏せられます。名前は最大 128 文字、ACL は READ / WRITE / MANAGE の 3 段階です。

Unity Catalog の権限モデル — GRANT / REVOKE と USE の連鎖、継承の例外、MANAGE と所有権、DENY 非対応

Unity Catalog で `GRANT SELECT ON TABLE main.sales.orders TO `analysts`` を実行したのに、そのグループの利用者がクエリを投げると `PERMISSION_DENIED` で失敗する。原因は権限の種類ではなく、権限の連鎖を組み立てていないことにあります。

メタストアの下にカタログ、スキーマ、テーブルが並ぶ三段構造そのものは深追いしません。押さえるのは「三段のどこに何を GRANT すると、どこまで効くか」です。

GRANT / REVOKE / SHOW GRANTS の構文

権限操作の構文は 3 つだけです。付与は `GRANT privilege_types ON securable_object TO principal`、取り消しは `REVOKE privilege_types ON securable_object FROM principal`、確認は `SHOW GRANTS [principal] ON securable_type securable_name` です。付与が `TO`、取り消しが `FROM` の違いが引っかけに使われます。

GRANT SELECT ON TABLE main.sales.orders TO `analysts`;
REVOKE MODIFY ON TABLE main.sales.orders FROM `analysts`;
SHOW GRANTS `analysts` ON TABLE main.sales.orders;

選択肢には存在しない構文が並びます。`SHOW PERMISSIONS`、`LIST GRANTS FOR`、`DESCRIBE PRIVILEGES`、`CREATE ROLE`、`GRANT OWNERSHIP`、`ALTER TABLE ... ADD READER` はいずれも Databricks SQL にありません。`INFORMATION_SCHEMA` も読み取り専用で、`INSERT` による権限変更はできません。

プリンシパルはユーザー・グループ・サービスプリンシパルの 3 種類です。ユーザーはメールアドレス、サービスプリンシパルはアプリケーション ID で指定し、特殊文字を含む名前はバッククォートで囲みます。クラスタ ID やジョブ ID は指定できません。

GRANT と REVOKE は加減算モデルです。`GRANT SELECT, MODIFY` のあとに `REVOKE MODIFY` を実行すれば SELECT だけが残ります。REVOKE が外すのは書いた権限だけで、別の権限にも、別のプリンシパルにも、別のオブジェクトにも連鎖しません。`REVOKE ALL PRIVILEGES ON SCHEMA sales_db.sales` を実行しても、親カタログに付けた `USE CATALOG` はそのまま残ります。付与されていない権限を REVOKE してもエラーにはならず成功します。GRANT に有効期限はなく、期間限定のアクセスは期間終了後に REVOKE するジョブで実現します。

古い問題文やスクリプトでは `GRANT USAGE ON CATALOG sales_db TO `data_analyst`` も見かけます。`USAGE` はレガシーの Hive メタストア用テーブルアクセス制御にあった権限で、それ自体は操作を許さず、スキーマのオブジェクトを触るための追加要件として働きました。Unity Catalog での正式名が `USE CATALOG` と `USE SCHEMA` です。捏造構文だと早合点しないでください。

権限の名前と、それが許す操作

権限許すこと
SELECTテーブル・ビューの読み取り
MODIFYINSERT / UPDATE / DELETE / MERGE の書き込み
CREATE TABLEスキーマ配下へのテーブル作成
EXECUTESQL UDF の呼び出し
READ VOLUMEボリューム内のファイル読み取り
BROWSEデータを読ませずメタデータを閲覧させる
APPLY TAGタグの追加・編集
USE CATALOG / USE SCHEMA子オブジェクトへ到達する通行許可
MANAGE権限付与・所有権移譲・名前変更・削除

読み取り専用の要件に `ALL PRIVILEGES` が過剰なのは、MODIFY まで付くためです。

USE CATALOG と USE SCHEMA の連鎖

子オブジェクトへ到達するには親の通行許可が要ります。カタログには `USE CATALOG`、スキーマには `USE SCHEMA` が必要で、この 2 つはデータへのアクセス権を一切与えません。逆に、どちらかが欠けるとテーブルに SELECT を持っていても親階層をたどれず失敗します。冒頭の `PERMISSION_DENIED` の正体はたいていこれです。

やりたいこと必要な権限の組み合わせ
テーブルを SELECT するカタログの USE CATALOG + スキーマの USE SCHEMA + テーブルの SELECT
マネージドテーブルを作るUSE CATALOG + USE SCHEMA + スキーマの CREATE TABLE
外部テーブルを作る上記に加えて外部ロケーションの CREATE EXTERNAL TABLE
SQL UDF を呼び出すUSE CATALOG + USE SCHEMA + 関数の EXECUTE
テーブルに GRANT する所有者または MANAGE + 親の USE CATALOG / USE SCHEMA

権限を配るための権限も連鎖の対象です。GRANT と REVOKE を実行できるのはそのオブジェクトの所有者、親カタログや親スキーマの所有者、そのオブジェクトに MANAGE を持つ利用者、メタストア管理者の 4 者で、いずれも親コンテナの利用権限が要ります。アカウント管理者である必要はなく、SELECT と MODIFY はデータ操作の権限であって権限管理の権限ではありません。

例外は `BROWSE` です。オブジェクトを発見しメタデータを閲覧してアクセス申請を行う権限で、`USE CATALOG` も `SELECT` も与えずに探索だけを許可します。中身は見せずにテーブルの存在だけ見せたい要件はこれで解きます。

継承する権限と、継承しない権限

親コンテナに付けた権限は現在および将来の子オブジェクトに継承されます。`GRANT SELECT ON SCHEMA main.sales TO `alice`` と書けば、後から作られるテーブルやビューにも SELECT が及びます。逆方向はなく、テーブルへの GRANT が親スキーマやカタログへ広がることはありません。

例外が 2 つあります。1 つ目はメタストアで、ここに付与した権限は配下のカタログにもテーブルにも継承されません。カタログに SELECT を付ければ配下のテーブルを読めるのとは扱いが違います。2 つ目は所有権で、カタログの所有者でも配下に他人が作ったテーブルの所有者にはなりません。ただし所有者は子オブジェクトを管理できます。

MANAGE と所有権、そしてカタログの専権操作

`MANAGE` は所有者に近い操作をまとめて許可する権限です。所有者との差は「データ操作権が自動で付くかどうか」です。

比較軸MANAGE 権限所有者 (OWNER)
権限の付与・取り消しできるできる
所有権の移譲・名前変更・削除できるできる
SELECT や MODIFY の自動付与付かない (自分自身へ付与は可能)所有者として操作できる
設定方法GRANT MANAGE ON ... TO ...ALTER ... OWNER TO ...
ALL PRIVILEGES に含まれるか含まれない該当なし

`ALL PRIVILEGES` は対象に適用できる権限をまとめて付与しますが、`MANAGE`・`EXTERNAL USE SCHEMA`・`EXTERNAL USE LOCATION` の 3 つは含みません。所有権の移譲は `ALTER <securable-type> <name> OWNER TO <principal>` で行い、実行できるのは GRANT と同じ 4 者です。所有者にはグループも指定できます。`GRANT OWNERSHIP` ではありません。

カタログ層には別に押さえる点が 2 つあります。`DROP CATALOG` と `ALTER CATALOG ... OWNER TO` はカタログの所有者かメタストア管理者だけの操作です。スキーマ作成は `CREATE SCHEMA` を持つ人なら誰でもでき、テーブルへの GRANT も所有者か MANAGE でできますが、カタログの削除と所有者変更は降りてきません。新しいカタログを作れるのはメタストアレベルで CREATE CATALOG を付与された利用者かメタストア管理者だけです。一般ユーザーの `CREATE CATALOG sales` が権限エラーになるのは設計どおりで、名前の衝突や言語設定が原因ではありません。

DENY は Unity Catalog では使えない

`DENY privilege_types ON securable_object TO principal` という構文は Databricks SQL に実在します。GRANT と同じく `TO` を使う点に注意してください。しかしこの機能はUnity Catalog ではサポートされず、レガシーの `hive_metastore` 配下にのみ適用されます。UC で「見せない」を実現する手段は REVOKE と、次節以降の行フィルタ・列マスク・ABAC ポリシーです。

拒否は明示・暗黙を問わず付与より優先され、スキーマへの拒否は配下の全オブジェクトへ、カタログへの拒否は配下の全スキーマへ暗黙的に及びます。解除は GRANT による上書きではなく同じ権限を REVOKE することで行い、`UNDENY` は存在しません。

確認 — 穴あけ 3

0 / 3

空欄を押すと選択肢が出ます。間違えても減点はありません。

Unity Catalog でテーブルを SELECT するには、テーブルの SELECT とカタログの USE CATALOG に加えて、スキーマの が必要です。

ALL PRIVILEGES には EXTERNAL USE SCHEMA、EXTERNAL USE LOCATION、そして が含まれません。

DENY ステートメントは Unity Catalog では未サポートで、 カタログとその配下オブジェクトにのみ適用できます。

行フィルタと列マスク — SET ROW FILTER / ALTER COLUMN SET MASK / USING COLUMNS、DBR 要件と非サポート事項

GRANT で解けるのは「このテーブルを見せるか、見せないか」までです。ところが現場の要件はもっと細かく、「営業担当には自分の担当地域の行だけ見せたい」「マイナンバーの列は人事だけ生の値、他部署は伏字」という形で来ます。部門ごとにテーブルやビューを複製すれば実現できますが、部門が 12 で対象テーブルが 40 枚なら 480 本になり、列が 1 つ増えるたびに全部を直すことになります。この困りごとに対する Unity Catalog の答えが行フィルタ (Row Filter)列マスク (Column Mask) です。

この 2 つが登場する前は、動的ビュー (Dynamic View) と呼ばれるパターンが使われていました。`CREATE VIEW` の定義の中に `CASE WHEN is_account_group_member('HR') THEN ssn ELSE '***-**-****' END` のような式や `WHERE current_user() = owner` のような条件を直接書き、ビュー側で可視範囲を分岐させる方法です。今も動きますが、守っている対象がビューなので、基礎テーブルへの直接アクセスを塞ぎ続ける運用が付いて回ります。行フィルタと列マスクは、この制御をテーブル本体へ移すための機能です。

行フィルタ — BOOLEAN を返す SQL UDF をテーブルに紐づける

行フィルタの実体は Unity Catalog に永続化されたSQL UDF です。戻り値の型は `BOOLEAN` でなければならず、`TRUE` を返した行だけがクエリ結果に残ります。`FALSE` はもちろん、`NULL` を返した行も除外される点が重要です。参照する列に NULL が混ざると意図せず行が消えるため、NULL を考慮した実装が要ります。ノートブックのセルで定義した一時 UDF や Hive Metastore の Java UDF は使えません。

CREATE FUNCTION main.sec.filter_region(region STRING)
RETURNS BOOLEAN
RETURN IF(is_account_group_member('admin'), true, region = 'US');

ALTER TABLE main.sales.orders SET ROW FILTER main.sec.filter_region ON (region);
ALTER TABLE main.sales.orders DROP ROW FILTER;

テーブル作成と同時に付ける場合は `CREATE TABLE employees(emp_name STRING, dept STRING) WITH ROW FILTER filter_emps ON (dept)` のように `WITH ROW FILTER <関数> ON (<列>)` を書きます。`ON (...)` には関数のパラメータに対応する列名のほか、STRING・数値・BOOLEAN・INTERVAL・NULL といった定数リテラルも渡せます。任意の SQL 式や他テーブルの列は渡せません。解除はテーブル単位の `ALTER TABLE t DROP ROW FILTER` で、列名は指定しません。行フィルタは 1 テーブルにつき 1 つだけです。

列マスク — 列定義に紐づけ、対象列の型に合わせて返す

列マスクも SQL UDF ですが、戻り値の要件が違います。戻り型はマスク対象列の型にキャスト可能である必要があり、BOOLEAN 固定でも STRING 固定でもありません。数値列を数値のままマスクすることもできます。マスク対象の列は関数の第 1 引数へ自動的に対応づけられ、2 つ目以降の引数は `USING COLUMNS` で渡します。

CREATE FUNCTION main.sec.mask_ssn(ssn STRING)
RETURNS STRING
RETURN CASE WHEN is_account_group_member('HR') THEN ssn ELSE '***-**-****' END;

CREATE TABLE main.hr.persons (name STRING, ssn STRING MASK main.sec.mask_ssn);
ALTER TABLE main.hr.persons ALTER COLUMN ssn SET MASK main.sec.mask_ssn;
ALTER TABLE main.hr.addr ALTER COLUMN address SET MASK main.sec.mask_pii USING COLUMNS (region);
ALTER TABLE main.hr.persons ALTER COLUMN ssn DROP MASK;

作成時は列定義の直後に `MASK <関数名>` を書きます。`MASKED BY` は他製品の構文で Databricks には存在せず、テーブル単位の `WITH MASK` や `SET MASK ... ON (...)` もありません。解除は必ず列を指定した `ALTER TABLE t ALTER COLUMN c DROP MASK` で行い、テーブル単位で一括解除する構文はありません。1 つの列に付けられるマスクは 1 つだけで、条件を組み合わせたい場合は `USING COLUMNS` で追加の列を渡し、1 つの関数の中で分岐します。

比較軸行フィルタ列マスク
制御するものどの行を見せるか列の値をどう変換して見せるか
UDF の戻り型BOOLEAN 固定 (TRUE の行だけ残る)対象列の型にキャスト可能な型
作成時の構文WITH ROW FILTER fn ON (col)col STRING MASK fn
既存への適用ALTER TABLE t SET ROW FILTER fn ON (col)ALTER TABLE t ALTER COLUMN c SET MASK fn
追加引数の渡し方ON (列 または 定数リテラル)USING COLUMNS (列 または 定数リテラル)
解除ALTER TABLE t DROP ROW FILTERALTER TABLE t ALTER COLUMN c DROP MASK
設定できる数1 テーブルにつき 1 つ1 列につき 1 つ (複数列に併用可)

偽の構文も型が決まっています。`CREATE ROW POLICY` は PostgreSQL や Snowflake の書き方です。`GRANT ROW FILTER` や `GRANT MASK` という権限種別も存在せず、行フィルタと列マスクは権限ではなくテーブルの属性です。`ADD CONSTRAINT` に寄せた書き方も誤りで、CHECK 制約とは別の機構です。

両者は同じテーブルに併用できます。評価順は行フィルタで行を絞ってから、残った行に列マスクを適用する順です。しかも適用のタイミングはデータソースから行が取得された直後で、述語・集計・並べ替えはすべてその後に評価されます。したがって `SELECT count(*)` でさえフィルタ通過後の行だけを数え、実行するユーザーによって返る値が変わります。

関数の中で誰が実行しているかを判定するには、専用の組み込み関数を使います。`is_account_group_member('HR')` はセッションユーザーがアカウントレベルのそのグループに所属していれば TRUE を返し、`current_user()` と `session_user()` は実行者の ID を返します。`current_database()` のようなセッション情報はユーザー属性ではないため使えません。管理者に全行を見せたい行フィルタは `RETURN IF(is_account_group_member('admin'), true, region = 'US')` と書きます。ここを `AND` でつなぐと、管理者ですら US 以外の行を見られなくなります。

設定・利用に必要な権限とランタイム

フィルタやマスクを割り当てるには、関数への `EXECUTE`、関数のスキーマへの `USE SCHEMA`、親カタログへの `USE CATALOG` が必要です。加えて、既存テーブルへ設定・解除する場合はテーブルの所有者であるか、MANAGE と SELECT の両方を持つ必要があります。新規テーブルとして作る場合はスキーマの `CREATE TABLE`、列を追加するなどスキーマ変更を伴う文ではさらに `MODIFY` が要ります。列単位の `GRANT MASK` のような権限は存在しません。

コンピュートの種類行フィルタ / 列マスクを使う要件
SQL ウェアハウスそのまま利用できる
標準アクセスモードDatabricks Runtime 12.2 LTS 以上
専用アクセスモード15.4 LTS 以上で読み取り (書き込みは 16.3 以上)
DBR 12.2 LTS 未満非対応。安全側に倒れてデータが返らない
パーティション列にポリシーがある表への DELETE / UPDATE / MERGE17.2 以上

12.2 LTS 未満のクラスタから読んだときに全行が返ってしまうことはありません。古いランタイムでポリシーを回避して生データを読む抜け道はない、と覚えてください。

効かない場所と、壊しやすい操作

ポリシーはビューそのものには適用できません。ただし基礎テーブルに付いたポリシーはビュー経由のアクセスでもセッションユーザーの ID で評価されるため、ビューを挟んで回避することはできません。同様に、クラウドストレージのパスを直接指定するファイルアクセスも非サポートで、テーブル名を通さない抜け道は塞がれています。

  • タイムトラベル、DEEP CLONE / SHALLOW CLONE は非サポートです。クローン前提のバックアップ運用は設計を見直す必要があります。
  • MERGE は、ポリシーに入れ子・集計・ウィンドウ関数・LIMIT・非決定的関数が含まれると失敗します。含まなければ実行できます。
  • 生成列 (generated column) から参照されている列にはマスクを適用できません。
  • Python UDF や Scala UDF はそのままでは指定できず、SQL UDF でラップする必要があります。
  • ポリシー関数の中で、行フィルタや列マスクが有効な別テーブルを参照することはできません。循環依存も不可です。
  • Delta Lake API や Iceberg REST カタログ経由のアクセスも対象外です。
  • ANSI_MODE が無効な状態で引数の型にキャストできない値があると、エラーにならず静かに NULL へ変換されます。

運用で最も壊しやすいのは関数の削除順序です。テーブルに割り当てられたままの UDF を先に `DROP FUNCTION` すると、そのテーブルはアクセス不能な状態になります。必ず `ALTER TABLE ... ALTER COLUMN ... DROP MASK` または `ALTER TABLE ... DROP ROW FILTER` でポリシーを外してから関数を削除します。順序はどちらでもよい、という選択肢は誤りです。

もう 1 つの落とし穴がマテリアライズドビューとストリーミングテーブルです。これらではポリシーがパイプラインの実行 ID (run-as) で評価されます。その ID がフィルタやマスクの対象に含まれていると、マスク済みの値がそのまま実体化されて恒久的に残ります。パイプライン用のサービスプリンシパルは、次節の `EXCEPT` で除外しておくのが定石です。

確認 — 穴あけ 3

0 / 3

空欄を押すと選択肢が出ます。間違えても減点はありません。

行フィルタに使う SQL UDF の戻り値の型は でなければならず、FALSE を返した行と NULL を返した行が除外されます。

既存テーブルの列にマスクを設定する構文は ALTER TABLE t ALTER COLUMN ssn mask_ssn です。

手動で設定した行フィルタ・列マスクを標準アクセスモードで使うには、Databricks Runtime 以上が必要です。

ABAC ポリシー — CREATE POLICY / MATCH COLUMNS / has_tag_value / TO・EXCEPT とクォータ

前節の `ALTER TABLE` による手動適用には 2 つの弱点があります。1 つは、テーブルが増えるたびに人手で付け直す必要があり、翌週に作られたテーブルには何も効かないこと。もう 1 つは、テーブル所有者が自分で外せてしまい、統制する側とされる側が同じ人になることです。これを解くのがABAC (属性ベースアクセス制御) です。テーブルを名指しする代わりに「pii タグが付いた列」という属性でポリシーを書き、カタログやスキーマに 1 度貼れば配下へ自動的に効かせます。

ガバナンスタグが前提になる

ABAC の条件に使える属性は、アカウントレベルで定義され付与権限が制御されたガバナンスタグに限られます。誰でも自由に付けられる通常のタグでは動きません。Delta の `TBLPROPERTIES` もタグとは別の仕組みで、条件には使えません。タグの変更がポリシー評価に反映されるまでには数分かかります。

CREATE POLICY の構文

CREATE [OR REPLACE] POLICY policy_name
ON { CATALOG c | SCHEMA s | TABLE t }
[COMMENT description]
{ ROW FILTER fn | COLUMN MASK fn }
TO principal [, ...]
[EXCEPT principal [, ...]]
FOR TABLES
[WHEN condition]
[MATCH COLUMNS condition [AS alias] [, ...]]
ON COLUMN alias              -- COLUMN MASK では必須
[USING COLUMNS (arg [, ...])]

紐づけ先はカタログ・スキーマ・テーブルの 3 つで、メタストアやワークスペースには付けられません。角括弧の付き方そのものが正誤判定になります。`TO` と `FOR TABLES` は省略できない必須句で、`ON COLUMN` は列マスクでは必須・行フィルタでは書きません。任意なのは `COMMENT`・`EXCEPT`・`WHEN`・`MATCH COLUMNS`・`USING COLUMNS` です。`WHEN` を省略すると条件は TRUE 扱いになり、配下の全テーブルが対象になります。

`TO` にはポリシーを適用するプリンシパル、`EXCEPT` には適用から免除するプリンシパルを書きます。管理者や ETL 用サービスプリンシパルを `EXCEPT` に入れ、マスクなしで処理させる設計が定番です。前節で触れたパイプラインの run-as も、ここで除外します。

`MATCH COLUMNS` は対象列を特定して `AS` で別名を付ける句で、条件には 2 つの関数を使います。`has_tag('pii')` はタグのキーが付いているかだけを見て値は問わず、`has_tag_value('pii', 'ssn')` はキーと値の組で絞り込みます。pii が付いた列を一律に伏せるなら前者、pii の値が ssn の列だけを狙うなら後者です。条件は AND / OR / NOT で組み合わせられます。列マスクではさらに `ON COLUMN <別名>` で、一致した列のうちどれにマスクを掛けるかを指定し、行フィルタでは `USING COLUMNS` で別名を UDF の引数として渡します。

CREATE POLICY mask_pii ON CATALOG prod
COLUMN MASK prod.governance.mask_value
TO `account users` EXCEPT `etl_service_principal`
FOR TABLES
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn
ON COLUMN ssn;

管理系の構文も 3 つ覚えます。一覧は `SHOW [EFFECTIVE] POLICIES ON { CATALOG | SCHEMA | TABLE } <名前>`、詳細は `DESCRIBE POLICY <名前> ON ...`、削除は `DROP POLICY <名前> ON ...` です。作成・編集・削除・参照のすべてに、対象セキュラブルの所有権または MANAGE 権限が必要で、加えてポリシーが使う UDF への EXECUTE が要ります。テーブルへの SELECT だけでは触れませんし、メタストア管理者に限定されているわけでもありません。

この一点が ABAC の職務分離を成立させています。ポリシーはカタログやスキーマの管理者が貼るため、配下のテーブル所有者は自分のテーブルに掛かったマスクを上書きも解除もできません。手動適用ではテーブル所有者が自分で `DROP MASK` できてしまうのと対照的です。

クォータと競合、そして手動適用との使い分け

項目上限
メタストアあたりのポリシー数10,000
カタログまたはスキーマあたり100
テーブルあたり50
1 ポリシーの TO と EXCEPT の合計プリンシパル数20
MATCH COLUMNS の列条件数3

実行環境の要件は手動適用とは別物です。ABAC ポリシーにはサーバーレスコンピュート、または Databricks Runtime 16.4 以上の標準/専用コンピュートが必要で、専用の場合はきめ細かなアクセス制御によるフィルタリングを有効にします。手動適用の 12.2 LTS とは数字が違う点が狙われます。

競合の扱いも重要です。あるユーザーと 1 つのテーブルに対して実行時に解決される行フィルタは 1 つ、1 つの列に解決される列マスクも 1 つでなければなりません。複数の異なるものが該当すると、AND で合成されることも作成順で優先されることもなく、アクセスが拒否されます。`TO` と `EXCEPT` で範囲を切り分け、重ならないよう設計します。ビューに直接適用できないこと、タイムトラベルとクローンが使えないことは手動適用と同じです。

比較軸ABAC ポリシー手動の ALTER TABLE 適用
付ける場所カタログ / スキーマ / テーブルテーブル (と列)
新規テーブルへの追随タグが付けば自動で効く効かない。都度設定が必要
管理する人上位のガバナンス管理者テーブル所有者
所有者による解除できない (職務分離が成立)できる
向く場面多数テーブルへの一貫適用テーブル固有のロジック
コンピュート要件サーバーレスまたは DBR 16.4 以上SQL ウェアハウスまたは DBR 12.2 LTS 以上

確認 — 穴あけ 3

0 / 3

空欄を押すと選択肢が出ます。間違えても減点はありません。

ABAC ポリシーの TO 句と EXCEPT 句に指定できるプリンシパルは、1 ポリシーあたり合計 までです。

ABAC ポリシーの作成・編集・削除・参照には、対象セキュラブルの所有権または 権限が必要です。

ABAC ポリシーを使うには、サーバーレスコンピュートまたは Databricks Runtime 以上のコンピュートが必要です。

アイデンティティ・シークレット・ネットワークを統制する — アカウントグループ、Secret Scope、Serverless Egress と NCC

ここまでの GRANT もポリシーも、宛先となる ID が正しく揃っていて初めて機能します。権限も行フィルタも正しく書いたのに効かない、という最後の落とし穴はアクセス制御の外側にあります。誰に配るか (アイデンティティ)、資格情報をどこに置くか (シークレット)、外へ出る通信をどう絞るか (ネットワーク) の 3 点を片付けます。

UC の権限はアカウントグループにしか付かない

Databricks のグループには 2 種類あります。アカウントコンソールで管理されるアカウントグループと、ワークスペース内で作られたレガシーのワークスペースローカルグループです。Unity Catalog のデータ権限を付与できるのはアカウントグループだけで、ワークスペースローカルグループには付与できず、他ワークスペースへの割り当てもアカウントレベルのロール付与もできません。GRANT がうまくいかないときは、グループ名の特殊文字やメンバー数ではなく、まずグループの種別を疑ってください。ワークスペースローカルグループが自動でアカウントグループへ昇格することもありません。

アカウント内の全ユーザーとサービスプリンシパルを含む `account users` というシステムグループが自動で用意されており、ABAC ポリシーの `TO` に指定する宛先としてよく使われます。ここへ広い権限を与えると事実上の全員公開になる点には注意します。前節で見た `is_account_group_member()` がアカウントレベルの所属だけを判定するのも、この設計に対応しています。

Secret Scope — 資格情報をノートブックに書かない

外部 API のキーや DB のパスワードをノートブックへ平文で書くと、UC の GRANT が一切効かない場所に機密が露出します。正しい置き場がシークレットスコープです。取得は `dbutils.secrets.get(scope="prod", key="api_key")` の 1 行で、取得した値は表示時に `[REDACTED]` に置き換えられます。`dbutils.fs.head` で読む経路や `spark.conf.get` で読む API は存在しません。

スコープ名はワークスペース内で一意で、英数字・ダッシュ・アンダースコア・`@`・ピリオドが使え、最大 128 文字、大文字小文字は区別されません。アクセス制御は `READ` / `WRITE` / `MANAGE` の 3 段階です。値を Databricks 側に保存するスコープと、Azure Key Vault の内容を読み出すスコープがありますが、取得コードはどちらも同じ `dbutils.secrets.get` です。

サーバーレスの外向き通信を絞る

サーバーレスコンピュートは Databricks 側の基盤で動くため、顧客 VPC のセキュリティグループでは制御できません。公式の手段は 2 つです。1 つはServerless Egress Control で、許可したドメイン (FQDN) 宛だけにアウトバウンドを限定します。もう 1 つがNCC (Network Connectivity Configuration) で、こちらの中核用途はサーバーレスの送信元 IP を安定させることです。接続元 IP を allowlist で絞っている Snowflake などの外部サービスへ接続するとき、この固定化がないと通してもらえません。

NCC はアカウント管理者がアカウントコンソールで作るリージョン単位のオブジェクトで、プライベートエンドポイントを束ねる役割も持ち、ワークスペースへアタッチして使います。宛先を絞るのが Egress Control、出口に固定の名札を付けるのが NCC、と役割で分けて覚えます。サーバーレスは全エグレスを遮断していて外部 API を呼べない、という説明は誤りです。

この 3 つは、いずれも「テーブルに GRANT を書く」だけでは塞げない穴に対応しています。アカウントグループを整えなければ権限の宛先が定まらず、シークレットスコープを使わなければ資格情報が UC の外に漏れ、外向き通信を絞らなければ許可された利用者がデータを外部へ持ち出せます。アクセス制御は、この 3 層が揃って初めて意図どおりに働きます。

確認 — 穴あけ 3

0 / 3

空欄を押すと選択肢が出ます。間違えても減点はありません。

Unity Catalog のデータ権限を付与できるのは グループで、ワークスペースローカルグループには付与できません。

シークレットスコープ名は最大 文字で、大文字小文字は区別されません。

サーバーレスの送信元 IP を安定させ、IP allowlist を持つ外部サービスへ接続できるようにするのは です。

この章のまとめ

  1. テーブル読み取りは USE CATALOG + USE SCHEMA + SELECT の三点セットです
  2. 権限は親から子へ継承しますが、メタストアと所有権は継承しません
  3. 行フィルタは BOOLEAN 固定で 1 テーブル 1 つ、列マスクは 1 列 1 つです
  4. 手動適用は DBR 12.2 LTS 以上、ABAC はサーバーレスか DBR 16.4 以上です
  5. UC の権限はアカウントグループにしか付かず、DENY は UC では使えません

この端末にだけ保存されます(登録不要)

この章の根拠

最終確認 2026-08-09 / 対応バージョン DEA 2026-05-04 改訂版

コース全体

  1. Databricks とレイクハウスの全体像 — なぜ必要か、何がどこに属し、どの計算資源で動くか
  2. データはどこに、どんな形で保存されるか — テーブルの実体と Delta Lake の内部
  3. 計算資源を作り込み、コードを書く場所を決める — クラスタ設定とノートブック/ローカル IDE
  4. Spark はどう動き、SQL で何をどこまで書けるか
  5. PySpark でデータを加工し、遅いコードを見抜く
  6. 流れ込むデータを受け止める — Structured Streaming と Auto Loader のファイル検出
  7. 取り込み時にスキーマをどう扱うか — Auto Loader のスキーマ進化と COPY INTO
  8. ファイル以外からも取り込む — read_files・Lakeflow Connect・JDBC と API
  9. 生データを使える形に育てる — メダリオン設計と宣言的パイプライン
  10. 処理を1つのジョブに束ねる — タスク種別と依存関係の設計
  11. ジョブを動かし、失敗から立て直す — トリガー・リトライ・パラメータ
  12. 書いたものを安全に本番へ届ける — Git 連携とデプロイの自動化
  13. 誰に何を見せるか — Unity Catalog のアクセス制御とアイデンティティ統制
  14. 誰が何をしたか、いくらかかったか、どこで詰まったかを見る
  15. テーブルを保守して速くする — 運用コマンド・保持期間・レイアウト設計・障害復旧
  16. DEA 直前仕上げ — 方式選定・出題範囲対応表・数値総まとめ・引っかけの型