Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Amazon Verified Permissionsを利用した 責務の分割のメリット・デメリ...

Amazon Verified Permissionsを利用した 責務の分割のメリット・デメリット / Advantages and Disadvantages of Separation of Responsibilities Using Amazon Verified Permissions

2023/08/26 Security-JAWS【第30回】[Security-JAWS DAYS] ~Day1~

Amazon Verified Permissionsを利用した責務の分割のメリット・デメリット
https://s-jaws.doorkeeper.jp/events/155024

西川 彰
Software Engineer, Security Engineering

株式会社カミナシ

August 25, 2023
Tweet

More Decks by 株式会社カミナシ

Other Decks in Technology

Transcript

  1. AVPとは アプリケーション向けの認可機能を提供しているサービス 対応している権限モデル • ロールベースアクセス制御(RBAC) • 属性ベースアクセス制御(ABAC) ポリシー言語 • Cedarを採用

    認可を外部化させることでアプリケーション開発を20%加速させた(らしい) AWS re:Inforce 2023 - Fine-grained authorization for apps with Amazon Verified Permissions(IAM 308)
  2. permit( principal in User::"alice", // 誰が action in [Action::"update", Action::"delete"],

    // 何を resource == Photo::"flower.jpg") // 何に when { context.mfa_authenticated == true && context.request_client_ip == "222.222.222.222" }; Cedar言語とは プリンシパルやリソースに関す ることをpermitに書く アプリケーションがリクエスト を受けた時点で初めてわかるも のなどをwhenに書く チュートリアルもあるので、まずは触ってみることをおすすめします Cedar Language Playground:https://www.cedarpolicy.com/en/tutorial/policy-structure
  3. { "url": "https://example.com/path/to?name=alice } contextで使用するデータは正規化して送信する { "url": { "transport": "https",

    "host": "example.com", "path": "/path/to" "queryParams": { "name": "alice", } } アプリケーションはポリシーが作成 しやすいように正規化して送信する permit (principal, action, resource) when { context.url.path == "/path/to" context.url.queryParams.name == "alice" };
  4. 正規表現は実装しないの? • リソースの過剰消費を防ぐ ◦ 攻撃者に意図的に評価の時間を掛けさせられないように • 「誰でも書ける」が阻害される ◦ CedarはSQLよりも簡単であるとうたっている ◦

    正規表現の場合、ぱっと見どういう内容かエンジニア以外の人がわかりづらい • 誤りに気付きにくい ◦ エラーになってもポリシーが無視されるだけなので気付きづらい ◦ 想定通りに動いているのかわかりづらい 以上のような理由で意図的に外されている 参考:https://cedarland.blog/design/why-no-regex/content.html  (Why doesn’t Cedar have regexes and string operators? - Cedarland Blog)
  5. ワイルドカードは条件でのみ利用できる permit ( principal == User::"3gi488f2-123c-820a-5678-e7fden84b398", action, resource ) when

    { resource.id like "image*.jp*" }; 書けるもののパフォーマンスが低下することがあると言及されている 合わせて「admin」に許可したつもりが「badminton-club」も許可されてしまったりする ので注意が必要(実際にあったらしい)
  6. permit( principal in User::"alice", action in [Action::"update", Action::"delete"], resource ==

    File::"hoge/image.jpg" ) エンティティには一意で普遍で再利用不可能なものを使用する これは推奨されていない aliceさんがこのシステムを利用しなくなった時のことを考える。 このルールが削除されなかった場合に、以前のaliceさんがアクセスできていたものに、 新しく利用を開始した別のaliceさんがアクセスできてしまう可能性がある
  7. ) when { !( principal.sports == "soccer") // sportsという要素がないとtrueになってしまう };

    ) when { principal has sports && !(principal.sports == "soccer") }; 要素を持っているかどうか確認する
  8. OIDCプロバイダーを利用する利点 permit( principal in User::"ap-northeast-1_12345|12345678-ref8d9-4033-a750-4c8622d62fb6", action in [Action::"update", Action::"delete"], resource

    == Photo::"flower.jpg") when { principal.cognito.username == "nishikawa" && principal has custom && principal.custom has sports && principal.custom.sports == “soccer” }; Cognitoが持っている情報を条件 に利用できたり、OIDCで持って いる情報をCustom claimを使っ て比較できる
  9. こんな感じで認可の検証ロジックをコードから消すことができる(スッキリ) function huga(request): if (!isAdmin(request.user)) { return Exception('Access Denied'); }

    if (request.ip_addr == '会社のIPアドレス') { return Exception('Access Denied'); } : : function huga(request): if (!client.is_authorized(...)) { return Exception('Access Denied') } コードがシンプルになり、ビジネスロジックでは認可に関して気にしなくてよくなる!
  10. AVPとビジネスロジックが切り分けられない場合 function show(request, id): if (!client.is_authorized(request)) { return Exception('Access Denied')

    } : select = "" if (is_jinji(request)) { // こういう条件を加えてしまっている場合 select = ",name" } sql = "SELECT profile" + select + " FROM human_resources" いわゆるRESTfulAPIのアンチパターン を書いてしまうと厳しい
  11. AVPとビジネスロジックが切り分けられない場合 function show(request, id): if (!client.is_authorized(request)) { return Exception('Access Denied')

    } : : select = "" if (!is_business(request)) { // エンタープライズプランなら機密情報へのアクセス可能 select = ",secret" } sql = "SELECT profile" + select + " FROM human_resources" permit (principal, action, resource) when { principal has custom && principal.custom has plan && principal.custom.plan in [“business”, “enterprise”, “personal”] };             後から追加した条件によって本来enterpriseしかアクセス できないデータにpersonalプランの人もアクセスできてし まう
  12. シングルサービスにおける責務分割パターンのメリット・デメリット アプリケーション開発者がポリシーを書く場合 メリット • 構成としてはシンプルで推奨されている形 • アプリケーションとポリシーと同期が取りや すい デメリット •

    メンテナンスが多重で発生する可能性がある • アプリケーションのコンテキストを把握して いる必要があるので詳細を監査できるのか不 明 ポリシー管理者がポリシーを書く場合 メリット • アプリケーション開発者が一切認可のこと を気にしなくてよくなる デメリット • アプリケーションのコンテキストをポリ シー管理者が把握する必要がある ◦ そのためにアクセス管理者と共同で動 く必要がある • ビジネスロジックに認可が絡むと事故が起 きる可能性がある アプリケーション開発者がポリシーも書く場合 ポリシー管理者がポリシーを書く場合
  13. マルチサービスにおける責務分割パターンのメリット・デメリット アプリケーション開発者がポリシーを書く場合 サービスAの開発者がポリシーを触ることによっ てサービスBに影響が出てしまう可能性があるな どマルチサービスの場合はそもそも向いていない ポリシー管理者がポリシーを書く場合 メリット • アプリケーションとポリシー作成者が分か れているため責任を分割させやすい

    • マルチサービスの場合、この構成以外考え づらい(メリット?) デメリット • 監査として「第三者」という観点が抜ける ◦ アクセス管理者と共同で作業するなど の運用ルールである程度は担保できる かも アプリケーション開発者がポリシーも書く場合 ポリシー管理者がポリシーを書く場合
  14. 参考 Amazon Verified Permissions Documentation https://docs.aws.amazon.com/verifiedpermissions/ Amazon Verified Permissions workshop

    https://catalog.workshops.aws/verified-permissions-in-action/en-US/10-intro/getting-started Cedarのチュートリアル https://www.cedarpolicy.com/en/tutorial Cedarポリシー評価のテスト https://github.com/Pigius/cedar-authorization-service/tree/main