実行コンテキスト
実行コンテキスト
AppKit は、次の 2 つのコンテキストで Databricks の認証を管理します。
- ServiceContext (シングルトン) : アプリ起動時にサービスプリンシパルの資格情報で初期化されます
- ExecutionContext: 実行時に決定され、サービスプリンシパルまたはユーザーのいずれかのコンテキストになります
ユーザーコンテキスト用のヘッダー
x-forwarded-user: 本番環境では必須。ユーザーを識別しますx-forwarded-access-token: ユーザートークンのパススルーに必須
ユーザースコープの操作に asUser(req) を使用する
asUser(req) パターンを使うと、プラグイン はリクエスト元ユーザーの資格情報で操作を実行できます。
// カスタムプラグインのルートハンドラー内
router.post("/users/me/data", async (req, res) => {
// ユーザーとして実行(そのユーザーのDatabricks権限を使用)
const result = await this.asUser(req).query("SELECT ...");
res.json(result);
});
// サービスプリンシパルとして実行(デフォルト)
router.post("/system/data", async (req, res) => {
const result = await this.query("SELECT ...");
res.json(result);
});コンテキストヘルパー関数
@databricks/appkit からエクスポートされます。
getCurrentUserId(): ユーザーコンテキストではユーザー ID を、それ以外ではサービスユーザー ID を返しますgetWorkspaceClient(): 現在のコンテキストに適した WorkspaceClient を返しますgetWarehouseId():Promise<string>(DATABRICKS_WAREHOUSE_IDから取得。開発環境では自動選択)getWorkspaceId():Promise<string>(DATABRICKS_WORKSPACE_IDから取得。未設定の場合は取得処理を実行)
テレメトリスパン属性
実行インターセプタチェーンが作成する plugin.execute スパンには、次の属性が含まれます。
| 属性 | 型 | 説明 | |
|---|---|---|---|
execution.context | "user" | "service" | 操作をユーザー (OBO) として実行するか、サービスプリンシパルとして実行するか |
caller.id | string | ユーザーID (OBO) またはサービスプリンシパルID | |
execution.obo_dev_fallback | boolean | 開発モードでOBO呼び出しがサービスプリンシパルにフォールバックした場合に true が設定される |
これらの属性は、プラグインが execute() または executeStream() を使用した際に自動的に追加されます。組み込みプラグインはすべて、OBO操作にこれらのメソッドを使用しています。カスタムプラグインでも同様に実装すれば、テレメトリ計装が自動的に適用されます。
Lakebase のユーザーごとの接続
Lakebase プラグイン では、asUser(req) に別の仕組みを使用します。AsyncLocalStorage 経由で WorkspaceClient を差し替えるのではなく、ユーザーごとに個別の pg.Pool を作成し、それぞれが独自の OAuth トークンのリフレッシュを行います。これは、PostgreSQL の接続が接続時に認証される、つまりプール自体が認証の境界となるためです。
詳細は Lakebase プラグイン — ユーザーごとの接続 を参照してください。
開発モードでの動作
ローカル開発時 (NODE_ENV=development) に、ユーザートークンなしで asUser(req) を呼び出すと、警告がログに記録され、ユーザーの代理実行はスキップされます。代わりに、アプリに設定されたデフォルトの資格情報で処理が実行されます。テレメトリスパンには execution.context: "service" と execution.obo_dev_fallback: true が記録されるため、通常のサービスプリンシパルによる呼び出しと区別できます。