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

Open Policy Agentを用いたAPI Gatewayの認可制御 / Authorization in API Gateway using Open Policy Agent

Rina Ueno
September 17, 2021

Open Policy Agentを用いたAPI Gatewayの認可制御 / Authorization in API Gateway using Open Policy Agent

Rina Ueno

September 17, 2021
Tweet

Other Decks in Technology

Transcript

  1. © Hitachi, Ltd. 2021. All rights reserved.
    Open Policy Agentを⽤いたAPI Gatewayの認可制御/
    Authorization in API Gateway using Open Policy Agent
    Hitachi OSS Tech Talk#1
    2021.09.17
    Hitachi, Ltd. R&D Group
    Rina Ueno

    View Slide

  2. © Hitachi, Ltd. 2021. All rights reserved.
    認可制御へのOPAの適⽤
    本セッションはOPAのユースケースのうち、認可制御を⾏う
    1
    6
    © Hitachi, Ltd. 2021. All rights reserved.
    2-1 OPAの主なユースケース
    Kubernetes
    CI/CD Authorization
    Service Mesh
    pAPI GWなどでの認可処理
    pRBAC, ABAC, JWT(JSON Web Token)
    pPath, HTTP Method
    pService間 でのアクセス制御
    pSource , Destination
    pJWT/x509 SVIDs
    pManifestの検査
    pLabel
    pResource Requests/Limits
    p自動/継続的な検査
    pDependency (Image, Package)
    pK8s Configs, Resources Check

    View Slide

  3. © Hitachi, Ltd. 2021. All rights reserved. 2
    1. API Gatewayと認可制御
    2. API GatewayへのOPA適⽤⽅式
    3. API GatewayとOPA連携の実装例
    4. OPAの注意点とその対策
    ⽬次

    View Slide

  4. © Hitachi, Ltd. 2021. All rights reserved.
    1. API Gatewayと認可制御
    3

    View Slide

  5. © Hitachi, Ltd. 2021. All rights reserved.
    APIアクセス制御にはセキュリティ機能のとして「認証」「認可」がある
    API Gatewayのアクセス制御
    4
    ※ シングルサインオン(SSO)とは、1度システム利⽤開始のユーザー認証 (ログイン) を⾏う
    と、複数のシステムを利⽤開始する際に、都度認証を⾏う必要がない仕組み。
    API
    Gateway
    アクセス
    アクセス
    Client
    API
    API
    API
    SSOサーバ ユーザID管理
    エンドユーザ
    API管理、
    アクセス制御 (認可を含む)
    ユーザは誰? APIへのアクセス権限はある?

    View Slide

  6. © Hitachi, Ltd. 2021. All rights reserved.
    API Gatewayで認可制御を⾏う上での課題
    5
    認可処理の再利⽤性の向上
    API API
    認可処理や設定⽅法がAPI GatewayやSSOの機能のソ
    フトウェアの仕様に依存する。類似の処理でも使⽤するソフ
    トごとに個別で設計・設定する必要がある。
    認可処理のテスト容易性の向上
    API Gateway は⼀般に認可判定処理とアクセス制御の
    処理が⼀連で⾏われるため、認可判定のみのテストが困
    難。認可判定の単体テストのために実環境へのAPI
    Gatewayデプロイやダミーアクセス等が必要になる。
    Log

    View Slide

  7. © Hitachi, Ltd. 2021. All rights reserved.
    Open Policy Agent (OPA) の活⽤
    6
    • 軽量かつ汎⽤的なポリシーエンジン
    • ポリシーに反するデータを検出
    • ポリシーはコード化してファイルに記述
    • CNCF Graduated Project
    開発時や運⽤時におけるルールを規定したもの
    Policy as Code

    View Slide

  8. © Hitachi, Ltd. 2021. All rights reserved.
    2. API GatewayへのOPA適⽤⽅式
    7

    View Slide

  9. © Hitachi, Ltd. 2021. All rights reserved.
    API GatewayでのOPA活⽤のメリット
    8
    ポリシーロジックとビジネスロジックの分離
    → 認可処理とAPI Gatewayの依存性を排除
    再利⽤性
    OPAで認可制御を共通化。
    認可処理をコード化すれば、
    類似案件に再利⽤しやすい。
    テスト容易性
    • 認可処理のみのテストが可能
    • OPAは単体テスト機能を持ち、
    テスト⾃動化もしやすい。
    API
    Gateway
    Client API
    SSOサーバ 認証
    アクセス制御 (認可を含む)
    OPA 認可
    ポリシーロジック
    ビジネスロジック

    View Slide

  10. © Hitachi, Ltd. 2021. All rights reserved.
    Token Introspection型のOPA適⽤パターン
    9
    Ø OAuth 2.0の
    Token Introspectionを⽤い
    て、SSOサーバにトークンの有効
    性を検証させる⽅式
    Ø 利点
    • シンプルで実装しやすい
    • ⼀般でよく使われる
    ※ OAuth 2.0の署名検証を⽤いた「署名検証型のOPA連携パターン」も検討した。
    API Gateway
    Resource
    Server
    A-3. トークンの要求
    A-1. 認証(OIDC, SAML, etc.)
    A-4. トークン発⾏
    (JWS, etc.)
    B-7. アクセス
    (A-1~A-4は初回のみ実施)
    • 属性の取得 : JWSのParse
    • アクセス可否の判定 :
    URL・属性から判定
    (true/false)
    Client
    App.
    OPA
    REST Server
    mode
    B-6. アクセス制御
    B-4. 認可判定
    B-3. Token Introspection
    SSO
    B-1. アクセス
    (with JWS)
    B-5. 結果通知
    (true/false)
    B-2. 認可依頼
    (with JWS)
    A-2. 認証処理

    View Slide

  11. © Hitachi, Ltd. 2021. All rights reserved.
    3. API GatewayとOPA連携の実装例
    10

    View Slide

  12. © Hitachi, Ltd. 2021. All rights reserved.
    • 銀⾏⼝座へのアクセスを模したサンプル
    • ClientごとにScopeを設定。ScopeとHTTP Methodを対応させてアクセス制御
    SSO Server
    OPAによるAPI Gatewayアクセス制御のシナリオ例
    11
    Users Clients Scope 備考
    john
    kakeibo account-read 家計簿アプリ
    atm
    account-read
    account-write
    ATMアプリ
    an_account Realm
    GET /bankaccount
    POST /bankaccount
    ※API GatewayやOPAは
    シナリオに直接関係しないため省略
    銀⾏⼝座取引API
    凡例
    Access
    Denied
    Access
    Allowed

    {
    "id" : ,
    "update_time": ,
    "operation" : "[deposit|withdrawal]",
    "expense" : "",
    "memo" : ""
    }
    kakeibo
    atm
    john
    Users Clients
    scope: account–read
    が必要
    scope: account–write
    が必要

    View Slide

  13. © Hitachi, Ltd. 2021. All rights reserved.
    システム構成
    • Amazon API Gatewayを使⽤
    • API Gatewayの認可処理はLambda Authorizerを⽤い、その内部でOPAを動作
    12
    クライアント
    銀⾏⼝座取引API
    認可処理
    AWS EC2
    Instance
    Keycloak®
    Subnet
    AWS Lambda
    Authorizer
    OPA Lib.
    Amazon
    API Gateway
    7. アクセス
    5. 認可判定
    読み込み
    4. Token Introspection
    Amazon
    VPC
    Endpoint
    1. JWSトークン取得(ログイン処理)
    2. アクセス
    (with JWS)
    3. 認可依頼
    (with JWS)
    6. 結果通知
    (true/false)
    AWS Lambda
    (BankApp)
    Amazon S3
    Bucket
    policy.rego
    data.json
    AWS EC2
    Instance
    Client App.
    2. アクセス
    (with JWS)

    View Slide

  14. © Hitachi, Ltd. 2021. All rights reserved.
    OPAのポリシー 1/3 (ルール)
    13
    package authz
    # What is this?
    #
    # Token Introspection方式でトークンの正当性をチェックし、
    # その後、jwsトークン内のrolesとHTTP MethodsからRBACベースの認可判定を行う
    # 入出力のサンプルは末尾に記載
    default allow = false
    default authenticate = false
    default authorize = false
    # アクセス制御を判断するメインの処理。
    # authenticate == true && authorize == true が条件
    allow {
    authenticate
    authorize
    }
    # 処理時間最適化のため、decodeは1回で済ませる
    params := get_cid_and_scopes(input.access_token)
    # token_intospectionを用いたトークン正当性チェックのルール
    # JWSのClient IDがdataで指定した値の場合、対応するClient Secretとともに
    token_introspectionを実行し、
    # そのリクエストが成功し(200)、かつtokenがactiveであればtrue
    authenticate {
    some x
    params.client_id == data.clients[x].id
    client_secret := data.clients[x].secret
    keycloak_url := get_url(data.base_url, data.realm,
    data.introspect_format)
    result := token_introspection(input.access_token, keycloak_url,
    params.client_id, client_secret)
    result.status_code == 200
    result.active == true
    }
    # JWS内のscopeとHTTP Methodを用いた認可チェックのルール
    # grants内に指定されたRole(account-read/account-write)があり、
    # かつHTTP MethodがRoleに許可されたactionならばtrue
    authorize {
    some x
    params.scopes[_] == data.grants[x].role
    upper(input.method) == data.grants[x].action[_]
    }

    View Slide

  15. © Hitachi, Ltd. 2021. All rights reserved.
    OPAのポリシー 2/3 (関数)
    14
    token_introspection(
    access_token,
    keycloak_url,
    client_id,
    client_secret,
    ) = {"status_code": status_code, "active": active} {
    # Keycloakにtoken introspectionを行う関数
    # Keycloakの token/introspect にpostリクエストを投げ、ステータスコードとトークン
    正当性を返す
    #
    # Args:
    # access_token (string): jwsのアクセストークン
    # keycloak_url (string): Token Introspectionを行うURL。realm情報が
    埋め込まれているため注意
    # client_id (string): クライアントの名前。今回はbank_app
    # client_secret (srting): クライアントのシークレット情報。詳しくはKeycloak
    のドキュメント参照
    #
    # Returns:
    # object: 以下2種のデータを含む
    # status_code (int) : HTTPのstatus code。200が正常
    # active (boolean) : トークン正当性
    auth := base64.encode(concat(":", [client_id, client_secret]))
    body := urlquery.encode_object({
    "token_type_hint": "access_token",
    "token": access_token,
    })
    resp := http.send({
    "method": "post",
    "url": keycloak_url,
    "raw_body": body,
    "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": concat(" ", ["Basic", auth]),
    },
    })
    status_code := resp.status_code
    active := resp.body.active
    }

    View Slide

  16. © Hitachi, Ltd. 2021. All rights reserved.
    OPAのポリシー 3/3 (関数)
    15
    get_cid_and_scopes(access_token) = {"client_id": client_id, "scopes":
    scopes} {
    # JWSトークンをデコードし、client_idとscopesを抽出する関数
    #
    # Args:
    # access_token (string): decode対象のjwsトークン
    #
    # Returns:
    # object: 以下2種のデータを含む
    # client_id (string) : JWSが指定するClient ID
    # scopes (list of strings) : JWSのトークン正当性
    [_, payload, _] := io.jwt.decode(access_token)
    client_id := payload.azp
    scopes := split(payload.scope, " ")
    }
    get_url(base_url, realm, format) = url {
    # 引数を基にKeycloakのURLを生成する関数
    #
    # Args:
    # base_url (string): プロトコルとドメインとポート番号。
    http://example:8080 など
    # realm (string): Realm名
    # format (string): URLの雛形。変数は%vで表現。
    #
    # Returns:
    # string: KeycloakのURL
    url := sprintf(format, [base_url, realm])
    }
    #---------------------------------------------
    # 入力サンプル
    # {
    # "access_token": ,
    # "method": "get"
    # }
    # --------
    # 出力サンプル(result[0].expressions[0].value.allowが判定結果)
    # {
    #
    # }

    View Slide

  17. © Hitachi, Ltd. 2021. All rights reserved.
    JSONファイルを⽤いた固有情報の分離
    16
    案件固有データ data.json
    {
    "base_url": "http://demo.ap-northeast-1.compute.internal:8080",
    "realm": "an_account",
    "introspect_format": "%v/auth/realms/%v/protocol/openid-connect/token/introspect",
    "clients": [
    {
    "id": "kakeibo", "secret": "c109740e-4fe8-47be-82bf-5ad41c9f00a7"
    },
    {
    "id": "atm", "secret": "0239a3e0-5b6f-462c-af8d-5cc128c4e78d"
    }
    ],
    "grants": [
    { "role": "account-read", "action": [ "GET" ] },
    { "role": "account-write", "action": [ "POST", "PUT" ] }
    ]
    }
    案件ごとに異なる値はRegoファイル(ポリシー)から分離してJSONファイルに集約
    →ポリシーの可搬性向上

    View Slide

  18. © Hitachi, Ltd. 2021. All rights reserved.
    OPAを⽤いた認可処理テストの実⾏例
    17
    「トークンとメソッドの記述」と、「OPAのREPLでテスト実⾏するコード」を作成
    ⼊⼒データ input.json
    {
    "access_token": ,
    "method": "get"
    }
    ポリシー実⾏コード eval.sh
    #!/bin/bash
    opa eval --fail -i input.json -d policy.rego -d data.json "data.authz"
    ポリシー実⾏⽤のファイルディレクトリ
    $ tree
    .
    ├── data.json
    ├── eval.sh
    ├── input.json
    └── policy.rego

    View Slide

  19. © Hitachi, Ltd. 2021. All rights reserved.
    OPAを⽤いた認可処理テストの実⾏例(出⼒結果)
    18
    kakeibo
    get
    kakeibo
    post
    atm
    post
    atm
    get

    View Slide

  20. © Hitachi, Ltd. 2021. All rights reserved.
    4. OPA適⽤時の注意点とその対策
    19

    View Slide

  21. © Hitachi, Ltd. 2021. All rights reserved.
    注意点1 Rego ⾔語の学習容易化
    Rego ⾔語での特有な記述⽅法に慣れるまではポリシーの作成コストが⼤きい
    20
    • ⼀般的なユースケースについて作成
    • 学習/作成時間の削減
    コードのサンプルやガイドラインを作成
    • 関数の説明⽂を記述
    • ポリシーの処理の理解の容易化
    Docstring ※1の記述
    ※1 Docstring:Pythonのコメント表記⽅式
    sample-
    policy-
    1.rego
    sample-
    policy-
    2.rego
    sample-
    policy-
    3.rego
    OPA Repo. # JWSトークンをデコードし、client_idとscopesを抽出する関数
    #
    # Args:
    # access_token (string): decode対象のjwsトークン
    #
    # Returns:
    # object: 以下2種のデータを含む
    # client_id (string) : JWSが指定するClient ID
    # scopes (list of strings) : JWSのトークン正当性

    View Slide

  22. © Hitachi, Ltd. 2021. All rights reserved.
    注意点2 挙動や処理のトレースの容易化
    OPAはルールの判定結果しか出⼒されず、出⼒を得るまでの挙動/処理を追いにくい
    trace関数を活⽤し、処理を追えるようにする
    21
    ※1 Explanationの出⼒⽅法の情報がなかったため、筆者が内容を調査して公式ドキュメントに記載(merge済)
    API Parameter Example
    CLI --explain
    opa eval --explain=notes
    --format=pretty 'trace("hello world")'
    HTTP explain=notes curl localhost:8181/v1/data/example/allow?explain=notes&pretty
    REPL notes n/a
    trace 関数
    § ルールや関数内で処理途中の変数を出⼒するなど`printf`のように利⽤できる。引数は⼀つの⽂字列のみ。
    § trace関数の処理結果の出⼒にはExplanationの出⼒を有効化する必要あり※1

    View Slide

  23. © Hitachi, Ltd. 2021. All rights reserved.
    参考) Fregotを⽤いたOPAのデバッグ
    Fregotとは?
    § Fugue Rego Toolkit
    § Rego⾔語開発を⽀援するサードパーティーツール
    § CLIにて対話形式でのポリシーのステップイン実⾏
    が可能(REPL機能; 右画像)
    利点
    § エラーメッセージが充実
    注意点
    § regoエンジンが古く、最近の関数には未対応
    最終更新: 2021.4.8
    § data.json(固有値記述ファイル)には未対応
    22
    fregotのHPより引⽤

    View Slide

  24. © Hitachi, Ltd. 2021. All rights reserved.
    まとめ
    1. OPAを⽤いた認可制御を紹介
    ◇ メリットは「認可処理の再利⽤性・テスト容易性の向上」
    ◇ API GatewayへのOPA適⽤は「Token Introspection⽅式」
    2. Amazon API GatewayとOPA連携の実装例を紹介
    3. 事業へOPA適⽤する際の注意点とその対策を紹介
    ◇ 注意点「Rego ⾔語の学習容易化」のため、
    サンプルコードやコーディングガイドラインを作成、Docstringに関数説明を記述
    ◇ 注意点「デバッグの容易化」のため、trace関数を活⽤し処理を追跡
    23

    View Slide

  25. © Hitachi, Ltd. 2021. All rights reserved.
    商標
    § Open Policy Agentは、 The Linux Foundationの⽶国またはその他の国における登録商標または
    商標です。
    § Keycloakは、Red Hat, Inc.の⽶国またはその他の国における登録商標または商標です。
    § Fregotは、 Fugue, Inc.の⽶国またはその他の国における登録商標または商標です。
    § Amazon Web Services, Amazon API Gateway, Amazon VPC, Amazon EC2, AWS Lambda,
    Amazon S3, AWS CloudFormation, Amazon Cognito, AWS IAM は、⽶国および/またはその他
    の諸国における、Amazon.com, Inc. または その関連会社の商標です。
    § その他記載の会社名、製品名、サービス名、その他固有名詞は、
    それぞれの会社の商標または登録商標です
    § 本発表中の⽂章、図では、TM、🄬マークは表記しておりません。
    24

    View Slide

  26. View Slide