「認可済みリソース型」は既存研究の直訳ではなく設計上の合成
Document を認可したあと EditableDocument や Authorized[Document] に変換し、その型だけを business logic へ渡す、という設計は直感的に魅力がある。
DocumentID
-> Document
-> authorize
-> EditableDocument
-> business logic
しかし、今回確認した一次文献の範囲では、この形をそのまま一般的な「認可済みリソース型」パターンとして定式化・命名した主要研究は見つけられなかった。近接する研究はいくつもあるが、それぞれ意味が違う。
- Object-Capability は authority を参照の到達可能性で表す — authority を unforgeable reference の保持・到達可能性として表す
- Proof-Carrying Authorization は認可結果ではなく証明を持ち運ぶ — authorization の成立を logical proof として運ぶ
- 型システムで「認可ポリシーを守るコード」を検証する研究 — policy proposition と implementation の対応を dependent/refinement type で検証する
- AURA と PCML₅ は認可ロジックをプログラム構造へ組み込む — authorization assertion や proof obligation を programming language の一級概念にする
- Zanzibar / OpenFGA は認可関係をデータとして表す — principal-resource relationship を外部データとして表す
- Cedar の PARC は resource を認可問い合わせの一級要素にする — principal/action/resource/context を authorization request の一級要素にする
したがって EditableDocument は、それらのどれかの「実装例」と断言するより、複数の考え方を普通の型システムへ落とす engineering synthesis と呼ぶ方が正確である。
型を作るだけでは authority にならない
特に object-capability との類似を主張するときは注意が必要である。次のコードで EditableDocument の constructor を隠しても、下流コードが汎用 DB や DocumentRepository を持っていて任意の Document を再取得できるなら、authority は EditableDocument だけに制約されていない。
type Scope struct {
Editable EditableDocument
DB *sql.DB // ここから別 Document を取り直せる
}
この場合 EditableDocument は「この resource について authorization check を通過した」という evidence / marker としては使えるが、capability confinement とは言いにくい。
これは tanukirpc の tanukirpc の RouteWithTransformer を capability と読む際にも重要である。Reg2 が Reg1 を埋め込み、Reg1 が DB や unrestricted repository を持ち続ける設計なら、下位 handler は認可済み resource を受け取りつつ、同時に bypass path も保持する。
type ProjectScope struct {
*AppRegistry // DB / repository を引き継ぐ
Project *Project
}
したがって現在の RouteWithTransformer を object-capability mechanism そのもの と呼ぶのは強すぎる。より正確には、認可済み resource/evidence を request-local dependency graph へ追加する仕組みと読める。
capability 的な性質を強めるなら、変換後 scope から unrestricted authority を除き、必要な resource-specific operation だけを渡す設計が必要になる。
type EditableProjectScope struct {
Project EditableProject
// generic DB/repository は持たせない
}
一方、目的が「認可漏れを handler API 上で目立たせる」ことであれば、完全な capability confinement まで求めなくても wrapper には意味がある。ただし、その保証は「型があるから安全」ではなく、constructor の封鎖、raw resource 取得経路、scope に残る authority、lifetime を含めて評価する必要がある。
出典
🔗 リンクされているノート
- tanukirpc の RouteWithTransformer
- Webアプリのリソース認可パターン 調査ノート
- request-scoped DI をセキュリティコンテキストとして使う
- 認可済みリソースをハンドラ入力にすると前提を構造化できる
- 認可をプログラム構造で表す研究 調査ノート
- 認可済み値には lifetime と再検証の問題が残る
- Macaroons / Biscuit は権限を持ち運び、途中で弱められる
- Cedar の PARC は resource を認可問い合わせの一級要素にする
- Zanzibar / OpenFGA は認可関係をデータとして表す
- 型システムで「認可ポリシーを守るコード」を検証する研究
- Proof-Carrying Authorization は認可結果ではなく証明を持ち運ぶ
- Object-Capability は authority を参照の到達可能性で表す