Databricksの監査ログ・課金情報のシステムテーブルをワークスペース単位で分離する方法

# はじめに
Databricksの一般的な利用形態として、1つのDatabricksアカウントを複数の組織で共有するケースがあります。例えば、企業内の複数部門や企業グループ内の複数の関連会社がそれぞれ独自のワークスペースを持ち、運用するといった形です。

このような環境では通常、中央ITチームがDatabricksアカウント全体を管理し、必要に応じて各組織にワークスペースを払い出します。この際によくある課題が、中央ITチームとしては「各組織には自分たちのワークスペースに関連する課金情報や監査ログだけを見せたい（他組織の情報は見せたくない）」というものです。しかし、Databricksの[システムテーブル](https://learn.microsoft.com/ja-jp/azure/databricks/admin/system-tables/)にはアカウント全体の情報が含まれているため、そのままでは他組織のワークスペースの情報も閲覧できてしまいます。

このブログでは、Unity Catalogの[ビュー](https://learn.microsoft.com/ja-jp/azure/databricks/views/create-views)を活用して、各組織が自組織のワークスペースに関連する監査ログと課金情報のみを参照できる環境を構築する方法を紹介します。

# 環境構成と要件
本記事では、ABCフィナンシャルグループ (FG) という架空の金融グループ会社を想定します。ABC FGではメインリージョンとしてAzure東日本リージョンを利用します。

:::note information
**本記事の内容はクラウドを問いません**

本記事ではAzure Databricksを例としています。若干手順の読み替えが必要な箇所はありますが、Databricks on AWS、Databricks on Google Cloudでも同様の構成が可能です。
:::

## 環境構成
環境構成は以下の図の通りです。

```mermaid
flowchart LR
    subgraph account["ABC-FG Databricksアカウント"]
        direction TB
        subgraph JP["Azure東日本リージョン"]
            IT["ABC-FG中央ITチーム<br>ワークスペース"]
            Bank["ABC銀行<br>ワークスペース"]
            Securities["ABC証券<br>ワークスペース"]
            MS_JP["Unity Catalog<br>メタストア"]
        end
    end

    IT --- MS_JP
    Bank --- MS_JP
    Securities --- MS_JP
    
    %% スタイル設定
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px
    classDef account fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    classDef region fill:#fff0e6,stroke:#cc6600,stroke-width:1px
    classDef workspace fill:#e6ffe6,stroke:#009900,stroke-width:1px
    classDef metastore fill:#f9e6ff,stroke:#9900cc,stroke-width:1px
    
    class account account
    class JP region
    class IT,Bank,Securities,US_Bank workspace
    class MS_JP metastore
```

<dl>
<dt>Databricksアカウント</dt>
<dd>ABCフィナンシャルグループ全体で1つのDatabricksアカウントを使用</dd>
</dl>
<dl>
<dt>Databricksワークスペース（いずれもAzure東日本リージョンを利用）</dt>
<dd>ABCフィナンシャルグループ中央ITチーム用ワークスペース</dd>
<dd>ABC銀行用ワークスペース</dd>
<dd>ABC証券用ワークスペース</dd>
</dl>

## 要件
ABCフィナンシャルグループの中央ITチームは、各社に対して以下の要件を満たす必要があります。

- ABC銀行には、ABC銀行のワークスペースに関連する監査ログ・課金データのみを見せる
- ABC証券には、ABC証券のワークスペースに関連する監査ログ・課金データのみを見せる
- 他社の情報を見られないようにする

## 対象とするシステムテーブル
本記事においてワークスペース単位の分離対象とするシステムテーブルは以下の3つです。

1. **監査ログ**: `system.access.audit`
1. **課金対象の使用状況システムテーブル**: `system.billing.usage`
1. **価格設定システムテーブル** `system.billing.list_prices`

各システムテーブルの詳細は以下のリンクをご覧ください。

https://learn.microsoft.com/ja-jp/azure/databricks/admin/system-tables/audit-logs

https://learn.microsoft.com/ja-jp/azure/databricks/admin/system-tables/billing

https://learn.microsoft.com/ja-jp/azure/databricks/admin/system-tables/pricing

:::note information
**システムテーブルによるワークスペースレベル情報の有無**

監査ログテーブルと課金対象の使用状況テーブルには、ワークスペースレベルの情報が含まれています。一方、価格設定テーブルはSKU価格の履歴ログであり、ワークスペース固有の情報は含まれていません。そのため、後段のステップではワークスペースIDによるフィルタを行う必要がありません。
:::

# 実装方法
要件を満たすために、以下の構成を実装していきます。

1. 中央ITチーム管理者グループのみが `system` カタログへのアクセス権を持つ
1. 中央ITチーム管理者グループが所有者となり各社共有用の `shared_system` カタログを作成する
1. 中央ITチームが `shared_system` カタログ配下に各社用のスキーマを作成し、各社に読み取りアクセス権を付与する
1. システムテーブルからワークスペースIDでフィルタした監査ログ・課金情報のシステムテーブルのビューを各社のスキーマに作成する
1. 各社ワークスペースと `shared_system` カタログをワークスペースバインディングで接続する

```mermaid
flowchart TB
    subgraph central["中央ITチーム環境"]
        central_it_ws["中央ITチーム<br>ワークスペース"]
        central_it_admins["中央ITチーム<br>管理者グループ"]
        
        central_it_ws --- central_it_admins
        
        subgraph system_catalog["system (カタログ)"]
            access.audit
            billing.usage
            billing.list_prices
        end
        
        subgraph shared_system_catalog["shared_system (カタログ)"]
            subgraph abc_bank_schema["abc_bankスキーマ"]
                bank_access_audit["access_audit<br>(ビュー)"]
                bank_billing_usage["billing_usage<br>(ビュー)"]
                bank_billing_list_prices["billing_list_prices<br>(ビュー)"]
            end
            
            subgraph abc_securities_schema["abc_securitiesスキーマ"]
                sec_access_audit["access_audit<br>(ビュー)"]
                sec_billing_usage["billing_usage<br>(ビュー)"]
                sec_billing_list_prices["billing_list_prices<br>(ビュー)"]
            end
        end
        
        central_it_admins -- "アクセス権" --> system_catalog
        central_it_admins -- "所有者" --> shared_system_catalog
        abc_securities_schema -- "参照" --> system_catalog
        abc_bank_schema -- "参照" --> system_catalog
    end
    
    subgraph customer_ws["各社ワークスペース"]
        abc_bank_ws["ABC銀行<br>ワークスペース"]
        abc_bank_admins["ABC銀行<br>管理者グループ"]
        abc_sec_ws["ABC証券<br>ワークスペース"]
        abc_sec_admins["ABC証券<br>管理者グループ"]
        
        abc_bank_ws --- abc_bank_admins
        abc_sec_ws --- abc_sec_admins
    end
    
    abc_bank_admins -- "アクセス権" --> abc_bank_schema
    abc_sec_admins -- "アクセス権" --> abc_securities_schema

    %% スタイル設定
    classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px;
    classDef environment fill:#e6f3ff,stroke:#0066cc,stroke-width:2px;
    classDef workspace fill:#e6ffe6,stroke:#009900,stroke-width:1px;
    classDef catalog fill:#fff0e6,stroke:#cc6600,stroke-width:1px;
    classDef schema fill:#f9e6ff,stroke:#9900cc,stroke-width:1px;
    
    %% クラスの適用
    class central,customer_ws environment;
    class central_it_ws,abc_bank_ws,abc_sec_ws workspace;
    class system_catalog,shared_system_catalog catalog;
    class abc_bank_schema,abc_securities_schema schema;
```

## 1. 環境準備
以下の環境が既に準備されていることを前提とします。

- **Azure Databricksワークスペース**
  - 中央ITチーム用ワークスペース
  - ABC銀行用ワークスペース
  - ABC証券用ワークスペース
- **各ワークスペースは同一のメタストアに関連付けられている**
- **アカウントグループ**
  - 中央ITチーム管理者グループ
  - ABC銀行管理者グループ
  - ABC証券管理者グループ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/d229c376-98b2-4d67-9bcd-6ff039fc5f1f.png)
|:-:|
*本記事で使用するAzure Databricksワークスペース*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/0999eab0-29ad-4fd5-bcbe-a7c8dab932aa.png)
|:-:|
*ワークスペースに同一のメタストアを割り当て*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/4d89623e-7a0e-4d8a-a0b2-bcb8e9ca2a5e.png)
|:-:|
*本記事で使用するアカウントグループ*

## 2. 各ワークスペースにアカウントグループをワークスペース管理者グループとして登録
アカウントコンソール ([https://accounts.azuredatabricks.net](https://accounts.azuredatabricks.net)) で、各ワークスペースの管理者グループを登録します。

1. アカウントコンソールの各ワークスペースの[権限]タブにアクセス
1. 該当するアカウントグループをワークスペース管理者 (`Admin`) として追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/5ab6d6a6-640f-44a4-a5eb-97980b8ae060.png)
|:-:|
*中央ITチーム用ワークスペースの管理者グループ（他ワークスペースも同様に設定）*

## 3. システムスキーマを有効化
中央ITチーム用ワークスペースでシステムスキーマを有効化します。これにより、監査ログや課金情報にアクセスできるようになります。

以下のQiita記事を参考に、Databricks SDK for Pythonを使って有効化するのが楽です。

https://qiita.com/nakazax/items/6ec113daadb8b52584fb

:::note information
**システムスキーマ有効化の備考**

- システムスキーマの有効化を実行するユーザーは、アカウント管理者の権限を持っている必要があります
- 上記Qiita記事は、有効化可能なすべてのシステムスキーマを有効化する実装になっています。有効化対象のシステムスキーマを絞り込みたい場合は、一部書き換えて実行してください
:::

### システムスキーマ有効化後の見え方：アカウント管理者
システムスキーマを有効化後、アカウント管理者の権限を持つユーザーのカタログエクスプローラーには、システムスキーマの一覧が表示され、各テーブルにSELECTができる状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/deddb8b3-7481-4a65-9514-c81bd552668d.png)
|:-:|
*カタログ：アカウント管理者に`USE CATALOG`が付与されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/87f9e3b2-61ae-4d4d-9705-7dc5f465128f.png)
|:-:|
*スキーマ：アカウント管理者に`USE SCHAME`が付与されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/a709497a-9734-4da4-9d8d-3119c1ef0764.png)
|:-:|
*テーブル：アカウント管理者に`SELECT`が付与されている*

### システムスキーマ有効化後の見え方：非アカウント管理者
アカウント管理者の権限を持たないユーザーのカタログエクスプローラーには、システムスキーマ有効化前と同様、`system.ai`スキーマと`system.information_schema`スキーマのみが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/e7e843f8-1608-42fc-b122-d209cbddc70a.png)
|:-:|
*カタログ：All account usersに`USE CATALOG`が付与されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/403c4b6c-0ce3-42a8-a138-ed6c33d35114.png)
|:-:|
*`system.ai`スキーマ：All account usersに各種権限が付与されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/9d3facb1-f005-45cb-b3fd-b32550eb2218.png)
|:-:|
*`system.information_schema`スキーマ：All account usersに`USE SCHAME`が付与されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/ef64b912-6453-41f0-83be-0b73cde41c39.png)
|:-:|
*`system.information_schema`スキーマ配下のテーブル：All account usersに`SELECT`が付与されている*

## 4. `shared_system` カタログを作成
続いて、各組織のワークスペースへの共有用のカタログ `shared_system` を、中央ITチームのAzureポータルおよびDatabricksワークスペースを通じてセットアップしていきます。

### Azureポータル：ストレージアカウント & コンテナーの作成
まずは、Azureポータルにアクセスし、カタログのパスとして設定するストレージアカウントおよびコンテナーを作成します。ストレージアカウント作成時に、階層型名前空間を有効にすることを失念しないようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/b314c3d2-bc9c-47ad-9747-1e3f277def4c.png)
|:-:|
*新しいストレージアカウントの作成*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/2d38e02f-89ef-44c9-a1de-a3721f476c06.png)
|:-:|
*新しく作成したコンテナー*

### Azureポータル：アクセスコネクターの作成と権限付与
続いて、Azure Databricksのアクセスコネクターを作成し、先ほど作成したストレージアカウントに対する`ストレージBLOBデータ共同作成者`の権限を付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/ef15ee02-2c79-4229-9994-50c8f6fe93eb.png)
|:-:|
*新しいアクセスコネクターの作成*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/696f97cd-d016-46eb-8f61-8073b960958b.png)
|:-:|
*アクセスコネクターのストレージアカウントに対する権限*

### Databricksワークスペース：メタストアレベルの権限付与
この後、ストレージ資格情報、外部ロケーション、カタログを作成していきます。メタストアレベルで以下の権限を持っていることを確認し、不足している場合には付与しておきます。

- `CREATE CATALOG`
- `CREATE EXTERNAL LOCATION`
- `CREATE STORAGE CREDENTIAL`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/56ba42d8-9343-4632-a70e-03d71f7fa949.png)
|:-:|
*メタストアレベルの権限付与*

### Databricksワークスペース：ストレージ資格情報の作成・管理
続いて、Azure Databricksワークスペースにて、新しいストレージ資格情報を作成します。ここでは `abc_cred_shared_system` という名前にします。

アクセスコネクターIDには、Azureポータル上でアクセスコネクターの概要ページのリソースIDからコピーした値を貼り付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/8693fcc1-88f9-4532-b5e3-f40f35e81bf0.png)
|:-:|
*ストレージ資格情報の作成*

#### 推奨設定：所有者をグループに変更
Unity Catalogではオブジェクトを作成したユーザーが自動的に所有者になるため、忘れずに所有者をグループに変更しておくのが良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/a5350907-0ef4-45cd-819e-29f338148bac.png)
|:-:|
*作成直後はユーザーが所有者*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/fb3f0eaf-56f6-4ad4-9116-0233ce445c78.png)
|:-:|
*所有者をグループに変更*

#### 推奨管理：必要なワークスペースのみにバインディングを変更
ストレージ資格情報について、作成直後はすべてのワークスペースにバインディングされますが、必要なワークスペースのみにバインディングを変更しておくのが良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/32adb99c-cfda-45ae-9bb2-223bd01d017b.png)
|:-:|
*中央ITチーム用ワークスペースにのみバインディング*

### Databricksワークスペース：外部ロケーションの作成・設定
続いて、新しい外部ロケーションを作成します。ここでは `abc_extloc_shared_system` という名前にします。

- 作成後、接続のテストを行い、すべて成功することを確認します
- 推奨設定：所有者をグループに変更
- 推奨設定：必要なワークスペースのみにバインディングを変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/046daabd-0d0e-42e8-97c1-28e9f45dba7e.png)
|:-:|
*外部ロケーションの作成*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/8107364d-ff0a-4595-bf6a-5f54ce5372e9.png)
|:-:|
*接続のテスト*

### Databricksワークスペース：カタログの作成
続いて、新しいカタログを作成します。ここでは `shared_system` という名前にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/18614878-7f19-4b7c-8691-98d58479ac07.png)
|:-:|
*カタログの作成*

### Databricksワークスペース：カタログの設定
引き続きカタログの設定を行います。

- 必要なワークスペースのみにバインディングを変更
    - ここでは、中央IT、銀行、証券のワークスペースにバインディング
- 所有者をグループに変更
- 権限は一旦なしにする
    - デフォルトはAll account usersへの`BROWSE`権限だが、これを削除

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/ac93ac6b-5b0e-42ed-94af-19fd643fea8b.png)
|:-:|
*カタログの設定1*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/4aa5170e-f7a0-4948-aa72-49e94f5d6b91.png)
|:-:|
*カタログの設定2*

## 5. 各社のスキーマ作成と所有者の変更
SQLエディタで以下のSQLを実行し、各社のスキーマ作成と所有者の変更を行います。

```sql:各社のスキーマ作成と所有者の変更
-- スキーマ作成
CREATE SCHEMA IF NOT EXISTS shared_system.abc_central_it COMMENT 'Schema for ABC Central IT system tables';
CREATE SCHEMA IF NOT EXISTS shared_system.abc_bank COMMENT 'Schema for ABC Bank system tables';
CREATE SCHEMA IF NOT EXISTS shared_system.abc_securities COMMENT 'Schema for ABC Securities system tables';

-- 所有者の変更
ALTER SCHEMA shared_system.abc_central_it OWNER TO `ABC Central IT Admin Group`;
ALTER SCHEMA shared_system.abc_bank OWNER TO `ABC Central IT Admin Group`;
ALTER SCHEMA shared_system.abc_securities OWNER TO `ABC Central IT Admin Group`;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/3cb6bfd7-2890-40e2-a325-d5de238d6805.png)
|:-:|
*スキーマ作成・所有者変更の実行結果*

## 6. 各社のビュー作成
SQLエディタで以下のSQLを実行し、各社のビュー作成と所有者の変更を行います。冒頭の変数宣言の`catalog_schema`と`workspace_id`を各社の値に変更し、ワークスペース数と同じ回数、実行します。

```sql:各社のビュー作成と所有者の変更
DECLARE catalog_schema = 'shared_system.abc_securities.';
DECLARE workspace_id = '3920382974887062';
DECLARE owner_principal = 'ABC Central IT Admin Group';

-- 監査ログの動的ビュー
DECLARE create_view_access_audit = "CREATE OR REPLACE VIEW " || catalog_schema || "access_audit AS SELECT * FROM system.access.audit WHERE workspace_id = '" || workspace_id || "'";
EXECUTE IMMEDIATE create_view_access_audit;

-- 課金使用状況の動的ビュー
DECLARE create_view_billing_usage = "CREATE OR REPLACE VIEW " || catalog_schema || "billing_usage AS SELECT * FROM system.billing.usage WHERE workspace_id = '" || workspace_id || "'";
EXECUTE IMMEDIATE create_view_billing_usage;

-- 価格設定の動的ビュー（ワークスペース固有情報なし）
DECLARE create_view_billing_list_prices = "CREATE OR REPLACE VIEW " || catalog_schema || "billing_list_prices AS SELECT * FROM system.billing.list_prices";
EXECUTE IMMEDIATE create_view_billing_list_prices;

-- 所有者を変更
DECLARE alter_view_access_audit = "ALTER VIEW " || catalog_schema || "access_audit OWNER TO `" || owner_principal || "`";
EXECUTE IMMEDIATE alter_view_access_audit;

DECLARE alter_view_billing_usage = "ALTER VIEW " || catalog_schema || "billing_usage OWNER TO `" || owner_principal || "`";
EXECUTE IMMEDIATE alter_view_billing_usage;

DECLARE alter_view_billing_list_prices = "ALTER VIEW " || catalog_schema || "billing_list_prices OWNER TO `" || owner_principal || "`";
EXECUTE IMMEDIATE alter_view_billing_list_prices;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/f9db1a69-f120-417c-8eb4-58b4007bd2fd.png)
|:-:|
*ビュー作成・所有者変更の実行結果*

## 7. 各管理者グループへの権限付与
各グループが適切な権限を持つように、カタログ、スキーマ、およびビューに対する権限を設定します。以下では、中央ITチーム、ABC銀行、およびABC証券の各管理者グループに対して必要な権限を付与するSQLステートメントを示します。

### 権限付与の概要
1. **中央ITチーム管理者グループ**
   - `shared_system`カタログに対する完全な管理権限（ALL PRIVILEGESとMANAGE）
2. **ABC銀行管理者グループ**
   - `shared_system`カタログの使用権限（USE CATALOG）
   - `abc_bank`スキーマの使用権限と読み取り権限（USE SCHEMAとSELECT）
3. **ABC証券管理者グループ**
   - `shared_system`カタログの使用権限（USE CATALOG）
   - `abc_securities`スキーマの使用権限と読み取り権限（USE SCHEMAとSELECT）

この権限設定により、各組織は自社のデータのみにアクセスでき、中央ITチームはすべてのリソースを管理できます。

```sql:各管理者グループへの権限付与
-- 中央ITチームの管理者グループに対する権限付与
-- shared_systemカタログにALL PRIVILEGESとMANAGEを付与
GRANT ALL PRIVILEGES ON CATALOG shared_system TO `central_it_admins`;
GRANT MANAGE ON CATALOG shared_system TO `central_it_admins`;

-- ABC銀行の管理者グループに対する権限付与
-- shared_systemカタログにUSE CATALOGを付与
GRANT USE CATALOG ON CATALOG shared_system TO `abc_bank_admins`;
-- abc_bankスキーマにUSE SCHEMAとSELECTを付与
GRANT USE SCHEMA ON SCHEMA shared_system.abc_bank TO `abc_bank_admins`;
GRANT SELECT ON SCHEMA shared_system.abc_bank TO `abc_bank_admins`;

-- ABC証券の管理者グループに対する権限付与
-- shared_systemカタログにUSE CATALOGを付与
GRANT USE CATALOG ON CATALOG shared_system TO `abc_securities_admins`;
-- abc_securitiesスキーマにUSE SCHEMAとSELECTを付与
GRANT USE SCHEMA ON SCHEMA shared_system.abc_securities TO `abc_securities_admins`;
GRANT SELECT ON SCHEMA shared_system.abc_securities TO `abc_securities_admins`;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/8a96a9b9-f3ba-421c-8757-5d705a0033e3.png)
|:-:|
*各管理者グループへの権限付与の実行結果*

## 8. `system`カタログへの権限付与
上記で各社グループの設定については完了したのですが、最後の設定作業として、`system`カタログに対して中央ITチームの管理者グループに以下の権限を設定する必要があります。

- `USE CATALOG`
- `USE SCHEMA`
- `SELECT`
- `MANAGE` (オプション)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/99142931-41a8-4106-a4cc-136c4e5ff2c1.png)
|:-:|
*`system`カタログへの権限付与*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/dcca5177-4b59-4c66-9756-d921a6b05afe.png)
|:-:|
*`system`カタログの権限一覧*

### `system`カタログ権限付与の前提条件
`system`カタログに権限を付与できるのは、メタストア管理者に属するグループのユーザーになります。

中央ITチームの管理者グループがメタストア管理者の権限を持っていない場合、当該グループを一時的にメタストア管理者に設定する必要があります。

`system`カタログへの権限付与後、メタストア管理者の設定は削除（既定の`System user`に戻す）しても問題ありません。

### `system`カタログ権限未設定時のエラー
もし上記の権限を設定せずに、各社のビューをSELECTすると、以下のようなエラーメッセージが表示され、SELECTに失敗します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/585e4cd3-0ae2-4de1-a3ee-822be1f423ae.png)
|:-:|
*ビューのSELECT時のエラー*

```text:サンプルデータの取得エラー
Your request failed with status FAILED: [BAD_REQUEST] [INSUFFICIENT_PERMISSIONS] Insufficient privileges: Table 'access_audit' does not have sufficient privilege to execute because the owner of one of the underlying resources failed an authorization check. User does not have USE SCHEMA on Schema 'system.access'. SQLSTATE: 42501
```

## 9. 見え方のテスト
実装が完了したら、各管理者グループで正しくアクセス権が設定されているかテストします。

### 中央IT管理者グループ
中央IT管理者グループは、すべてのシステムテーブルおよびビューにアクセスできることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/14647a24-1055-43e9-87e8-5dfa93a71dd6.png)
|:-:|
*`system.access.audit`のサンプルデータ閲覧ができる*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/f53e8fc7-6886-4cfa-bc19-b5cedcde9c40.png)
|:-:|
*`shared_system`スキーマ配下の各社のビューが見えており、ビューのサンプルデータ閲覧ができる*

### ABC銀行管理者グループ
ABC銀行管理者グループは、自社のスキーマ内のビューのみにアクセスできること、`system`カタログおよび他社のスキーマで監査ログ・課金情報が見えないことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/d7ae09ea-5bbc-4433-a8af-2ada416f55c9.png)
|:-:|
*`system`カタログはデフォルトの表示、`shared_system`カタログでは自社の`abc_bank`スキーマのみが表示されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/a5407118-206b-4e76-9969-2785357356ba.png)
|:-:|
*スキーマ配下のビューのサンプルデータ閲覧ができる*

### ABC証券管理者グループ
ABC証券管理者グループも同様に、自社のスキーマ内のビューのみにアクセスできること、`system`カタログおよび他社のスキーマで監査ログ・課金情報が見えないことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/bbedc1c7-5be8-4e67-afdb-af8f70e478a9.png)
|:-:|
*`system`カタログはデフォルトの表示、`shared_system`カタログでは自社の`abc_securities`スキーマのみが表示されている*

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/f529e3b2-ba4c-488c-aed5-80700efccba2.png)
|:-:|
*スキーマ配下のビューのサンプルデータ閲覧ができる*

# 考慮事項
最後に、いくつかの考慮事項を記載します。

## マルチリージョン対応
上記の実装は、メインリージョンである東日本リージョンのワークスペースを想定したものです。システムテーブルの情報はリージョンごとに分かれているため、別リージョンのワークスペースを利用する場合では、各リージョンに同様の仕組みを実装するなどの対応が必要となります。

## 定期メンテナンス
定期的なメンテナンスとして以下の点に留意が必要です。

- 新たなワークスペースが追加された場合の対応
- ワークスペースIDが変更された場合のビューの更新
- アクセス権限の定期的な監査と見直し

## ビューの読み取りに必要な権限
ビューを読み取るために必要な権限は、コンピュートの種類、Databricks Runtimeのバージョン、およびアクセスモードによって異なります。正確な内容は以下のドキュメントを参照ください。

https://learn.microsoft.com/en-us/azure/databricks/views/#requirements

(以下、上記ドキュメントより抜粋し機械翻訳した内容）

> # ビューの照会に関する要件
> 
> ビューを読み取るために必要な権限は、コンピュートの種類、Databricks Runtimeのバージョン、およびアクセスモードによって異なります。
> 
> **注意**
> すべてのビューについて、ビュー自体とビューの元になる基盤テーブルおよびビューの両方で権限チェックが実行されます。基盤テーブルとビューについて権限がチェックされるユーザーは、コンピュートによって異なります。以下の場合、Unity Catalogは基盤データに対するビュー所有者の権限をチェックします：
> * SQLウェアハウス
> * 標準コンピュート（以前の共有コンピュート）
> * きめ細かいアクセス制御が有効な、Databricks Runtime 15.4 LTS以上の専用コンピュート（以前の単一ユーザーコンピュート）
> 
> Databricks Runtime 15.3以下の専用コンピュートでは、Unity Catalogは基盤データに対するビュー所有者の権限とビューユーザーの権限の両方をチェックします。
> 
> この動作は以下の要件に反映されています。いずれの場合も、ビューユーザーがビューにアクセスするためには、ビュー所有者が基盤データに対する権限を維持する必要があります。
> 
> * すべてのコンピュートリソースについて、ビュー自体に対する`SELECT`権限、その親カタログに対する`USE CATALOG`権限、およびその親スキーマに対する`USE SCHEMA`権限が必要です。これはUnity Catalogをサポートするすべてのコンピュート種類（SQLウェアハウス、標準アクセスモードのクラスター、およびDatabricks Runtime 15.4以上の専用アクセスモードのクラスター）に適用されます。
> 
> * Databricks Runtime 15.3以下の専用アクセスモードを使用するクラスターの場合、ビューによって参照されるすべてのテーブルとビューに対する`SELECT`権限に加えて、それらの親カタログに対する`USE CATALOG`権限、およびそれらの親スキーマに対する`USE SCHEMA`権限も必要です。
> 
> **注意**
> Databricks Runtime 15.4 LTS以上の専用クラスターを使用していて、基盤テーブルとビューに対する`SELECT`権限の要件を回避したい場合は、*ワークスペースがサーバーレスコンピュートに対応しているか*確認してください。
> 
> サーバーレスコンピュートはデータフィルタリングを処理し、基盤テーブルとビューに対する権限がなくてもビューへのアクセスを可能にします。専用コンピュートを使用してビューを照会する場合、サーバーレスコンピュートの料金が発生する可能性があることに注意してください。詳細については、**専用コンピュート（以前の単一ユーザーコンピュート）におけるきめ細かいアクセス制御**を参照してください。

# おわりに
本記事では、Databricksの環境において、複数の組織間でシステムテーブル情報を安全に分離・共有する方法を実装しました。中央ITチームがシステムテーブルへの直接アクセスを制御しつつ、各社には自社の情報のみを閲覧できる仕組みを構築することで、情報セキュリティと必要なデータアクセスの両立を実現しています。

Unity Catalogのビュー機能を活用したこの手法が、皆様のDatabricks環境管理の参考になれば幸いです。