using-backstage-permissions について
Backstage プラグインに権限チェックを実装する開発スキルです。共有する権限定義やフロントエンド・バックエンドの認可に加え、リソース単位の判定方法を説明します。
主な機能
- 01プラグイン共通の権限を宣言
- 02権限チェックでフロントエンド UI を制御
- 03バックエンド操作を認可
- 04条件付きのリソース単位判定
- 05非同期の権限状態を処理
活用シーン
- 01未認可ユーザーから操作項目を隠す
- 02ルート処理の前に権限を確認
- 03リソース所有者に基づいて更新を制限
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ vinzscam/ backstage-skills --skill using-backstage-permissionsインストール後、Claude Code で/using-backstage-permissionsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/backend.mddeclaring.mdfrontend.mdresource-permissions.md詳細
Backstage の権限パターン
このスキルを使用する場面
- 権限のないユーザーにボタン、メニュー、ページを表示しないようにする必要があるプラグイン(フロントエンド)
- アクションを実行する前に、プラグインのルートハンドラーで呼び出し元を認可する必要がある(バックエンド)
- プラグインの新しい権限を定義する
- リソースごとに権限を確認する(「コンポーネント全般を更新できるか」ではなく「このコンポーネントを更新できるか」)
適切なパターンを選択する
権限の宣言
| 構築するもの | パターン | リファレンス |
|---|---|---|
| プラグインの新しい権限 | *-common ライブラリ内の createPermission({ name, attributes }) | references/declaring.md |
フロントエンド(プラグインコンポーネント内)
| 状況 | パターン | リファレンス |
|---|---|---|
| 権限に基づいて UI を条件付きでレンダリングする | usePermission({ permission }) フック | references/frontend.md |
| サブツリー全体を権限ゲートで囲む | <RequirePermission permission={...}>...</RequirePermission> | references/frontend.md |
バックエンド(ルートハンドラーまたはスケジュールされたタスク内)
| 状況 | パターン | リファレンス |
|---|---|---|
| 基本的なアクション権限を認可する | coreServices.permissions.authorize([{ permission }], { credentials }) | references/backend.md |
| リソースごとに認可する(条件付きの判定を使用) | permissions.authorizeConditional([{ permission, resourceRef }], { credentials }) + permissionsRegistry.addResourceType(...) | references/resource-permissions.md |
2 つの呼び出しモード
- 単独(開発途中):ユーザーが既存のプラグインを編集しています。追加する内容(権限の定義、UI の制御、またはバックエンドでの認可)に基づいて、適切なリファレンスを選択します。
- スキャフォールド後(
creating-backstage-pluginから呼び出されます):意図に「管理者のみが…できる」「現在のユーザーには…する権限が必要」などのアクセス制御に関する表現が含まれる場合に、関連するパターンを新しくスキャフォールドされたプラグインに追加します。
よくある注意点
- 権限は一度宣言し、2か所で使用します。 権限オブジェクトは
*-common(または*-permissions-common)ライブラリに置き、フロントエンド(usePermission)とバックエンド(permissions.authorize)の両方から同じ定義をインポートします。同じ権限を2か所で再宣言しないでください。 - ホストアプリで権限フレームワークを有効にする必要があります。 導入側は
app-config.yamlでpermission.enabled: trueを設定し、PermissionPolicyをインストールします。権限が有効でない場合、authorizeは常にAuthorizeResult.ALLOWを返します。プラグインのコードは正しくても、強制されません。前提条件として、プラグインの README に記載してください。 permissions.authorizeは、リクエストの順序に対応する配列を返します。 権限が1つの場合は、const [decision] = await permissions.authorize(...)と分割代入します。なお、判定結果はブール値ではなく、decision.result === AuthorizeResult.ALLOWです。- リソース権限では、判定がリソースに依存する場合(例:「所有者は更新できる」)、
authorizeよりauthorizeConditionalを優先してください。 条件付きの判定が返されるため、これをデータベースレベルのフィルターに変換でき、候補となるすべてのリソースをメモリに読み込む必要がなくなります。 usePermissionは非同期です。{ allowed, loading, error }を返します。読み込み中は<Skeleton />を表示してください。そうしないと、アクセス権の判定中に UI がちらつきます。- バックエンドプラグインの場合、
coreServices.permissionsとcoreServices.permissionsRegistryは@backstage/backend-plugin-apiから取得します。これらはプラグインのスコープに限定されており、プラグインには、そのプラグイン自身の pluginId をすでに認識しているPermissionsServiceが提供されます。
コメント
Markdown 対応