DatabricksのサービスプリンシパルのPersonal Access Token (PAT) の作成方法

# はじめに
DatabricksワークスペースのAPIをDatabricksの外側から呼び出す際、認証には**アクセストークン**が必要です。アクセストークンの取得方法には以下のような選択肢があります：

取得方法 | 備考
--- | ---
ユーザーのPersonal Access Token (PAT) | PATをDatabricks API認証用のアクセストークンとしてそのまま利用可能
ユーザーのOAuth認証 (OAuth U2M; User to Machineの略) | OAuth認証の結果としてアクセストークンが返却されるので、そちらをDatabricks API認証に利用
サービスプリンシパルのPAT | PATをDatabricks API認証用のアクセストークンとしてそのまま利用可能
サービスプリンシパルのOAuth認証 (OAuth M2M; Machine to Machineの略) | OAuth認証の結果としてアクセストークンが返却されるので、そちらをDatabricks API認証に利用

上記のうち、ユーザーのPATが最も簡単な方法ですが、組織内のカスタムアプリからDatabricks APIを呼び出す場合、個人のアクセストークンではなく、そのアプリ専用のサービスプリンシパルを用いて認証を行う方法が考えられます。

OAuth M2M認証を利用できるのが理想的です。Databricksの公式ツール（Databricksの各言語用のSDK、Databricks CLI、Terraformプロバイダー）はOAuth M2Mをサポートしており、アクセストークンの有効期限が切れた際に自動で再取得する機能が組み込まれています。

しかし、ユーザーがカスタムアプリでOAuth M2M認証を利用する場合には、アクセストークンの再取得ロジックを実装する必要があり、やや複雑になります。そのため、間を取って、サービスプリンシパルのPATを利用するケースも多いと思います。

本記事では、サービスプリンシパルのPATを作成する方法について詳しく説明します。

# 注意事項
本記事で扱うサービスプリンシパルはDatabricksが管理するものを対象としています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/339a027c-91d4-7e76-18e8-a86a7d974460.png)

サービスプリンシパルのPAT作成には、Databricks CLI バージョン 0.205 以降が必要です。インストールされていない場合や古いバージョンの場合は、Databricks CLIのインストールまたは更新の手順に従ってください。
CLIのバージョンは `databricks -v` コマンドで確認できます。

https://learn.microsoft.com/ja-jp/azure/databricks/dev-tools/cli/install

# 手順
以下の手順に従って、サービスプリンシパルのPATを作成します：

1. サービスプリンシパルの作成
1. サービスプリンシパルのクライアントシークレット生成
1. ワークスペースへのサービスプリンシパル追加
1. サービスプリンシパルのトークン利用設定
1. Databricks CLIでのM2M認証設定
1. Databricks CLIを使用したサービスプリンシパルのPAT作成
1. Databricks CLIを使用したテスト実行

## 1. サービスプリンシパルの作成
アカウント管理者がアカウントコンソールでサービスプリンシパルを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/1bd6415d-173b-7161-7333-565b8e95fb0b.png)

## 2. サービスプリンシパルのクライアントシークレット生成
アカウント管理者がアカウントコンソールで、サービスプリンシパルのシークレットを生成します。生成されたクライアントIDとシークレットを手元に控えておきます。特にシークレットは生成時にしか表示されないので注意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/d70ff5b2-d740-6544-b03a-6e78fb956049.png)

## 3. ワークスペースへのサービスプリンシパル追加
ワークスペース管理者が、ワークスペース設定からサービスプリンシパルをワークスペースに追加し、必要な資格（エンタイトルメント）を付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/2c828a5e-810d-4031-8a72-e48e4a9ee06f.png)

以下キャプチャはデフォルトのエンタイトルメント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/aef766a6-c0ca-ce04-1f2d-b1e0c0b8d201.png)

## 4. サービスプリンシパルのトークン利用設定
ワークスペース管理者が、ワークスペース設定（Advancedセクション）で、Personal Access Tokensをオンにします。さらに、[Permission Settings] から、サービスプリンシパルに使用可能（CAN USE）の権限を付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/234eee5d-793e-bbd0-c230-adedc29841d7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284925/8eac1c04-b4ae-83ab-d6a5-e6f3f87ec7da.png)

### 補足
- 本手順では簡単のために、サービスプリンシパルに直接権限を付与していますが、本番環境などではグループを作成してグループに権限を付与するのが良いプラクティスです
- ワークスペースに1件もPATが存在しない場合、[Permission Setting]が非活性の状態となり、クリックできません。この場合、誰かしらのユーザーでPATを作成することで、[Permission Setting]がクリックできるようになります。

## 5. Databricks CLIでM2M認証設定
Databricks CLIの認証情報は、ユーザーのホームディレクトリの `.databrickscfg` ファイルに保存されます。以下の形式で、ワークスペースURLおよびサービスプリンシパルのクライアントID、クライアントシークレットを記載します。

```configuration
[<一意の設定プロファイル名>]
host          = <ワークスペースURL>
client_id     = <サービスプリンシパルのクライアントID>
client_secret = <サービスプリンシパルのOAuthシークレット>
```

以下は例です（ダミーの値）。

```configuration
[hinak-adb-ejp-20240903]
host          = https://adb-123450042242060.0.azuredatabricks.net/
client_id     = a1b2c3d4-3478-4b08-9af2-deddb481871e
client_secret = sampled2056b7f46e347abb4dd48045f3634
```

## 6. Databricks CLIを使用したサービスプリンシパルのPAT作成
以下のコマンドを実行して、サービスプリンシパルのPATを作成します。

```bash
databricks tokens create --comment <comment> --lifetime-seconds <lifetime-seconds> -p <profile-name>
```

- `--comment`：オプション。PATの使用用途などを記述。
- `--lifetime-seconds`：オプション。PATの有効期限を秒数で指定。省略すると無期限になるため、何らか指定することを推奨。以下は秒数の早見表。
    - 1日 86400
    - 30日 2592000
    - 365日 31536000
- `-p`：`.databrickscfg`で設定したプロファイル名を指定。

### レスポンス
コマンドが成功すると、以下のようなレスポンスが返されます。`token_value`がアクセストークンです。

```json
{
  "token_info": {
    "comment":"",
    "creation_time":1725324451821,
    "expiry_time":-1,
    "token_id":"123456dd8f247254fac3c5f8f08655d2fa7a3aa902dd7b9c9a82a97511b60033"
  },
  "token_value":"samplee9e3f0e6b9eaa9a018f72b4d80c505"
}
```

## 7. Databricks CLIを使用したテスト実行
`.databrickscfg`にPATを使用したプロファイルを追加します。以下は例です。

```
[hinak-adb-ejp-20240903-pat]
host  = https://adb-123450042242060.0.azuredatabricks.net/
token = sampled2056b7f46e347abb4dd48045f3634
```

以下ではSQLウェアハウスをリストするコマンドでPATが問題なく動作するかをテストします。

```bash
databricks warehouses list -p hinak-adb-ejp-20240903-pat
```

以下のような結果が返って来れば、問題なく動作しています。

```
ID                Name                          Size   State
48f2284132f3a963  Serverless Starter Warehouse  Small  STOPPED
```

# エラーメッセージと対処方法
以下は、Databricks CLIでのサービスプリンシパル作成時のエラーメッセージと対処方法です。基本的には本記事の流れに沿って実施していれば、発生しないはずです。

## `On-behalf-of token creation for service principals is not enabled for this workspace`
- 発生状況：ユーザーの認証情報を使ってサービスプリンシパルのPATを作成しようとする際に発生。
- 対処方法：サービスプリンシパルのOAuth認証 (OAuth M2M) の構成を完了する。

参考ドキュメント

https://community.databricks.com/t5/data-engineering/not-able-to-generate-access-token-for-service-principal-using/td-p/7383

## `Error: User does not have permission to use tokens`
- 発生状況：サービスプリンシパルがトークンの使用（Token Usage）について、使用可能（Can use）の権限を持っていない場合に発生。
- 対応方法：ワークスペース管理者が、ワークスペースの設定 > Advanced > Personal Access Tokens > Permission Settingsから、サービスプリンシパルに使用可能の権限を付与する。

参考ドキュメント

https://kb.databricks.com/en_US/notebooks/service-principal-cannot-create-access-token

# 参考リンク
認証方法について網羅的に記載したドキュメント

クラウド | リンク
--- | ---
Azure Databricks | [Azure Databricks ツールと API の認証 - Azure Databricks \| Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/databricks/dev-tools/auth/)
Databricks on AWS | [DatabricksツールとAPIsの認証 \| Databricks on AWS](https://docs.databricks.com/ja/dev-tools/auth/index.html)
Databricks on GCP | [DatabricksツールとAPIsの認証 \| Databricks on Google Cloud](https://docs.gcp.databricks.com/ja/dev-tools/auth/index.html)

サービスプリンシパルのPAT作成のドキュメント

クラウド | リンク
--- | ---
Azure Databricks | [サービス プリンシパルを管理する - Azure Databricks \| Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/databricks/admin/users-groups/service-principals#manage-personal-access-tokens-for-a-service-principal)
Databricks on AWS | [サービスプリンシパルを管理する \| Databricks on AWS](https://docs.databricks.com/ja/admin/users-groups/service-principals.html#manage-personal-access-tokens-for-a-service-principal)
Databricks on GCP | [サービスプリンシパルの管理 \| Databricks on Google Cloud](https://docs.gcp.databricks.com/ja/admin/users-groups/service-principals.html)

以上です。