タラバガニー設計局stalins.clubNOTE/notes/request-scoped-authorization-evidence-has-a-lifetime

認可済み値には lifetime と再検証の問題が残る

認可後に EditableDocument や request-local scope を作れば、その値の lifetime を HTTP request 程度に限定できる。これは長寿命 credential を配布するより扱いやすいが、request scope にしただけで revocation や TOCTOU が解決するわけではない

t0: resource を読む
t1: authorization を確認する
t2: AuthorizedResource を作る
t3: 権限・resource state が変わる
t4: 書き込みを行う

t1 で成立した authorization が t4 でも成立する保証は、wrapper の型だけからは得られない。

capability system でも revocation は古くから独立した問題として扱われている。J-Kernel/Luna の研究は、通常の Java pointer を capability として渡すと一度渡した pointer を revoke できない点を明示し、indirection や remote pointer の仕組みを導入している。storage capability の研究でも object version や capability ID/group を使った revocation mechanism が別途必要になる。

cryptographic capability credential でも同様で、Biscuit は token ごとの revocation identifier を提供するものの、revocation list/database などの external state management は specification の外にあると明記している。

したがって request-local authorization evidence については、少なくとも次を別々に考える必要がある。

  • lifetime — その値をどこまで持ち出せるか
  • revocation — 発行後に authority を失効させられるか
  • freshness — authorization が参照した membership / owner / state がまだ同じか
  • atomicity — authorization check と side effect の間で前提が変化しないか

request-scoped DI をセキュリティコンテキストとして使う の Registry/DI scope は lifetime を短くするには都合がよい。しかし、それは主に値の生存期間に関する性質であり、authorization state の atomicity を保証するものではない。

たとえば「project member なら更新可」が transaction 中にも変更され得るなら、write transaction の中で membership を再確認する、policy version を比較する、resource update 自体を条件付き SQL にする、といった application-level mechanism が必要になる場合がある。

このため 「認可済みリソース型」は既存研究の直訳ではなく設計上の合成 を設計する際、Authorized<T> を「永続的な権限証明」と考えるより、ある時点・ある scope で認可を通過した evidence と考える方が安全である。

出典

▸ ノート一覧に戻る