DatabricksのHiveメタストアの権限およびセキュリティ保護可能オブジェクト(レガシー)

[Hive metastore privileges and securable objects \(legacy\) \| Databricks on AWS](https://docs.databricks.com/data-governance/table-acls/object-privileges.html) [2023/4/6時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本書では、Databricksワークスペースのそれぞれに組み込まれているレガシーなDatabricks Hiveメタストアの権限モデルを説明します。また、ビルトインのHiveメタストアの権限をどのように許可、拒否、剥奪するのかも説明します。Unity Catalogでは権限付与において異なるモデルを採用しています。[Unity Catalogにおける権限およびセキュリティ保護可能オブジェクト](https://qiita.com/taka_yayoi/items/57dfb4d1c5908c1f5d9e)をご覧ください。

:::note
**注意**
Hiveメタストアによって管理されるデータに対するテーブルアクセスコントロールは、レガシーなデータガバナンスモデルです。[Hiveメタストアによって管理されるテーブルをUnity Catalogメタストアにアップグレード](https://qiita.com/taka_yayoi/items/5e896b50b915b9de8fb3)することをお勧めします。Unity Catalogは、お使いのアカウントにおける複数のワークスペースにおけるデータアクセスの管理と監査を行うための集中管理の場所を提供することで、皆様のデータのセキュリティとガバナンスをシンプルにします。レガシーな権限モデルとUnity Catalogの権限モデルがどのように違うのかを理解するには、[Unity CatalogとレガシーHiveメタストアを操作する](https://qiita.com/taka_yayoi/items/befd7538a8a988f847b6)をご覧ください。
:::

# 要件

- 管理者はワークスペースにおいて[テーブルアクセスコントロールを有効化、強制](https://docs.databricks.com/data-governance/table-acls/table-acl.html#enable-table-acl-workspace)しなくてはなりません。
- クラスターでは[テーブルアクセスコントロール](https://docs.databricks.com/data-governance/table-acls/table-acl.html#table-access-control)が有効化されなくてはなりません。

:::note
**注意**
- ワークスペースでテーブルアクセスコントロールが*有効化されていなくても*、Databricks SQLではデータのアクセスコントロールは*常に有効化*されます。
- ワークスペースでテーブルアクセスコントロールが有効化され、ワークスペースでACL(権限の付与や拒否)が指定されると、これらのACLはDatabricks SQLにも反映されます。
:::

# Hiveメタストアのオブジェクトの権限管理

Hiveメタストアで管理されるデータオブジェクトの権限は、ワークスペース管理者あるいはオブジェクトのオーナーによって付与することができます。SQLコマンドを用いてHiveメタストアオブジェクトの権限を管理することができます。

SQLで権限を管理するには以下の構文を用いて、ノートブックあるいはDatabricks SQLのクエリーエディターで[GRANT](https://docs.databricks.com/sql/language-manual/security-grant.html)、[REVOKE](https://docs.databricks.com/sql/language-manual/security-revoke.html)、[DENY](https://docs.databricks.com/sql/language-manual/security-deny.html)、[MSCK](https://docs.databricks.com/sql/language-manual/security-msck.html)、[SHOW GRANTS](https://docs.databricks.com/sql/language-manual/security-show-grant.html)を活用することができます。

```sql:SQL
GRANT privilege_type ON securable_object TO principal
```

ここでは:

- `privilege_type`は[Hiveメタストアオブジェクトに許可できる権限](#hiveメタストアオブジェクトに許可できる権限)です。
- `securable_object`は[Hiveメタストアにおけるセキュリティ保護可能オブジェクト](#hiveメタストアにおけるセキュリティ保護可能オブジェクト)です。
- `principal`は、ユーザー、サービスプリンシパル、グループのいずれかです。ユーザー、サービスプリンシパル、グループには特殊文字のバックティックス( `` )を使用する必要があります。[Principal](https://docs.databricks.com/sql/language-manual/sql-ref-principal.html)をご覧ください。

Hiveメタストアにおけるオブジェクトの権限管理の詳細については、[Privileges and securable objects in the Hive metastore](https://docs.databricks.com/sql/language-manual/sql-ref-privileges-hms.html)をご覧ください。

# オブジェクトのオーナーシップ

クラスターやSQLウェアハウスでテーブルアクセスコントロールが有効化されると、スキーマ、テーブル、ビュー、関数を作成したユーザーがオーナーとなります。オーナーには全ての権限が付与され、他のユーザーに権限を付与することができます。

グループがオーナーになることも可能で、その際には当該グループの全メンバーがオーナーとみなされます。

オブジェクトのオーナーあるいはワークスペース管理者は、ALTER \<object\> OWNER TO \`\<user-name\>@\<user-domain\>.com\` コマンドを用いて、オブジェクトのオーナーシップを委譲することができます。

# Hiveメタストアにおけるセキュリティ保護可能オブジェクト

セキュリティ保護可能オブジェクトは:

- `CATALOG`: データカタログ全体に対するアクセスをコントロールします。
    - `SCHEMA`: スキーマに対するアクセスをコントロールします。
        - `TABLE`: マネージドテーブル、外部テーブルに対するアクセスをコントロールします。
        - `VIEW`: SQLビューに対するアクセスをコントロールします。
        - `FUNCTION`: 名前付き関数に対するアクセスをコントロールします。
- `ANONYMOUS FUNCTION`: [anonymous or temporary functions](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-create-function.html)に対するアクセスをコントロールします。

    :::note
    **注意**
    Databricks SQLでは`ANONYMOUS FUNCTION`オブジェクトはサポートされません。
  :::

- `ANY FILE`: 背後のファイルシステムに対するアクセスをコントロールします。

    :::note alert
    **警告！**
    `ANY FILE`へのアクセスが許可されたユーザーは、ファイルシステムを直接読み込むことで、カタログ、スキーマ、テーブル、ビューに設定された制限をバイパスすることができます。
:::

# Hiveメタストアオブジェクトに許可できる権限

- `SELECT`: オブジェクトの読み取り権限を付与します。
- `CREATE`: オブジェクトの作成権限(スキーマ内のテーブルなど)を付与します。
- `MODIFY`: オブジェクトに対する追加、削除、変更権限を付与します。
- `USAGE`: いかなる能力も付与しませんが、スキーマオブジェクトで全てのアクションを行うために必要な追加要件となります。
- `READ_METADATA`: オブジェクトとそのメタデータの参照権限を付与します。
- `CREATE_NAMED_FUNCTION`: 既存のカタログやスキーマに名前付きUDFを作成する権限を付与します。
- `MODIFY_CLASSPATH`: ファイルにSparkクラスパスを追加する権限を付与します。
- `ALL PRIVILEGES`: 全ての権限を付与します(上述のすべての権限に変換されます)。

:::note
**注意**
Databricks SQLでは`MODIFY_CLASSPATH`権限はサポートされません。
:::

## `USAGE`権限

Hiveメタストアでスキーマオブジェクトに対するアクションを実行するには、当該アクションを実行するための権限に加えて、当該スキーマに対する`USAGE`権限が必要となります。いかのいずれも、`USAGE`権限を満たすことになります:

- ワークスペース管理者である
- 当該スキーマに対する`USAGE`権限を持つ、あるいは当該スキーマに対する`USAGE`権限を持つグループに属している
- `CATALOG`に対する`USAGE`権限を持つ、あるいは`USAGE`権限を持つグループに属している
- スキーマのオーナーである、あるいはスキーマのオーナーであるグループに属している

スキーマ内のオブジェクトのオーナーであっても、それを使用するには`USAGE`権限が必要となります。

# 権限の階層構造

ワークスペースとすべてのクラスターでテーブルアクセスコントロールが有効化されると、DatabricksのSQLオブジェクトは階層型となり、権限は下流に継承されます。これは、`CATALOG`への権限の付与や拒否は、カタログのすべてのスキーマの権限を自動で許可、拒否することを意味します。同様に、スキーマに許可された権限は、スキーマ内のすべてのオブジェクトに継承されます。このパターンはすべてのセキュリティ保護可能オブジェクトで共通です。

テーブルの権限を拒否すると、スキーマのすべてのテーブルの一覧しようとしてもテーブルを参照できなくなります。あるユーザーに対してスキーマに対する権限を拒否すると、カタログのすべてのスキーマを一覧しようとしてもスキーマの存在を確認できなくなります。

# 動的ビュー関数

Databricksには、ビュー定義の中に動的な行レベル、列レベルでのアクセス権を表現できる二つのユーザー関数があります。

- `current_user()`: 現在のユーザー名を返します。
- `is_member()`: 現在のユーザーが特定のDatabricks[グループ](https://docs.databricks.com/administration-guide/users-groups/groups.html)のメンバーかどうかを判定します。

:::note
**注意**
Databricksランタイム7.3 LTS以降で利用できます。しかし、これらの関数をDatabricksランタイム7.3 LTSで使用する際には、[Spark config](https://docs.databricks.com/clusters/configure.html#spark-config)に`spark.databricks.userInfoFunctions.enabled true`を設定する必要があります。
:::

以下の例では、両方の関数を用いてユーザーが適切なグループのメンバーかどうかを判別しています:

```sql:SQL
-- Return: true if the user is a member and false if they are not
SELECT
  current_user as user,
-- Check to see if the current user is a member of the "Managers" group.
  is_member("Managers") as admin
```

## 列レベルのアクセス権

動的ビューを通じて、特定のグループ、ユーザーが参照できる列を容易に制御できるようになります。`auditors`グループに属するユーザーのみが、`sales_raw`テーブルのemailアドレスを参照できる以下の例を考えてみます。解析の際、Saprkは`CASE`文をリテラルの`REDACTED`あるいは`email`カラムで置換します。この振る舞いによって、通常のSparkによるパフォーマンス最適化を利用することができます。

```sql:SQL
-- Alias the field 'email' to itself (as 'email') to prevent the
-- permission logic from showing up directly in the column name results.
CREATE VIEW sales_redacted AS
SELECT
  user_id,
  CASE WHEN
    is_member('auditors') THEN email
    ELSE 'REDACTED'
  END AS email,
  country,
  product,
  total
FROM sales_raw
```

## 行レベルのアクセス権

動的ビューを用いることで、行やフィールドレベルでアクセス権を適用することができます。`managers`グループに属するユーザーのみが、金額が$1,000,000.00より大きいトランザクションを参照できるようにする例を考えてみます。

```sql:SQL
CREATE VIEW sales_redacted AS
SELECT
  user_id,
  country,
  product,
  total
FROM sales_raw
WHERE
  CASE
    WHEN is_member('managers') THEN TRUE
    ELSE total <= 1000000
  END;
```

## データマスキング

これまでの例で示したように、適切なグループに属していないユーザーが特定の列を参照できないように、列レベルでのマスキングを実装することができます。これらのビューは標準的なSpark SQLですので、より複雑なSQL表現を用いて、より洗練されたマスキングを行うことができます。以下の例では、全てのユーザーはemailのドメインに対して分析をこなうことができますが、`auditors`グループのメンバーは、emailの全てを参照することができます。

```sql:SQL
-- The regexp_extract function takes an email address such as
-- user.x.lastname@example.com and extracts 'example', allowing
-- analysts to query the domain name

CREATE VIEW sales_redacted AS
SELECT
  user_id,
  region,
  CASE
    WHEN is_member('auditors') THEN email
    ELSE regexp_extract(email, '^.*@(.*)$', 1)
  END
  FROM sales_raw
```

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)