Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS のポリシー言語 Cedar を活用した高速かつスケーラブルな認可技術の探求 #phpe...

y_taka_23
March 22, 2025

AWS のポリシー言語 Cedar を活用した高速かつスケーラブルな認可技術の探求 #phperkaigi / PHPerKaigi 2025

PHPerKaigi 2025 で使用したスライドです。

Web アプリケーションのセキュリティ設計において、特定のユーザーに対してどの操作を許可するかという認可の設計は欠かせない要素です。近年では、マイクロサービスやゼロトラストの考え方が普及し、サーバー間の認可を含むより複雑な機能が求められています。

このような複雑な認可を効果的に管理する方法の一つとして、認可ロジックをアプリケーションから分離し、外部化して再利用可能なポリシー言語で定義する手法があります。AWS IAM はこのようなポリシー言語の一例ですが、AWS に限定されない一般用途にも Open Policy Agent (OPA) が広く知られています。

本セッションでは、認可の課題に対する新たなキラーソリューションとして、Cedar を紹介します。Cedar は AWS によって開発されたポリシー言語で、Amazon Verified Permissions としてマネージドサービスが提供されているほか、AWS 以外の環境でも使用可能な OSS としても公開されています。

OPA と比較した Cedar の顕著な特徴は、大量のルールを定義した場合のパフォーマンスにあります。このパフォーマンスは、一度評価された条件を部分的にキャッシュし再利用する仕組みにより実現されており、そのキャッシュ戦略の正当性は数学的に厳密に証明されています。このように、Cedarは高度な理論が実際のプロダクトに価値を提供する興味深い事例といえるでしょう。

Cedar は 2024 年に論文が発表されたばかりであり、理論的な詳細に関する日本語情報はほとんど存在しません。そのため、本セッションでは参加者が認可エンジンの内部機構と特性を深く理解し、実際のアプリケーションのセキュリティ設計に役立てられることを目指して、Cedar に対して応用と理論の両面から Deep Dive します。

プロポーザル:https://fortee.jp/phperkaigi-2025/proposal/f1d9f83e-790a-41be-a0e9-3a8a47cc164f

y_taka_23

March 22, 2025
Tweet

More Decks by y_taka_23

Other Decks in Technology

Transcript

  1. Cedar: A New Language for Expressive, Fast, Safe, and Analyzable

    Authorization J. W. Cutler et al. (OOPSLA 2024) https://doi.org/10.1145/3649835
  2. マイクロサービスに対する認可 • アプリ開発チームの苦労 ◦ 似たような判定を各チームが各言語で実装 ◦ 実装は別なのに、概念として一貫していないと動かない • セキュリティ /

    CCoE チームの苦労 ◦ セキュリティ統制的に共通のガードレールを敷きたい ◦ 実装は別なので、ルールに対する合致を監査できない
  3. PDP と PEP • Policy Decision Point (PDP) ◦ ポリシー言語に基づきアクセス要求を評価

    ◦ 許可(Allow)または拒否(Deny)を判断 • Policy Enforcement Point (PEP) ◦ PDP に判断を仰いで実際のアクセス制御を行う ◦ Web アプリでは API Gateway やバックエンド実装
  4. ポリシー言語としての IAM • IAM も PDP の一種とみなせる ◦ PEP は各種

    AWS サービス、操作対象は AWS リソース ◦ Principal / Action / Resource / Condition で指定 • 複数チームがポリシーを定義しても最終結果は安全側 ◦ Deny が一つでもあれば Allow より優先 ◦ ポリシーの順番や重複で結果が変わらない
  5. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ec2:TerminateInstances"],

    "Resource": ["*"], "Condition": { "IpAddress": { "aws:SourceIp": ["192.0.2.0/24"] } } } ] }
  6. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ec2:TerminateInstances"],

    "Resource": ["*"], "Condition": { "IpAddress": { "aws:SourceIp": ["192.0.2.0/24"] } } } ] } AWS 特化
  7. Cedar が目指す立ち位置 • 表現力が高い ◦ RBAC と ABAC を組み合わせて設計できる •

    パフォーマンスが高い ◦ 高速で、ポリシー数に対して速度が劣化しづらい • ポリシーの意味が理解しやすい ◦ 人間にとってはもちろん、自動解析の基礎も整っている
  8. Amazon Verified Permissions • AWS マネージド版の Cedar エンジン ◦ PDP

    は単一障害点なので管理したくない ◦ PHP 含め各言語の SDK でアクセス可 • Amazon Cognito とも連携可能 ◦ 認証:Cognito User Pool ◦ 認可:Verified Permissions https://aws.amazon.com/jp/verified-permissions/
  9. API Gateway を PEP とするパターン DynamoDB Authorizer API Gateway Verified

    Permissions Cognito User Application Allow / Deny User Pool 連携
  10. その他の OSS ポリシー言語 • Open Policy Agent (OPA) ◦ おそらく最も有名で広く使われている

    ◦ Prolog ベースの Rego 言語による記述 • OpenFGA ◦ Google の認可基盤 Zanzibar がベース ◦ エンティティ間のグラフ構造による記述 https://github.com/open-policy-agent https://github.com/openfga
  11. Section 1 のまとめ • PDP と PEP の分離 ◦ 認可処理を直接アプリに密結合したくない

    ◦ アプリとは分離して専用のポリシー言語で記述 • OSS ポリシー言語 Cedar ◦ マネージド版が Verified Permissions として利用可 ◦ 表現力 / パフォーマンス / 解析可能性
  12. Cedar によるポリシー記述 • 効果は permit(許可)/ forbid(拒否) ◦ 複数該当する場合は forbid が優先される

    • エンティティの三つ組を基本としてルールを記述 ◦ Principal:alice が(操作主体) ◦ Action:写真を閲覧する(操作内容) ◦ Resource:photo01.png を(操作対象)
  13. permit ( principal == PhotoApp::User::"alice", action == PhotoApp::Action::"viewPhoto", resource ==

    PhotoApp::Photo::"photo01.jpg" ); forbid ( principal == PhotoApp::User::"bob", action == PhotoApp::Action::"viewPhoto", resource == PhotoApp::Photo::"photo02.jpg" ); 基本となるポリシー
  14. permit ( principal == PhotoApp::User::"alice", action == PhotoApp::Action::"viewPhoto", resource ==

    PhotoApp::Photo::"photo01.jpg" ); forbid ( principal == PhotoApp::User::"bob", action == PhotoApp::Action::"viewPhoto", resource == PhotoApp::Photo::"photo02.jpg" ); 基本となるポリシー alice は photo01.jpg を閲覧できる
  15. permit ( principal == PhotoApp::User::"alice", action == PhotoApp::Action::"viewPhoto", resource ==

    PhotoApp::Photo::"photo01.jpg" ); forbid ( principal == PhotoApp::User::"bob", action == PhotoApp::Action::"viewPhoto", resource == PhotoApp::Photo::"photo02.jpg" ); 基本となるポリシー bob は photo02.jpg を閲覧できない
  16. Cedar による RBAC • Role-Based Access Control (RBAC) ◦ Principal

    の所属関係に依存した判定 • Cedar では Principal に加え Resource もグループ化できる ◦ Principal:グループ team01 のメンバが ◦ Action:写真を閲覧する ◦ Resource:アルバム album01 内の写真を
  17. permit ( principal in PhotoApp::UserGroup::"team01", action == PhotoApp::Action::"viewPhoto", resource in

    PhotoApp::Album::"album01" ); RBAC によるポリシー team01 に含まれる任意の principal album01 に含まれる任意の resource
  18. Cedar による ABAC • Attribute-Based Access Control (ABAC) ◦ エンティティの持つ属性に依存した判定

    • Cedar では自由に属性が定義できる ◦ Principal:誰でも ◦ Action:写真を閲覧する ◦ Resource:自分が所有する(owner)写真を
  19. permit ( principal, action == PhotoApp::Action::"viewPhoto", resource ) when {

    resource has owner && resource.owner == principal }; ABAC によるポリシー
  20. permit ( principal, action == PhotoApp::Action::"viewPhoto", resource ) when {

    resource has owner && resource.owner == principal }; ABAC によるポリシー 指定がない = ワイルドカード
  21. permit ( principal, action == PhotoApp::Action::"viewPhoto", resource ) when {

    resource has owner && resource.owner == principal }; ABAC によるポリシー 属性 owner による指定
  22. permit ( principal == ?principal, action == PhotoApp::Action::"viewPhoto", resource ==

    ?resource ); ポリシーテンプレート API を叩いて動的に ポリシーをインスタンス化
  23. Schema によるバリデーション • 記述言語としての汎用性はエラーの温床 ◦ エンティティ名も属性名もユーザ定義 ◦ Undefined 属性を参照すると意図しない結果を招く •

    Cedar は組み込みのバリデーション機能をサポート ◦ ポリシー自体とは別に Schema を定義できる ◦ 違反したポリシーは登録時に弾かれる
  24. "Photo": { "shape": { "type": "Record", "attributes": { "owner": {

    "type": "Entity", "name": "User", "required": true } } }, "memberOfTypes": ["Album"] }
  25. Slice 処理の流れ 1. 予め Principal + Resource をキーとしてポリシーを保持 2. リクエストが来たら、その

    Principal と Resource から 遡れる祖先要素をそれぞれ求める 3. Principle と Resource たちの全ての組合せを求める 4. ポリシーの中で最終結果に影響するのは、 ここで求めた組合せをキーとするポリシーのみ
  26. Any photo01.jpg photo02.jpg album01 team01 alice bob Request = (

    alice, viewPhoto, photo01.jpg ) owner alice の祖先 photo01.png の祖先
  27. Principal Resource Any Any Any album01 Any photo01.jpg team01 Any

    team01 album01 team01 photo01.jpg alice Any alice album01 alice photo01.jpg Slice の絞り込み Key Principal Resource Effect Any photo02.png permit team01 album01 permit alice album01 permit bob album01 permit alice photo02.jpg permit bob photo02.jpg permit alice photo02.jpg forbid team01 photo01.jpg forbid bob photo01.png forbid 定義されている全 Policy
  28. Principal Resource Any Any Any album01 Any photo01.jpg team01 Any

    team01 album01 team01 photo01.jpg alice Any alice album01 alice photo01.jpg Slice の絞り込み Key Principal Resource Effect Any photo02.png permit team01 album01 permit alice album01 permit bob album01 permit alice photo02.jpg permit bob photo02.jpg permit alice photo02.jpg forbid team01 photo01.jpg forbid bob photo01.png forbid Slice で絞り込まれた Policy
  29. Principal Resource Any Any Any album01 Any photo01.jpg team01 Any

    team01 album01 team01 photo01.jpg alice Any alice album01 alice photo01.jpg Slice の絞り込み Key Principal Resource Effect Any photo02.png permit team01 album01 permit alice album01 permit bob album01 permit alice photo02.jpg permit bob photo02.jpg permit alice photo02.jpg forbid team01 photo01.jpg forbid bob photo01.png forbid forbid に該当するので結果は拒否
  30. パフォーマンスの比較 • Cedar > OpenFAG >> Rego • 特に Rego

    に比べ、Cedar はエンティティ数で速度劣化しない https://doi.org/10.1145/3649835
  31. Section 2 のまとめ • Cedar によるポリシー記述 ◦ Principal / Action

    / Resource で条件を指定 ◦ RBAC / ABAC / 動的なポリシー生成 • パフォーマンス上の特性 ◦ OpenFGA や Rego より高速でスケールに強い ◦ テンプレートポリシーに対して Slice が有効
  32. 言語仕様と信頼性 • 自然言語で書かれた仕様書による定義 ◦ C++ / Java / PHP など大多数の言語が採用

    ◦ 曖昧性や矛盾の発見は人間の観察力頼み • 形式的意味論による定義 ◦ 言語の動作について厳密な数学的ルールを提供 ◦ アルゴリズムにより自動化された確実な検査が可能
  33. Cedar の形式的意味論 • ポリシーの評価規則 ◦ Alloy / Deny を判定する上で、対象のリクエストが ポリシーの条件に合致するかどうかを定義

    • ポリシーの型付け規則(今日は省略) ◦ Schema によるバリデーションの実体は型検査 ◦ capability と呼ばれる付帯条件付きの型付けを定義
  34. e = resource in PhotoApp::Album::"album01" σ = [ principal =>

    PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource => PhotoApp::Photo::"photo01.jpg" ] μ = [ PhotoApp::Photo::"photo01.jpg" => [ owner => PhotoApp::User::"alice", predecessors => { PhotoApp::Album::"album01" } ] ]
  35. e = resource in PhotoApp::Album::"album01" σ = [ principal =>

    PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource => PhotoApp::Photo::"photo01.jpg" ] μ = [ PhotoApp::Photo::"photo01.jpg" => [ owner => PhotoApp::User::"alice", predecessors => { PhotoApp::Album::"album01" } ] ] 祖先要素を保持
  36. e = resource in PhotoApp::Album::"album01" σ = [ principal =>

    PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource => PhotoApp::Photo::"photo01.jpg" ] μ = [ PhotoApp::Photo::"photo01.jpg" => [ owner => PhotoApp::User::"alice", predecessors => { PhotoApp::Album::"album01" } ] ] 書き換えたい式
  37. σ = [ principal => PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource

    => PhotoApp::Photo::"photo01.jpg" ] x = principal / action / resource に対して リクエストの x が v であるとき、 目的の式内の x を v で書き換えてよい e'= PhotoApp::Photo::"photo01.jpg" in PhotoApp::Album::"album01" e = resource in PhotoApp::Album::"album01"
  38. σ = [ principal => PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource

    => PhotoApp::Photo::"photo01.jpg" ] x = principal / action / resource に対して リクエストの x が v であるとき、 目的の式内の x を v で書き換えてよい e'= PhotoApp::Photo::"photo01.jpg" in PhotoApp::Album::"album01" e = resource in PhotoApp::Album::"album01" 前提条件
  39. σ = [ principal => PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource

    => PhotoApp::Photo::"photo01.jpg" ] x = principal / action / resource に対して リクエストの x が v であるとき、 目的の式内の x を v で書き換えてよい e'= PhotoApp::Photo::"photo01.jpg" in PhotoApp::Album::"album01" e = resource in PhotoApp::Album::"album01" 可能な書き換え
  40. σ = [ principal => PhotoApp::User::"alice", action => PhotoApp::Action::"viewPhoto", resource

    => PhotoApp::Photo::"photo01.jpg" ] x = principal / action / resource に対して リクエストの x が v であるとき、 目的の式内の x を v で書き換えてよい e'= PhotoApp::Photo::"photo01.jpg" in PhotoApp::Album::"album01" e = resource in PhotoApp::Album::"album01" x v
  41. μ = [ PhotoApp::Photo::"photo01.jpg" => [ owner => PhotoApp::User::"alice", predecessors

    => { PhotoApp::Album::"album01" } ] ] エンティティ E1::s1 の先祖に E2::s2 が含まれるとき、 in 式は true に書き換えてよい e'= true e = PhotoApp::Photo::"photo01.jpg" in PhotoApp::Album::"album01"
  42. μ = [ PhotoApp::Photo::"photo01.jpg" => [ owner => PhotoApp::User::"alice", predecessors

    => { PhotoApp::Album::"album01" } ] ] エンティティ E1::s1 の先祖に E2::s2 が含まれるとき、 in 式は true に書き換えてよい e'= true e = PhotoApp::Photo::"photo01.jpg" in PhotoApp::Album::"album01" h1 E1::s1 E2::s2
  43. 例:forbid がひとつでもあれば拒否 theorem forbid_trumps_permit (request : Request) (entities : Entities)

    (policies : Policies) : (∃ (policy : Policy), policy ∈ policies ∧ policy.effect = .forbid ∧ satisfied policy request entities ) → (isAuthorized request entities policies).decision = .deny
  44. 証明されている Cedar の性質 • forbid が一つでもあれば他に permit があっても拒否 • 許可されるのは

    permit が一つでもある場合のみ • ポリシーの重複や順序は結果に影響しない • Slice によるポリシーの絞り込みは結果に影響しない • バリデーションを通ったポリシーは評価時にエラーが起きない
  45. Section 3 のまとめ • 言語の意味論は厳密に定義できる ◦ 各規則は式の書き換えルールを与えている • 論文中では Cedar

    の意味論が与えられている ◦ ポリシーの評価 / 型付けによるバリデーション • Cedar の意味論は Lean を用いて検証されている ◦ コンパイルが通っていれば証明として正しい
  46. 本日のまとめ • マイクロサービスでのポリシー言語の役割 ◦ 認可(PDP)をアプリ(PEP)から分離 • Cedar / Amazon Verified

    Permissions の機能 ◦ RBAC / ABAC / テンプレート / バリデーション • 安全性が理論的に保証されている ◦ 形式的意味論 / 定理証明支援系 Lean による証明