1
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?

【IBM API Connect】ガバナンス機能触ってみた

Last updated at Posted at 2025-10-14

はじめに

API Connectのガバナンス・サービス機能を触ってみたので、概要と使用方法を備忘録として残しておきます。

公式ドキュメント:
https://www.ibm.com/docs/ja/api-connect/saas?topic=apis-configuring-governance-in-api-manager

ガバナンス機能とは?

IBM API Connectのアドオン機能で、API開発プロセスにおいて組織のガバナンス・ポリシーやベストプラクティスを検証・適用するためのサービスです。

事前に定義されたルールにAPIおよび製品ドキュメントが準拠しているかどうかをチェックすることが可能となります。

主な機能

  • カスタムルールセットの作成
    • Swagger(OpenAPI)、AsyncAPI、製品ドキュメントをチェックするためのルールをまとめたセットを作成
    • 複数のルールセットを定義可能
  • バリデーションスキャン:
    • カタログやスペースに対してスキャンを実行し、ポリシーやルールに準拠しているか確認
    • API単位での検証のほか、カタログ内のAPIや製品を一括でスキャンすることも可能

ガバナンス機能の概要

  • 目的
    • Swagger/OpenAPI/AsyncAPI、さらにProductドキュメントを、ルールセットに基づいて検証(lint)
    • これにより、組織の設計基準・ベストプラクティス・セキュリティ方針に沿っているかをチェック可能
  • 実装の中身
    • OpenAPIのリンティングツールであるSpectral をベースにしており、Spectralのコア関数のみ利用可能(カスタムJS関数は不可)
  • ルールセットの種類
    • Provider org ルールセット(組織カスタム、自分で作成可能)
    • Global ルールセット(IBM/Spectral既定のルールセットで、編集不可)

この機能を使用するメリット

  • 設計のばらつきを自動で検出
    • 命名・メタデータ不足・バージョニングの形式・セキュリティ定義の有無などを機械的に検知
    • レビュー効率の向上
  • 運用の前倒し品質保証
    • 公開前の強制バリデーション(10.0.10.0 Tech Preview)まで持っていくと、品質ゲートとして機能する(後述)
  • 結果の可視化
    • 改善点が明確になり、チームで共通言語化

カスタムルールセットの作成

前提条件

  • 管理サブシステムでガバナンスを有効化(管理者作業)
    • 有効化されていると、API Manager左メニューに盾アイコン(Governance)が表示されます
  • ロール
    • ガバナンスの構成にはOrganization Administrator、Owner、または権限 Settings: Manage を持つカスタムロールが必要

ルールセットの作成方法

ルールセットの作成には以下の3つの方法があります。

  • yamlを書いてインポートする方法
  • GUI上で作成する方法
  • CLIで追加する方法

今回はyamlのインポートとGUI上の作成の2つの方法で、以下の仕様を満たすルールセットを作成してみます。

ルールセットの仕様

  • APIドキュメントをスキャンするルールセット
  • 違反した場合は重大度warnで警告メッセージを表示
  • ルールセットには以下の2つのルールが入っている
    • ルール1: アセンブリーフローにGatewayScriptが含まれていなければ警告
    • ルール2: アセンブリーフローにParseが含まれていなければ警告

API ConnectのガバナンスはSpectralのルールセット記法に準拠します(Given/Then で対象と検査を定義)。

方法1:yamlのインポート

テキストエディタで以下のようなスクリプトを作成します。

Spectralの記法については以下のリンクを参考にしています。

ルールセット作成

コア関数

extends:
  - "spectral:oas"
formats:
  - oas3
rules:
  require-gatewayscript-in-assembly:
    description: "アセンブリーフローに少なくとも1つ 'gatewayscript' ポリシーが含まれていることを求めます。"
    message: "アセンブリに 'gatewayscript' が見つかりません。少なくとも1つ追加してください。"
    severity: warn
    given: $.x-ibm-configuration.assembly.execute
    then:
      - function: schema
        functionOptions:
          schema:
            type: array
            contains:
              type: object
              required: ["gatewayscript"]
  require-parse-in-assembly:
    description: "アセンブリーフローに少なくとも1つ 'parse' ポリシーが含まれていることを求めます。"
    message: "アセンブリに 'parse' が見つかりません。少なくとも1つ追加してください。"
    severity: warn
    given: $.x-ibm-configuration.assembly.execute
    then:
      - function: schema
        functionOptions:
          schema:
            type: array
            contains:
              type: object
              required: ["parse"]
  • Given:JSONPathでどの部分を検査するか
  • Then:どの関数でチェックするか(truthy/pattern/definedなどSpectralコア関数)
  • severity:error / warn / info / hint /off

次に、API Connectにこのyamlをインポートします。画面左のメニューからガバナンスを選択します。

ルール・セットタブから追加をクリックし、インポートを選択します。
image.png

ファイルを選択して次へをクリックします。
image.png

ルールセットのタイトルを設定します。

任意でこのルールセットの説明や、タグを設定することも可能です。
image.png

以上でルールセットが無事に追加されました。
image.png

このルールセットは後ほどスキャンに使用するため、公開を選択します。
image.png

image.png

方法2:最初から作成

GUI上からルールセットを作成することも可能です。

API Connectの画面左のメニューからガバナンスを選択します。

ルール・セットタブから追加をクリックし、最初から作成を選択します。
image.png

ルールセットのタイトルを設定します。

任意でこのルールセットの説明や、タグを設定することも可能です。
image.png

重大度と、ルールセットの内容を記載します。

こちらは上記の方法1で記載したyamlの内容と同一です。
image.png

$.x-ibm-configuration.assembly.execute
- function: schema
  functionOptions:
    schema:
      type: array
      contains:
        type: object
        required: ["gatewayscript"]

左の+ボタンをクリックして、さらにルールを追加します。
image.png

image.png

image.png

こちらも方法1の内容と同一です。

$.x-ibm-configuration.assembly.execute
- function: schema
  functionOptions:
    schema:
      type: array
      contains:
        type: object
        required: ["parse"]

作成したルールセットを保存して、公開を行います。
image.png

スキャン(検証)の実施

次に、上記の手順で作成したルールセットを使用して、スキャンを行います。

今回はスキャン対象のAPIとして、以下のリンクに記載のサンプルAPIを使用します。
https://github.com/ibm-apiconnect/sample-orders-api/blob/main/api/orders_api.yaml

openapi: 3.0.1
info:
  title: Order
  description: View and track your orders and deliveries.
  termsOfService: https://github.com/ibm-apiconnect/sample-orders-api
  contact:
    name: IBM Corporation
    url: https://www.ibm.com/products/api-connect
  version: 2.0.0
  x-ibm-name: ibm-sample-order-api
externalDocs:
  description: "Github project for this API, containing source code and deployment\
    \ pipeline"
  url: https://github.com/ibm-apiconnect/sample-orders-api
servers:
- url: /order
security:
- clientID: []
paths:
  /{orderNumber}:
    get:
      summary: Retrieve the details of your order.
      parameters:
      - name: orderNumber
        in: path
        description: Order number to lookup - you should find this in your confirmation
          e-mail
        required: true
        schema:
          type: string
      responses:
        "200":
          description: Order found successfully
          content:
            application/json:
              schema:
                title: Order Details
                type: object
                properties:
                  order_number:
                    title: Order Number
                    type: string
                    example: ORD00989792
                  tracking_status:
                    title: Tracking Status
                    type: object
                    properties: {}
                  shipped_at:
                    title: Date Shipped
                    type: string
                    format: date-time
                  created_at:
                    title: Date Order Created
                    type: string
                    format: date-time
                  status:
                    title: Order Status
                    type: string
                    enum:
                    - SHIPPED
                    - PICKED
                    - PENDING
                    - DELIVERED
                  tracking_reference:
                    title: Tracking Reference
                    type: string
components:
  securitySchemes:
    clientID:
      type: apiKey
      name: X-IBM-Client-Id
      in: header
x-ibm-configuration:
  properties:
    target-url:
      value: "https://sample-api.us-east-a.apiconnect.automation.ibm.com/orders/order/{orderNumber}"
      description: URL of the proxy policy
      encoded: false
  cors:
    enabled: true
  gateway: datapower-api-gateway
  type: rest
  phase: realized
  enforced: true
  testable: true
  assembly:
    execute:
    - invoke:
        title: order lookup
        version: 2.0.0
        verb: keep
        target-url: $(target-url)
        follow-redirects: false
        timeout: 60
        parameter-control:
          type: blocklist
          values: []
        header-control:
          type: blocklist
          values: []
        inject-proxy-headers: true
        persistent-connection: true
        backend-type: json
        output: order
        description: Retrieves order data from the fulfillment system using the key
          of the provided order number.
    - parse:
        version: 2.1.0
        title: parse response
        parse-settings-reference:
          default: apic-default-parsesettings
        input: order
        output: order
        description: Parse the JSON from the order fulfillment system so that the
          values can be used later in the flow.
    - map:
        version: 2.0.0
        title: map input to lambda
        inputs:
          input:
            schema:
              type: object
              properties:
                delivery_method:
                  type: string
                  name: delivery_method
                tracking_reference:
                  type: string
                  name: tracking_reference
            variable: order.body
        outputs:
          output:
            schema:
              type: object
              properties:
                shipper:
                  type: string
                  name: shipper
                reference:
                  type: string
                  name: reference
            variable: message.body
            content: application/json
        actions:
        - set: output.shipper
          from: input.delivery_method
        - set: output.reference
          from: input.tracking_reference
    - invoke:
        version: 2.2.0
        title: "lambda: track shipment"
        backend-type: detect
        header-control:
          type: blocklist
          values: []
        parameter-control:
          type: allowlist
          values: []
        http-version: HTTP/1.1
        timeout: 60
        verb: POST
        chunked-uploads: true
        persistent-connection: true
        cache-response: protocol
        cache-ttl: 900
        stop-on-error: []
        websocket-upgrade: false
        target-url: https://plgej7e2skungmxzjakprvhe340qkrkl.lambda-url.us-east-1.on.aws/
        output: tracking
        graphql-send-type: detect
        description: Call lambda function to look up the tracking for a  parcel with
          the associated shipping company.
    - map:
        version: 2.0.0
        title: combine data for response
        inputs:
          tracking:
            schema:
              type: object
              properties:
                trackResponse:
                  type: object
                  name: trackResponse
                  properties:
                    shipment:
                      type: object
                      name: shipment
                      properties:
                        package:
                          type: object
                          name: package
                          properties:
                            activity:
                              type: array
                              name: activity
                              items:
                                type: object
                                properties:
                                  status:
                                    type: object
                                    name: status
            variable: tracking.body
          order:
            schema:
              type: object
              properties:
                order_number:
                  type: string
                  name: order_number
                created_at:
                  type: string
                  name: created_at
                shipped_at:
                  type: string
                  name: shipped_at
                status:
                  type: string
                  name: status
                tracking_reference:
                  type: string
                  name: tracking_reference
            variable: order.body
        outputs:
          output:
            schema:
              type: object
              properties:
                order_number:
                  type: string
                  name: order_number
                status:
                  type: string
                  name: status
                shipped_at:
                  type: string
                  name: shipped_at
                tracking_reference:
                  type: string
                  name: tracking_reference
                tracking_status:
                  type: object
                  name: tracking_status
                created_at:
                  type: string
                  name: created_at
            variable: message.body
        actions:
        - set: output.order_number
          from: order.order_number
        - set: output.tracking_status
          from: tracking.trackResponse.shipment.package.activity.status
        - set: output.shipped_at
          from: order.shipped_at
        - set: output.tracking_reference
          from: order.tracking_reference
        - set: output.status
          from: order.status
        - set: output.created_at
          from: order.created_at
    finally: []
  activity-log:
    enabled: true
    success-content: activity
    error-content: payload
x-original-swagger-version: "2.0"

このAPIのアセンブリーフローは以下のようになっています。

image.png

このアセンブリーフローにはparseが使用されていますが、gatewayscriptは使用されていません。
そのため、上記手順で公開したルールセットに含まれている以下の2つのルールのうち、ルール1のみが発火すれば想定通りの挙動となります。

  • ルール1: アセンブリーフローにGatewayScriptが含まれていなければ警告
  • ルール2: アセンブリーフローにParseが含まれていなければ警告

スキャンの実行はガバナンスのメニューから行うことも可能ですが、今回は左メニューの開発でAPIを開発した際にスキャンを実施するユースケースを想定します。

まずはスキャンを行いたいAPIを選択します。
image.png

画面右上の妥当性検査をクリックし、ルール・セットを...(ルール・セットを使用して API を検証)を選択します。

image.png

ルールセットとして、先ほど追加したsample-rulesetを選択します。

APIルールセットにタグを付け、API側のtagsと一致させておくと、スキャン時に該当ルールセットが自動選択され時短になります。
特に、スキャンを行いたいルールセットが複数ある場合に便利です。

image.png

ルールセット内のルールが選択されているので、そのままValidateを選択します。
image.png

Validateを実行するとスキャンの結果が表示されます。

想定通り、gatewayscriptが存在しないことによる警告が表示されています。
image.png

Locationには、違反が検出されたパスが表示されています。ここから、どの箇所を修正すればよいかを確認可能です。
(今回の場合はフロー全体の中でGatewayScriptがないというエラーのためLocationの表示にはあまり意味がなさそうに見えますが、例えばフロー内のどこかのgatewayscriptの記述内容に違反がある、等のエラーの際に、Locationの表示から違反箇所が何番目のポリシーかをすぐに特定することができます。)

また、上記画面のダウンロードボタンをクリックすることで、エクスポートされたcsvファイルをダウンロードすることも可能です。
image.png

今回は1つのAPIに対してスキャンを実行しましたが、カタログ内のAPIに対して一括でスキャンを行うことも可能です。

Governance enforcement

バージョン10.0.10.0 では「Governance enforcement (Technology Preview)」として、カタログ公開前にAPI/Productを強制バリデーションする機能が追加されています。 

Enforcementを有効化している場合、ルールセットでerrorが検出された際にプロダクト公開可否の判定を設定可能です。​
(例:設定がStrictの場合は、エラーがある限り公開不可など)

さらに詳しい情報をお探しの方へ

IBMの最新情報、イベント情報、さらに役立つ資料は、以下のIBM Communityでも発信・格納されています。

最新のトレンドや有益な情報をチェックするために、ぜひご覧ください!

  • WebSphere: IBM Community - WebSphere

    WebSphere関連の最新情報やディスカッション、イベント情報、技術資料を公開中!

  • ELM (Engineering Lifecycle Management): IBM Community - ELM

    ELMに関する最新のイベント情報、ナレッジ共有、便利なドキュメントをチェック!

  • Integration: IBM Community - Integration

    Integrationに関する最新のイベント情報、ナレッジ共有、便利なドキュメントをチェック!

1
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
1
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?