タラバガニー設計局stalins.clubNOTE/notes/authorized-resource-as-handler-input

認可済みリソースをハンドラ入力にすると前提を構造化できる

リソースの取得と認可をハンドラの冒頭で毎回行う代わりに、認可に成功したリソースそのものをハンドラの入力として渡すという設計がある。

たとえば tanukirpc の RouteWithTransformer では、外側の Registry からパスパラメータに対応するリソースを取得し、認可後に別の Registry 型へ変換できる。Router[*App] の配下を Router[*ItemScope] に変換すれば、その内側のハンドラは ItemScope を受け取れること自体を前提にできる。さらに所有者専用なら OwnerScope へもう一段変換できる。API の詳細は tanukirpc の RouteWithTransformer にある。

FastAPI の依存関係システムでも、同じ構造を関数の依存グラフとして作れる。dependency は path parameter や認証済みユーザーを別 dependency から受け取り、DB から対象を取得し、認可に失敗すれば例外を返し、成功時だけモデルやラッパーを path operation 関数へ返せる。FastAPI に「AuthorizedResource」という特別な機能があるわけではないが、依存関係の返り値をその役割に使える。

この方式の重要な点は、認可チェックを一か所に寄せることだけではない。ハンドラが受け取れる値の集合そのものを狭めることにある。

ItemID
  -> Item
  -> ViewableItem
  -> OwnerItem

ハンドラ側から見ると「認可する」という副作用が消え、「この種類の入力を受け取ったなら、この操作をしてよい」という形になる。これは Route Model Binding はリソース解決を認可から分離する より一歩進み、解決済みと認可済みを区別する設計である。

ただし型名だけで安全になるわけではない。認可済み型を生成できる経路を制限し、その生成箇所が必ず正しいポリシーを通ることが必要になる。また権限が action ごとに細かく異なる場合は、ViewableItemEditableItemOwnerItem のような型や依存関係が増えすぎる可能性もある。

先行研究との位置づけ

より広い programming-language / access-control 研究を調べると、認可成立を boolean 以外で表す系譜として Object-Capability は authority を参照の到達可能性で表すProof-Carrying Authorization は認可結果ではなく証明を持ち運ぶ型システムで「認可ポリシーを守るコード」を検証する研究AURA と PCML₅ は認可ロジックをプログラム構造へ組み込む が存在する。

ただし、今回確認した一次文献の範囲では ViewableItem / EditableItem のような wrapper を一般的な resource authorization pattern としてそのまま定式化した主要研究は見つからなかった。したがって、このノートの方式を object-capability や proof-carrying authorization の直接の実装と呼ぶのは避けるべきである。詳しくは 「認可済みリソース型」は既存研究の直訳ではなく設計上の合成

特に変換後の scope に unrestricted DB/repository が残るなら、下流コードは wrapper を経由せず別 resource を取得できる。その場合 wrapper は authorization evidence としては有用でも、authority を wrapper に閉じ込めた capability とはいえない。

また、この evidence が有効な期間については 認可済み値には lifetime と再検証の問題が残る の問題が残る。

出典

▸ ノート一覧に戻る