3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

皆さんは普段どのようにMuleSoftを活用されているでしょうか。

多くの組織では、MuleSoftの優れた機能群とAPI-led Connectivityによる高いアジリティを活かして、生産性向上・デリバリ速度短縮・コスト削減といった社内開発効率化のために活用されているのではないかと思います。

ですが開発効率化が進んで組織内にAPIが浸透してくると、次のステップとして、資産化された社内のAPIをパートナ企業やエンドユーザへと公開し、APIビジネスをより拡大していく道が見えてきます。

そのタイミング、つまり「社内利用→社外公開」の拡張タイミングにおいて必ずぶつかる壁、それがセキュリティです。

  • 社外公開時のAPIセキュリティって何が必要なんだ。
  • これまでの社内利用から何を変えればいいんだ。
  • とりあえずAPIキーで上手いことやればいいんだよな。

まるで皆様からのそんな声が聞こえてくるかのようです。(幻聴)

本記事では、そのような「MuleSoftでAPIを公開したいけどセキュリティ分かんない」という方々に向けて、OSSのKeycloakをIdentity Provider (IdP)として活用したMuleSoftのAPIをセキュアに公開するためのソリューションを、具体的な手順と共に詳しくご紹介します。

※ 本記事は、あくまで執筆者の見解であり、日立製作所の公式なドキュメントではありません。

MuleSoftとは

MuleSoft はAPIの開発から運用までのAPI管理 (APIM) に必要な機能がAll-in-Oneで備わったクラウドプラットフォームです。
Gartner社によるAPIM製品の調査 でもリーダーとして評価されるなど、APIMプラットフォームの代表的な存在です。

Keycloakとは

Keycloak はIAM(Identity and Access Management)を実現するOSSです。2023/4にCloud Native Computing Foundation(CNCF)のプロジェクトに追加され、IAMにおけるOSSの定番になっています。

APIのユースケースとセキュリティ課題

APIのユースケース

まずはAPIのユースケースの分類を見ていきましょう。一般的にAPIのユースケースは以下の3つに分類されます。

  1. 社内利用
  2. パートナ連携
  3. エンドユーザ公開

image.png

冒頭でも記載した通り、多くの組織において、まずは社内開発効率化を目的とした「1.社内利用」から始められることが一般的です。
その後に社内利用が進んで、組織内でのAPI利用が一般的になりAPI資産が蓄積されてくると、次第に社内利用のみならずAPIのビジネスへの活用を検討するようになります。このフェーズになると「2.パートナ連携」や「3.エンドユーザ公開」へとユースケースが拡大し始めます。

社内から社外へ

この「1.社内利用」→「2.パートナ連携」「3.エンドユーザ公開」へのユースケース拡大によって、APIの公開範囲は社内から社外へと広がることとなります。

自明ではありますが、社内利用の場合と社外公開の場合とでは求められるセキュリティレベルが大きく異なります。

社内利用では、社内に閉じたイントラネット上のアクセス元が限定された環境での利用が主であり、IP制限やAPIキーによる簡易的なアクセス制御のみ (場合によっては全くのアクセス制御無し) でセキュリティ対策が十分なケースも少なくありません。

しかし、こと社外への公開となると、このような社内向けセキュリティ対策ではインターネット上に蔓延る攻撃者たちの格好の的です。

では、社外公開時にはどのようなAPIセキュリティ対策を行えばよいのでしょうか。

社外公開に必要なAPIセキュリティ

このような時に参考になるのが、OWASPのレポート「OWASP Top 10 API Security Risks – 2023」 です。

OWASPはセキュリティの分野で世界的に権威のある非営利団体で、世界各国の政府機関や大手企業のセキュリティ対策にも携わっており、OWASPがまとめたレポートの多くはセキュリティ分野のデファクトスタンダードとして認識されています。

OWASP Top 10 API Security Risks - 2023はそれらレポートのうちの最も有名な「OWASP Top 10シリーズ」の1つで、APIセキュリティにおける主要なセキュリティリスクの上位10項目をまとめたレポートです。

以下がそのレポート内で挙げられている10項目です。

  1. オブジェクトレベルの「認可」の不備
  2. 「認証」の不備
  3. オブジェクトプロパティレベルの「認可」の不備
  4. 無制限な資源消費
  5. 機能レベルの「認可」の不備
  6. 機密性の高いフローへの制限のないアクセス
  7. サーバーサイドリクエストフォージェリ
  8. セキュリティの設定不備
  9. 不適切な資産管理
  10. 安全でないAPIの消費

様々な観点でのリスクが存在しますが、最も注目すべきは太字で記載している「認可」の不備のリスクでしょう。Top10のうち1位・3位・5位を「認可」の不備のリスクが占めています。

このことから分かる通り、APIセキュリティで真っ先に考慮すべきはそう、「認可」ですね。

ということで本記事ではMuleSoft上のAPIの社外公開時におけるセキュリティ対策を、この「認可」に焦点を当ててご説明します。

補足: これら3つの認可の不備はそれぞれ認可のレベルが異なっており、おのおの以下のようなイメージです。

image.png

「認可」の不備の対策

前述した「認可」の不備のリスクを最小限に抑えるために、重要となってくるのが以下の3つの要素です。

  1. 標準仕様への準拠
  2. きめ細かな (fine-grained) アクセス制御
  3. 認可の分離

これらの要素を満たし、”認可のベストプラクティス” と考えることができる認可アーキテクチャを下図に示します。

image.png

このアーキテクチャは前述の3つの要素を、それぞれ以下の技術によって満たしています。

  1. OAuth 2.0への準拠
  2. ABAC (Attribute-Based Access Control)
  3. P*Pアーキテクチャ

本記事ではOAuth 2.0とABACについての詳細な説明は省略しますので、気になる方はリンク先のページなどを参照ください。

P*PアーキテクチャについてもABACのドキュメント内で説明はされていますが、こちらは馴染みのない方も多いかもしれませんので本記事内でも触れておこうと思います。

P*Pアーキテクチャとは認可という大きな責務を、役割の異なる複数のコンポーネント (PxP) に分解する考え方です。
認可の主要な役割は、定められた認可ポリシーに基づいて認可判断を行う「PDP (Policy Decision Point)」と、判断に基づいて各リクエストに対してアクセス制御を試行する「PEP (Policy Enforcement Point)」の2種類に大別できます。(詳細にはPIPやPAPもありますが今回は省略します。)

従来は1つのコンポーネント (各アプリケーション) でこのPDPと PEP両方の役割を担っていましたが、P*Pアーキテクチャでは認可判断に関するPDPの役割を別のコンポーネントとして分離し、各アプリケーションはPEPとして 単純な施行のみに徹することで、アプリケーションと認可という異なる関心を分離することを可能にしています。

加えてこの認可のベストプラクティスでは、アプリケーションの前段のゲートウェイ (Proxy等) で認可を施行することにより、PEPの役割すらもアプリケーションから分離し、アプリケーションと認可の完全な分離を実現しています。

MuleSoftでのAPIセキュリティ

では、この認可のベストプラクティスをMuleSoftの標準機能で実現できるのでしょうか。MuleSoftの各機能を見てみましょう。

MuleSoftが提供するIdP

まずIdPについてですが、MuleSoftはMule OAuth 2.0 ProviderというMuleSoftが開発したIdPを提供しています。しかし、Mule OAuth 2.0 ProviderはOAuth2.0には準拠しているものの、PEPと連携するための機能も、属性ベースでアクセス制御することもできず、認可のベストプラクティスの実現には不十分です。

また、公式にも以下の記載がある通り、エンタープライズレベルでの利用自体も推奨されておらず、別途外部IdPを用意する必要があります。

It is the recommended initial solution pending future corporate investments in enterprise specific OAuth 2.0 offerings.

MuleSoftが提供するAPI認可機能

次にAPI側についてですが、MuleSoftはMule Gateway Policy という、APIのセキュリティ管理やトラフィック制御のような汎用的なAPI統制ロジックを、再利用可能なコンポーネントとしてモジュール化する機能を提供しています。

Mule Gateway Policyは大きくIncluded Mule Gateway PolicyCustom Policyの2種類に分かれており、前者は一般的によく利用される統制ロジックをMuleSoft側で事前に用意してくれているもの、後者はそれだけでは不十分な場合に開発者が独自に実装するものとなっています。

認可は一般的なセキュリティであるため、勿論MuleSoftはIncluded Mule Gateway Policyとして、OAuth 2.0 Token Introspection[RFC 7662]に準拠してアクセストークンを検証するOpenID Connect OAuth 2.0 Token Enforcement や、JWT (JSON Web Token) の署名やClaimを検証するJWT Validationといった標準的な認可のMule Gateway Policyは提供しています。

しかしこれらも、「アクセストークンそのものが有効か」といった粗い粒度(coarse-grained)のアクセス制御が基本です。

そのため、標準提供されるIncluded Mule Gateway Policyでは、P*PアーキテクチャでのABACは実現できません。

Keycloak連携ソリューション

そこで、今回のご紹介するKeycloak連携ソリューションにより、MuleSoftで認可のベストプラクティスを実現します。

Keycloakの利用

まず、IdPおよびPDPとしてKeycloakを利用します。KeycloakはAuthorization Servicesという機能により、IdPとしての役割に加えて、ABACのPDPとしての役割も担うことができます。

KeycloakのAuthorization Servicesは、アクセス制御ポリシーを以下のResource, Scope, Policy, Permissionに基づくアクセス制御モデルに基づいてきめ細かに定義でき、定義したポリシーをGUIで一元管理することができる機能です。

・Resource
保護したい対象。APIエンドポイント (/orders, /users/{userId}/profile)など。
・Scope
Resourceに対して許可される操作。HTTPメソッド (GET, PUT) や、より抽象的な操作 (view, edit, approve) など。
・Policy
アクセスを許可するための条件。「誰が」「何に」「いつ」「どこで」アクセスできるかを定義する。User, Group, Role, Attributeなど多様な属性情報をベースに条件を作成することが可能。
・Permission
どの「Resource」のどの「Scope」に対して、どの「Policy」を適用するかを具体的に紐付けたもの。

Keycloakは、このAuthorization Servicesにより、「平日の業務時間内かつ営業部のユーザ (Policy) であれば、顧客の注文情報 (Resource) への参照と修正 (Scope) を許可する」のような複雑な属性ベースの認可ルール (Permission) を定義し、一元管理することが可能です。

PEPとしてのCustom Policyの実装

PEPには、PDP (Keycloak)と連携して認可を試行するロジックをCustom Policyとして実装した、Mule Gateway Policyを利用します。

今回のCustom Policyの役割は、PEPとして、API (API Instance)とKeycloakのAuthorization Servicesとの間の連携の架け橋となり、認可判定をKeycloakに問い合わせることです。

この連携のために必要な処理フローは以下の通りで、これをCustom Policyとして実装してAPI Instanceに適用します。

処理フロー:

  1. HTTPリクエストから必要な情報(AuthorizationヘッダーのBearerトークン、Resource(アクセス先エンドポイントのPath)、Scope(HTTPメソッド))を抽出する。
  2. 抽出した情報を使って、KeycloakのAuthorization Servicesが提供するエンドポイントに、認可判定のリクエストを送信する。
  3. カスタムポリシーはKeycloakからの応答に応じて、HTTPリクエストを許可、または403エラーレスポンスをクライアントに返却する。

最終的な連携イメージ

下図が、最終的な連携イメージです。

image.png

動作確認

それでは実際に、MuleSoftとKeycloakを連携して、認可のベストプラクティスに沿ったセキュアなAPI公開を試してみましょう。

今回の動作確認は下図のように、GETとPUTに対応したエンドポイントを持つ”Device API”を作成し、GETとPUTの両方の操作を許可された”管理者グループ”とGETのみ許可された”ユーザグループ”のそれぞれに所属する”管理ユーザ”と”エンドユーザ”からDevice APIをコールし、期待するアクセス制御が実現されることを確認します。

image.png

では、MuleSoftとKeycloakをそれぞれ設定していきます。

MuleSoft側の設定

まずはMuleSoft側の設定です。

MuleSoftの各機能は以下のバージョンを使用します。(執筆時点でのlatestバージョン)

  • API Manager: 2.5.10
  • Mule Runtime: 4.9.5

MuleSoft側では以下2点を実施します。

1. APIのデプロイ
保護対象のリソースとして“Device API”をデプロイします。
2. Custom Policyの適用
“API Instance”を作成し、CustomPolicyを適用します。

順に見ていきます。

1. APIのデプロイ

まずは保護対象となるリソース (Device API) をCloudHub2.0にデプロイします。

今回Device APIには、以下のAPI仕様に沿った、GETならDeviceModelの値を返却し、PUTならDeviceModelの値を更新するだけのシンプルな処理のみを実装しています。

openapi: 3.0.0
info:
  title: DeviceAPI
  version: 1.0.0

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    Device:
      type: object
      properties:
        deviceModel:
          type: string
          description: The model of the device.
          example: "iPhone 16 Pro"
      required:
        - deviceModel

security:
  - bearerAuth: []

paths:
  /device:
    get:
      description: Retrieves the current type of the device.
      operationId: getDeviceType
      responses:
        '200':
          description: Successfully retrieved the device type.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
        '401':
          description: Unauthorized. Authorization header is missing or invalid.
    put:
      description: Updates the type of the device based on the provided input.
      operationId: updateDeviceType
      requestBody:
        description: Device type to update.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Device'
      responses:
        '200':
          description: Successfully updated the device type.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
        '400':
          description: Bad Request. Invalid request body.
        '401':
          description: Unauthorized. Authorization header is missing or invalid.

2. Custom Policyの適用

前述の処理フローを実装したCustom PolicyをAnypoint Exchangeにデプロイします。(これによりAnypoint Platform上でCustom policyが利用可能になります。)

その後、API Manager経由で、手順1でデプロイしたMuleアプリケーションに紐づくAPI Instanceを作成してCustom Policyを適用します。

これでMuleSoft側の設定は完了です。

Keycloak側の設定

次にKeycloak側の設定です。
今回はKeycloakのバージョン26.2.4を使います。(執筆時点でのlatestバージョン)

Keycloak側では以下4点を実施します。

1. グループの作成
“管理者グループ”と”ユーザグループ”に対応する2つのグループを作成します。
2. ユーザの作成
“管理ユーザ”と”エンドユーザ”に対応する2人のユーザを作成し、それぞれグループに所属させます。
3. クライアントの作成
“操作端末”と”API Instance”に対応するクライアントを作成します。
4. Authorization Servicesの設定
きめ細かなアクセス制御のための、認可ポリシーの設定を行います。

順に見ていきます。

1. グループの作成

Keycloakを起動し、管理コンソールに任意のユーザでログインします。

任意のRealmを選択し(今回はmulesoftというRealmを使用)、「Groups」>「Create group」からグループを作成します。

今回はGETメソッドとPUTメソッドの両方が可能な”管理者グループ”に対応する"device-admin"グループと、GETメソッドのみが可能な”ユーザグループ”に対応する"device-enduser"グループの2グループを作成します。

image.png

2. ユーザの作成

手順1と同様のRealmで、「Users」>「Create new user」からユーザを作成します。

今回は管理ユーザに対応する"test-administrator"ユーザと、エンドユーザに対応する"test-enduser"ユーザの2ユーザを作成します。

"test-administrator"ユーザと"test-enduser"ユーザは、それぞれ手順1で作成した"device-admin"グループと、"device-enduser"グループに所属させます。

image.png

image.png

3. クライアントの作成

手順1と同様のRealmで、「Clients」> 「Create client」からクライアントを作成します。

今回はユーザの操作端末に対応する"test-client"クライアントと、MuleSoft側の設定で作成したAPI Instanceに対応する”device-api"クライアントの2クライアントを作成します。

作成時の設定画面では以下の通り設定を行います。

  • "test-client"クライアント

    • General settings
      • Client IDに"test-client"を入力し、Nextボタンを押下。
    • Capability config
      • Client authenticationをONへ変更し、Nextボタンを押下。
    • Login settings
      • 何も入力せず、Saveボタンを押下。
  • ”device-api"クライアント

    • General settings
      • Client IDに”device-api"を入力し、Nextボタンを押下。
    • Capability config
      • Client authenticationとAuthorizationをONへ変更し、Nextボタンを押下。
    • Login settings
      • 何も入力せず、Saveボタンを押下。

4. Authorization Servicesの設定

手順3で作成したClientの詳細画面からAuthorizationタブを選択します。ここでScope, Resource, Policy, Permissionをそれぞれ作成します。

  • Scope

「Scopes」>「Create authorization scope」からScopeを作成します。

今回はGETメソッドに対応した"GET"という名前のScopeと、PUTメソッドに対応した"PUT"という名前のScopeを作成します。

image.png

  • Resource

「Resources」>「Create resource」からResourceを作成します。

今回は保護対象のエンドポイントである"/device"という名前を入力し、Authorization scopesに先ほど作成した"GET"と"PUT"を選択して保存します。

image.png

  • Policy

「Policies」>「Create client policy」>「Group」からGroup-Based Policyを作成します。

今回は「device-adminグループのユーザの場合に許可するPolicy」と「device-enduserグループのユーザの場合に許可するPolicy」の2つのPolicyを作成します。

前者は"positive-group-device-admin"という名前を入力し、「Groups」>「Add groups」から"device-admin"グループを追加して保存します。

image.png

後者は"positive-group-device-enduser"を入力し、「Groups」>「Add groups」からdevice-enduserグループを追加して保存します。

image.png

  • Permission

「Permissions」>「Create permission」>「Create scope-based permission」からScope-Based Permissionを作成します。

ここまで作成したScope、Resource、Policyを紐づけて、「/deviceへのGETをdevice-adminグループのユーザ、またはdevice-enduserグループのユーザの場合に許可するPermission」と「/deviceへのPUTをdevice-adminグループのユーザの場合に許可するPermission」の2つのPermissionを作成します。

前者は"deviceapi-get"という名前を入力し、Resourceに"/device"を、Authorization scopesに"GET"を、Policiesに"positive-group-device-admin"と"positive-group-device-enduser"を、Decision strategyに”Affirmative”を選択して保存します。

image.png

後者は"deviceapi-put"という名前を入力し、Resourceに"/device"を、Authorization scopesに"PUT"を、Policiesに"positive-group-device-admin"を選択して保存します。

image.png

これでKeycloak側の設定は完了です。

動作確認

ここまでで全ての設定が完了したので、次は実際に"test-enduser"ユーザと"test-administrator"ユーザのそれぞれでKeycloakからアクセストークンを取得し、APIの/deviceエンドポイントをGETとPUTの両方で呼び出してみます。

下図 (再掲) の通り、GET /deviceは管理ユーザとエンドユーザの両者で成功し、PUT /deviceは管理ユーザのみが成功してエンドユーザが失敗となれば期待通りの動作ができていることになります。

image.png

動作確認はcurlコマンドなどでやってもよいのですが、見栄えのためにトークンを取得して/deviceをGETとPUTそれぞれでコールするだけの以下画像のような簡単なクライアントアプリケーションを作成したので、こちらを利用して操作していきます。

「Get Token」を押下すると認可フローが走り、取得したトークンが「Token =」の部分に表示されます。「Get Device API」と「Put Device API」を押下すると取得したトークンを付与して/deviceへGET/PUTリクエストを送信し、結果が「Result =」の部分に表示されます。

image.png

では、まずはエンドユーザ("test-enduser"ユーザ)で操作してみましょう。

「Get Token」を押下して表示されたログイン画面※ にエンドユーザのアカウント情報を入力してログインします。

※ 今回使用しているログイン画面は一部カスタマイズが施されており、バニラのログイン画面とはレイアウトが異なります。

image.png

image.png

トークンが取得できました。次は「Get Device API」と「Put Device API」をそれぞれ押下してみましょう。

image.png

image.png

期待通りGET操作は成功しましたが、PUT操作は403エラーが返ってきて失敗していますね。

次は管理ユーザ(“test-administrator”ユーザ)で操作してみましょう。
「Get Token」を押下して表示されたログイン画面に管理ユーザのアカウント情報を入力してログインします。

image.png

image.png

トークンが取得できました。次は「Get Device API」と「Put Device API」をそれぞれ押下してみましょう。

image.png

image.png

PUTでdeviceModelをAndroidに置き換えたので、再度「Get Device API」を押下してみます。

image.png

無事Androidの情報が取得でき、こちらも期待通りGET操作、PUT操作ともに成功しましたね。

このようにAPI側ではAPI InstanceにCustom Policyを設定するだけで、特に認可ロジックを意識することなく、ABACによるきめ細かなアクセス制御が実現できます。

今回は検証のためにABACの中でもシンプルなGroup-Basedな簡易ポリシーを定義しましたが、その他の時間やロケーション、任意のカスタム属性などの様々な条件を組合せることでよりきめ細かで動的な認可も簡単に実現することができます。

おわりに

本記事では認可にフォーカスして、MuleSoft × Keycloakで認可のベストプラクティスを実現し、セキュアにAPIを公開する方法を紹介しました。

APIの外部公開は、成熟したAPIビジネスにおいては不可欠な要素であり、その成功の鍵は信頼性と安全性を確保する堅牢なセキュリティにあります。もしこれからAPI公開を本格化させようとしているのであれば、今回ご紹介したKeycloakとMuleSoftの連携はその際の強力な選択肢となりますのでご参考にしていただければ幸いです。

※ MuleSoftは、Salesforce.com, Inc.の商標または登録商標です。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?