Databricks アプリで認可の設定をする
Databricks Apps は、Databricks での安全なアプリケーション開発をサポートします。アプリは、ワークスペース内のデータとサービスにアクセスするときに、データ アクセス制御を適用し、ユーザーのアクセス許可を尊重する認証および認可メカニズムを使用する必要があります。Databricks Apps の認可モデルは OAuth 2.0 に基づいており、アプリに割り当てられた権限と、アプリにアクセスするユーザーの権限が組み合わされます。
このフレームワークをサポートするために、Databricks Apps では 2 つの補完的な ID モデルを使用します。
アプリの認可
各Databricksアプリには、 Databricksリソースにアクセスするときに ID として機能する専用のサービス プリンシパルがあります。 このサービスプリンシパルはアプリ インスタンスに固有のものであり、アプリ間で再利用することはできません。 アプリの作成中に、アプリに割り当てられたサービスプリンシパルを変更したり、既存のサービスプリンシパルを指定したりすることはできません。 Databricks はこの ID を使用して、ユーザーとは独立してアプリのアクセス許可を評価します。これにより、ユーザー操作のコンテキスト外でも、アプリは明示的に許可されたリソースにのみアクセスできるようになります。
この分離により、セキュリティ境界が適用され、アプリのアクティビティの監査が可能になり、バックグラウンド処理や自動タスクなどのシナリオがサポートされます。
サービスプリンシパルは一意のIDで表されます。 アプリの 承認 タブからコピーします:
アプリを作成すると、 Databricks 自動的にプロビジョニング専用のサービスプリンシパルが発行されます。 サービスプリンシパルは、アプリのすべてのデプロイで同じままです。 アプリを削除すると、サービスプリンシパル Databricks 削除されます。
サービスプリンシパルは、個々のユーザーのコンテキストを必要とせずに、アプリが独自に実行するアクションに使用します。 一般的な使用例は次のとおりです。
- バックグラウンドタスクの実行
- 共有構成またはメタデータの読み取りまたは書き込み
- アクティビティまたは使用状況のメトリクスのロギング
- セキュアなエンドポイントを介した外部サービスの呼び出し
アプリによって開始されるすべてのアクションは、サービスプリンパルシの権限を使用します。 標準の権限割り当てを使用して、サービスプリンシパルに特定のリソースへのアクセスを付与します。 ただし、ユーザー レベルのアクセス制御はサポートされていません。アプリを操作するすべてのユーザーは、サービスプリンシパルに定義された同じ権限を共有します。これにより、アプリは個々のユーザー ID に基づいて詳細なポリシーを適用することができなくなります。
次の例は、アプリがサービスプリンシパルを使用して Unity Catalog内のデータをクエリする方法を示しています。
この場合、サービスプリンシパルは、 SQLウェアハウスとクエリを実行する Unity Catalog テーブルの両方に明示的にアクセスする必要があります。
このモデルは、アプリのすべてのユーザーに同じデータを表示する場合や、アプリがユーザー固有のアクセス制御に関連付けられていない共有操作を実行する場合に適しています。
アプリ認証資格情報を取得する
アプリの認可の場合、 Databricks はサービスのプリンシパル資格情報をアプリの環境に自動的に挿入します。 次の環境変数は、必要な OAuth クライアント値を保持します。
変数 | 説明 |
---|---|
| サービスプリンシパルのOAuth クライアント ID |
| サービスプリンシパルのOAuthクライアントシークレット |
Databricks は、アプリ ランタイムで環境変数を自動的に設定します。アプリは、それ自体として認証するときにこれらの変数を使用します。
- Python
- JavaScript
import os
client_id = os.getenv('DATABRICKS_CLIENT_ID')
client_secret = os.getenv('DATABRICKS_CLIENT_SECRET')
const clientId = process.env.DATABRICKS_CLIENT_ID;
const clientSecret = process.env.DATABRICKS_CLIENT_SECRET;
Databricks SDK を使用している場合、通常、これらの環境変数に手動でアクセスする必要はありません。SDK は 統合認証 に従い、環境内の資格情報を自動的に検出します。
例: アプリの認可を使用したクエリ
- Python
- JavaScript
この例では、 SDK Config オブジェクトを使用して、環境変数からサービスプリンシパル の資格情報 を取得し、 OAuth 認証を実行します。
from databricks import sql
from databricks.sdk.core import Config
cfg = Config()
conn = sql.connect(
server_hostname=cfg.host,
http_path="<your-warehouse-http-path>",
credentials_provider=lambda: cfg.authenticate,
)
query = "SELECT * FROM main.sandbox.sales_customers LIMIT 1000"
with conn.cursor() as cursor:
cursor.execute(query)
df = cursor.fetchall_arrow().to_pandas()
print(df.head())
conn.close()
この例では、環境変数を使用して OAuth を使用してサービスプリンシパルで認証し、Databricks SQL Driver for Node.jsでクエリを実行します。
import { DBSQLClient } from '@databricks/sql';
const client = new DBSQLClient();
const connection = await client.connect({
authType: 'databricks-oauth',
host: process.env.DATABRICKS_SERVER_HOSTNAME,
path: process.env.DATABRICKS_HTTP_PATH,
oauthClientId: process.env.DATABRICKS_CLIENT_ID,
oauthClientSecret: process.env.DATABRICKS_CLIENT_SECRET,
});
const query = 'SELECT * FROM main.sandbox.sales_customers LIMIT 1000';
const cursor = await connection.cursor(query);
const rows = [];
for await (const row of cursor) {
rows.push(row);
}
console.log(rows.slice(0, 5)); // Like df.head()
await connection.close();
ユーザー認証
プレビュー
ユーザー認証は パブリック プレビュー段階です。
ユーザー認可 ( ユーザー代理認可 と呼ばれることもあります) を使用すると、Databricks Apps アプリはアプリ ユーザーの ID で動作できます。Databricks はユーザーのアクセス トークンをアプリに転送し、アプリはトークンを使用してユーザーに代わってリソースにアクセスします。Databricks は、ユーザーの既存の Unity Catalog ポリシーに基づいてすべてのアクセス許可を適用します。
ユーザーに代わって動作するアプリのセキュリティリスクを管理するために、Databricks はスコープを使用して、ユーザーが認可を通じて実行できるアクションを制限します。
アプリが個々のユーザー権限を尊重する必要がある場合は、ユーザー認可を適用します。一般的な使用例は次のとおりです。
- テーブルまたはボリュームのクエリ
- SQLウェアハウスまたはコンピュートへのアクセス
- ユーザーアクションに関連付けられたジョブまたはワークフローの実行
すべてのアクションでは、ユーザーの既存の Unity Catalog のアクセス許可が使用されます。
ユーザー認可では、行レベルのフィルターや列マスクなどの Unity Catalog の機能をアプリのアクティビティに適用することで、きめ細かなアクセス制御が可能になります。このアプローチにより、アクセス制御とワークスペースのガバナンスとの一貫性が保たれ、アクセス許可ロジックがアプリにハードコーディングされるのを回避できます。
ユーザー認可によるきめ細かな権限
アプリにユーザー認可を追加すると、次のようなユーザーの既存の Unity Catalog のアクセス許可が適用されます。
- 表示される行を制限する行レベルのフィルター
- 機密データを編集または変換するための列マスク
Databricks はユーザーの ID を使用してユーザー認可要求を評価するため、アプリがデータにアクセスすると、これらのポリシーが自動的に適用されます。たとえば、テーブルに地域ごとに表示を制限する行フィルターが含まれている場合、アプリはユーザーがクエリを許可された行のみを返します。アプリには追加のフィルタリングロジックは必要ありません。
このアプローチにより、アプリケーション コード内のアクセス制御ロジックの重複が回避され、ワークスペース レベルのガバナンスとの一貫性が確保されます。管理者が Unity Catalog ポリシーを更新すると、アプリは自動的にその変更を尊重します。
スコープベースのセキュリティと特権昇格
ユーザー認証を使用するアプリは、ユーザーに代わってアプリが実行できる操作を制限するために、特定の認証スコープを宣言する必要があります。スコープは、次のような特定のAPIsまたはリソース タイプへのアクセスを制限します。
sql
クエリ用 SQLウェアハウスdashboards.genie
Genieスペースの管理にfiles.files
ファイルやディレクトリの管理のため
スコープを選択しない場合、 Databricks は、アプリが基本的なユーザー ID 情報を取得できるようにするデフォルト セットを割り当てます。
iam.access-control:read
iam.current-user:read
これらはユーザー認証機能をサポートするために必要ですが、データやコンピュート リソースへのアクセスは許可しません。 アプリを作成または編集するときに、追加のスコープを追加します。
スコープは、最小特権の原則を強制します。必要なスコープのみを要求するようにアプリを構成してください。Databricks は、ユーザーがアクセス許可を持っている場合でも、承認されたスコープ外の機能へのアクセスをブロックします。たとえば、アプリが sql
スコープのみをリクエストした場合、ユーザーがアプリの外部にいても、モデルサービングエンドポイントにはアクセスできません。
ユーザーが初めてアプリにアクセスすると、Databricks は、要求されたスコープ内でアプリが動作することを明示的に承認するように求めます。管理者は、必要に応じて、ユーザーに代わってアクセスを組織のポリシーに合わせるための同意を付与できます。
アプリにスコープを追加する
プレビュー
ユーザー認可は パブリック プレビュー段階です。アプリにスコープを追加する前に、ワークスペース管理者が有効にする必要があります。
ユーザー認証を有効にした後、スコープを追加する前に、既存のアプリを再起動する必要があります。ユーザー認証を無効にした場合、現在のユーザーのアクセストークンを使用してリソースにアクセスするのを停止するには、既存のアプリを再起動する必要があります。
Databricks UI でアプリを作成または編集するときに、ユーザー認証を構成します。
構成 ステップで、 + スコープの追加 をクリックし、アプリがユーザーに代わってアクセスできるDatabricks APIまたはリソースを定義するスコープを選択します。Databricks では、実行時にこれらのスコープが適用され、アクセスを許可する前にユーザーまたは管理者の同意が必要です。
完全な例については、 GitHub の Databricks Apps 認可デモを参照してください。サンプル アプリでは、アプリとユーザーの両方の認可モデルの使用方法を示し、ユーザー認可を使用したセットアップ手順とクエリの例が含まれています。
ユーザー認証資格情報の取得
ユーザー認可の場合、Databricks はユーザーの ID とアクセス トークンを HTTP ヘッダーでアプリに転送します。アプリは、ユーザーに代わって動作するために、これらのヘッダーを抽出する必要があります。
これらのヘッダーを取得する方法は、使用するフレームワークによって異なります。
- Streamlit
- Gradio
- Dash and Flask
- Shiny
- Express
import streamlit as st
user_access_token = st.context.headers.get('x-forwarded-access-token')
import gradio as gr
def query_fn(message, history, request: gr.Request):
access_token = request.headers.get("x-forwarded-access-token")
...
Gradioは、リクエストオブジェクトをパラメーターとして宣言すると、アプリの関数に自動的にリクエストオブジェクトを挿入します。 要求を手動で作成またはフェッチする必要はありません。
from flask import request
headers = request.headers
user_token = headers.get('x-forwarded-access-token')
user_token = session.http_conn.headers.get('x-forwarded-access-token')
import express from 'express';
const userAccessToken = req.header('x-forwarded-access-token');
例: ユーザー認可を使用したクエリ
この場合、アプリはユーザーのアクセス トークンを直接コネクタに渡し、Databricks はユーザーのアクセス許可をクエリに適用します。
- Python
- JavaScript
from databricks import sql
from databricks.sdk.core import Config
from flask import request
cfg = Config()
user_token = request.headers.get("x-forwarded-access-token")
conn = sql.connect(
server_hostname=cfg.host,
http_path="<your-warehouse-http-path>",
access_token=user_token
)
query = "SELECT * FROM main.sandbox.sales_customers LIMIT 1000"
with conn.cursor() as cursor:
cursor.execute(query)
df = cursor.fetchall_arrow().to_pandas()
print(df.head())
conn.close()
import { DBSQLClient } from '@databricks/sql';
import express from 'express';
const app = express();
app.get('/', async (req, res) => {
const userToken = req.header('x-forwarded-access-token');
const client = new DBSQLClient();
const connection = await client.connect({
authType: 'access-token',
host: process.env.DATABRICKS_SERVER_HOSTNAME,
path: process.env.DATABRICKS_HTTP_PATH,
token: userToken,
});
const query = 'SELECT * FROM main.sandbox.sales_customers LIMIT 1000';
const cursor = await connection.cursor(query);
const rows = [];
for await (const row of cursor) {
rows.push(row);
}
console.log(rows.slice(0, 5));
await connection.close();
res.send('Query complete');
});
app.listen(3000);
ユーザー認証のベスト プラクティス
ユーザーに代わって操作を行うアプリを作成する場合は、次のおすすめの方法に沿って、安全で監査可能なアクセスを確保してください。
- アプリ コードは、アプリの所有者または少数の信頼できるユーザーのみがアクセスできるフォルダーに格納します。
CAN MANAGE
権限は、アプリのメンテナンスとレビューを担当する信頼できる上級開発者にのみ付与します。アプリの実行が承認された特定のユーザーまたはグループにのみCAN USE
アクセス許可を付与します。- トークンが印刷、ログ記録、またはファイルに書き込まれていないことを確認します。これは、すべてのロギングステートメント、デバッグツール、およびエラーハンドラに適用されます。たとえば、
print(f"User token: {token}")
の代わりにheaders = {"Authorization": f"Bearer {token}"}
を使用します。 - 各アプリは、その機能に必要な最小限の認可スコープのみを要求するように構成します。
- コード レビュー中に、スコープとアクセス許可の設定がセキュリティ要件と一致していること、および不要なアクセスを許可していないことを確認します。
- 本番運用環境にデプロイする前に、すべてのアプリコードに対してピアレビューを実施します。
- ユーザー ID、アクションの種類、ターゲット リソース、ステータスなど、ユーザーに代わって実行されるすべてのアクションについて、構造化された監査ログがアプリ コードに記録されていることを確認します。
認証方法
Databricks Apps のウイルスを取得するには、ユーザーとサービスプリンシパルの両方が標準のOAuth 2.0 フローを使用して認証します。 方法は、呼び出し元がユーザーであるか、自動化されたワークロードであるかによって異なります。
ワークスペースログインの場合(ユーザーのみ):
- シングル サインオン (SSO): シングル サインオン (SSO) が構成されている場合、ユーザーは ID プロバイダーを通じて認証します。
- ワンタイム パスワード (OTP): SSO が構成されていない場合、ユーザーは一時パスワードを受け取ります。
OAuth フロー (アプリとワークロード) の場合:
- ユーザー対マシン (U2M) OAuth : ユーザーが認証し、結果として得られるトークンによってユーザー承認が有効になり、アプリがユーザーに代わって動作できるようになります。
- マシンツーマシン (M2M) OAuth : サービス プリンシパルは、クライアントの資格情報またはフェデレーションを使用して認証します。 これらのトークンは、アプリがユーザーではなくアプリ自身として機能するアプリ認証の基盤となります。
モデルの比較と結合
Databricks アプリは、アプリとユーザーの認可を個別に使用することも、一緒に使用することもできます。これらのモデルは異なる目的を果たし、並行して動作するように設計されています。
認可モデル | いつ使用するか | 使用例 |
---|---|---|
アプリ認可 | アプリがユーザーの ID に依存しない操作を実行する場合 | ログの書き込み、共有設定へのアクセス、外部サービスの呼び出し |
ユーザー認可 | アプリが現在のユーザーのコンテキストでリソースにアクセスする必要がある場合 | Unity Catalogデータのクエリ、コンピュートの起動、行レベルの権限の適用 |
両方 | アプリが共有操作とユーザー固有の操作の両方を実行する場合 | アプリ ID によるメトリクスのログ記録、ユーザー ID によるフィルター処理されたデータのクエリ |