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 ポリシーを更新すると、アプリは自動的にそれらの変更を尊重します。これにより、古い権限ロジックや不整合な権限ロジックによるデータ漏洩のリスクが軽減されます。
スコープベースのセキュリティと特権昇格
ユーザー認可を使用するアプリは、ユーザーに代わってアプリが実行できる操作を制御するために、特定の認可スコープを宣言する必要があります。スコープは、次のような特定の API またはリソースの種類へのアクセスを制限します。
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 アプリは、アプリとユーザーの認可を個別に使用することも、一緒に使用することもできます。これらのモデルは異なる目的を果たし、並行して動作するように設計されています。
認可モデル | いつ使用するか | 使用例 |
---|---|---|
アプリ認可 | アプリがユーザーの ID に依存しない操作を実行する場合 | ログの書き込み、共有設定へのアクセス、外部サービスの呼び出し |
ユーザー認可 | アプリが現在のユーザーのコンテキストでリソースにアクセスする必要がある場合 | Unity Catalogデータのクエリ、コンピュートの起動、行レベルの権限の適用 |
両方(合計) | アプリが共有操作とユーザー固有の操作の両方を実行する場合 | アプリ ID によるメトリクスのログ記録、ユーザー ID によるフィルター処理されたデータのクエリ |