Konnectに以前からAPI packagesという機能が公開されているが、まだあまり知られていないように感じる。ここでは機能の概要と、どんな使い方ができるかを整理して紹介する。
API packagesとは
KongのAPI packagesは、Dev Portalで公開するAPIを“パッケージ”としてまとめ、特定の操作セットやアクセス制御、レート制限を付与できる仕組みである。
APIパッケージは、OpenAPI Specに基づく「操作(operation)」の集合として構成される。操作はホスト名、パス、HTTPメソッドの組み合わせによって定義され、API上のoperationとGateway Routeの対応付けに使われる。
主なメリット:
- 複数のAPIやGateway Serviceから任意の操作を組み合わせて、パートナー向けや用途別の公開APIを作れる
- API package単位のレート制限だけでなく、個別operation単位の制限も設定できる
- Dev Portal経由の公開とアクセス制御をACE(Access Control Enforcement)プラグインで一元管理できる
- GatewayのRouteやServiceを直接書き換えずに、API公開ポリシーを柔軟に変更できる
これを活用すると、特定のパートナー向けのAPIセットを作成したり、社内向けと外部向けで異なるAPI公開ポリシーを適用したりすることができる。
例えば以下は、2つのGateway Service(BillingとFlights)から、異なるAPI packageを作成して公開する例である。
この例だと、Partners API packageはFlights Gateway ServiceのPOST/GET /flightsのみを公開しているのに対し、Org API packageはBillingとFlights両方の全操作を公開している。これにより、パートナーにはフライト関連のAPIだけを提供し、社内向けには請求関連も含めた全APIを提供することができる。
KAAとACE
従来のAPIsだと特定のServiceにAPIを紐づけることができ、その際にKAA(Konnect Application Auth)プラグインが自動適用されていた。これはDev Portalで設定した認証を実現するためのプラグインである。
一方で、API package利用時はACE(Access Control Enforcement)プラグインがControl Planeに対して自動で適用される。
ACEプラグインは、Dev Portalで公開されたAPI/API packageに対する開発者アクセス制御を行うための仕組みであり、他の認証プラグイン(例:Key Auth)が認証したアプリケーションに対し、公開されたoperationへのアクセス可否やAPI package/operation単位のレート制限を適用する。ACE自体は認証プラグインの後に実行され、認証に失敗した場合はACEが実行されない点に注意が必要である。ACEにはrequiredとif_presentというmatch_policyがあり、requiredでは定義済みoperationに一致しないリクエストを拒否し、if_presentではoperationに一致した場合のみACEが関与する。(詳細は後述)
主な違い:
- ACEはAPI packageの操作とRouteをマッピングし、公開APIごとのアクセス制御とレート制限を管理する
- KAAはKonnectのアプリケーション認証を担当し、個別API packageの操作単位の制御までは実現しない
- ACEは他の認証プラグインの後に動作し、認証済みのアプリケーションに対するアクセス可否を判断する
- API packagesではACEを利用して、Dev Portalで公開するAPIに対してより細かい制御を行う
APIsとAPI packagesの違い
API packagesは、既存のAPI定義から公開操作を拾い出し、パッケージ単位で公開制御、アプリケーション登録、レート制限を管理するためのレイヤーである。通常のAPIはAPIエンティティ自体の定義と公開を意味するのに対し、API packageはそのAPIに含まれる一部の操作を切り出して別の公開対象として扱う。
| 比較項目 | APIs | API packages |
|---|---|---|
| 公開単位 | APIエンティティ全体 | APIエンティティの中の操作セット(operation) |
| アクセス管理 | API全体への公開/非公開 | パッケージ単位でのアクセス権・アプリ認可管理 |
| レート制限 | API全体またはGateway側で管理 | API package単位/operation単位での制御が可能 |
| Dev Portal公開 | APIとして公開 | API packageとして公開し、特定のパートナーや用途向けに絞り込める |
| コンテンツの再利用 | API単位で管理 | 同じAPIの操作を複数パッケージで再利用可能 |
API packagesは、たとえば同じBackend Serviceを使う複数の利用者向けに、公開操作やレート制限を分けたい場合に有効である。API自体は同じでも、提供するエンドポイント集合や利用条件をAPI packageごとに変えられる点が特徴である。
API packagesの利用
実際に試してみる。
ここでは先ほど示した以下のパターンを作成する。
シナリオとしては、2つのAPI Packageを作成し、片方(パートナー向け)はFlights Gateway Serviceの操作のみを公開、もう片方(社内向け)はBillingとFlights両方の操作を公開するというものである。
前提
以下を前提とする。
- CPは用意済みでDPと接続されていること
- Konnectにアクセスするためのトークンは発行済
- Dev Portalは利用可能で既に1つ作成済み
- DPのバージョンは3.14を利用(機能として3.13以降が前提)
- deckはKonnectと接続可能な設定となっている
手順
APIとRouteの作成
Service, Routeを作成する。
cat > api-packages-gateway.yaml <<'EOF'
_format_version: "3.0"
services:
- name: billing-service
url: http://httpbin.konghq.com/anything
routes:
- name: billing-route
paths:
- /billing
methods:
- GET
- POST
strip_path: true
protocols:
- http
- https
- name: flights-service
url: http://httpbin.konghq.com/anything
routes:
- name: flights-route
paths:
- /flights
methods:
- GET
- POST
strip_path: true
protocols:
- http
- https
EOF
deck gateway apply api-packages-gateway.yaml
動作確認する。
curl -i -X POST http://localhost:8000/billing \
-H 'Content-Type: application/json' \
-d '{"type":"billing"}'
curl -i -X POST http://localhost:8000/flights \
-H 'Content-Type: application/json' \
-d '{"type":"flights"}'
現時点ではプラグインなどは適用されていないので普通に通信が通ることを確認する。
APIとOpenAPI specの紐付け
次にOpenAPI Spec(OAS)を作成する。
追記:以下のサンプルはあまり良くない。実際はbillingとflightsでOASを分けて、APIsで別々に登録した方がそれっぽくなる
cat > billing-flights-api.yaml <<'EOF'
openapi: 3.0.0
info:
title: Billing and Flights API
description: API package demo for Billing and Flights operations
version: 1.0.0
servers:
- url: http://localhost:8000
description: Local Kong proxy
paths:
/billing:
get:
summary: Get billing information
operationId: getBilling
tags:
- Billing
responses:
'200':
description: Successful response
post:
summary: Create billing information
operationId: postBilling
tags:
- Billing
requestBody:
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'200':
description: Successful response
/flights:
get:
summary: Get flights
operationId: getFlights
tags:
- Flights
responses:
'200':
description: Successful response
post:
summary: Create flight
operationId: postFlights
tags:
- Flights
requestBody:
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'200':
description: Successful response
EOF
ポイントとしてはOAS内のパスがRouteのパスと一致するようにすることである。ここでは/billingと/flightsがそれぞれのRouteのパスと一致している。
作成したOASはAPIとしてKonnectに登録する。
登録したOASでは以下の4つの操作を含んでおり、これらがAPI packageのoperationとして利用可能になる。
- GET /billing
- POST /billing
- GET /flights
- POST /flights
次に作成したAPIをControl Planeとリンクする。
- Catalogで作成した
Billing Flights APIを開く - Gateway タブから
Link gatewayをクリック - Control Planeとして用意したCPを選択
-
Select gateway link typeでLink to a control planeを選択 -
Add the Access Control and Enforcement pluginのところにあるAdd pluginをクリック -
Link gatewayをクリックして完了
これによって当該CPに対してKonnect Access Control Enforcement(ACE) PluginがGlobalスコープで適用される。
適用後に先程アクセスしたパスに再度アクセスしてみる。
curl -i -X POST http://localhost:8000/billing \
-H 'Content-Type: application/json' \
-d '{"type":"billing"}'
401が返るようになる。
HTTP/1.1 401 Unauthorized
Date: Wed, 13 May 2026 00:46:32 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 81
X-Kong-Response-Latency: 3
Server: kong/3.14.0.1-enterprise-edition
X-Kong-Request-Id: ca4714037590da27c29f40281b88040b
{
"message":"Unauthorized",
"request_id":"ca4714037590da27c29f40281b88040b"
}
なお、ACE Pluginは2つのモードがあり、デフォルトではif_presentで動作する。
| match_policy | 挙動 |
|---|---|
required |
Dev Portal上のAPI/API package operationに一致しないリクエストを404で拒否 |
if_present |
operationに一致した場合のみACEが関与し、一致しない場合は通す |
if_presentであればOASで定義した操作のみにACEが関与し、それ以外のリクエストはこれまで通り認証なしで通ることになる。requiredにすると、OASで定義した操作以外へのリクエストもすべて404で拒否されるようになる。
以下はrequiredにした場合の例である。OASで定義していないパスへのリクエストが404になることがわかる。
$ curl -i http://localhost:8000/test
HTTP/1.1 404 Not Found
Date: Wed, 13 May 2026 00:54:15 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 104
X-Kong-Response-Latency: 4
Server: kong/3.14.0.1-enterprise-edition
X-Kong-Request-Id: 4316ac723ee179032fe2f85a56ee5a3b
{
"message":"This API operation is not available",
"request_id":"4316ac723ee179032fe2f85a56ee5a3b"
}
requiredはAPIsで管理していないRouteにも影響するため、利用する際は慎重に検討した方がよい。
API packageの作成と公開
ここではパートナー向けと社内向けの2つのAPI Packageを作成する。
まずパートナー向けのAPI Packageを以下の手順で作成する。
- 左サイドバーのCatalogからAPIsを選択し、
API packagesタブを開く -
Create API packageをクリック - API package nameに
Partners API packageと入力 - Package rate limitを有効化し、値を設定する(ここでは5 requests / minuteにする)
-
Add operations from APIsをクリックし、Billing Flights API を選択後に以下をAddする
GET /flights
POST /flights -
Create API packageをクリックして完了
なお、ここのRate LimitはAPI package全体に対する制限である。各操作個別に対してもレート制限を設定することができ、その場合はパッケージレベルの制限は無視される。
次に社内向けのAPI Packageを作成する。手順は先程のパートナー向けと同じで、違う点は以下とする。
- API package nameは
Org API packageとする - Package rate limitは無効化する
-
Add operations from APIsではAdd allをクリックして全て追加する
作成が完了したらDev Portalに公開する。
最初にパートナー向けのAPI packageを公開する。
- 左サイドバーのCatalogからAPIsを選択し、
API packagesタブを開く - 作成した
Partners API packageをクリック - 右上の
Publish APIをクリック - 公開先の対象ポータルを選択
-
Authentication strategyはapikeyを選択 -
API visibilityはPrivateにし、Auto Approvalは有効化してPublish APIをクリックして完了
パートナー向けーのAPI packageの公開が完了したら、同じで順で社内向けのAPI packageも公開する。
なお、元APIのOASがAPI packageのDev Portal表示用ドキュメントとして自動的に継承されず、API PackageはAPI Packageで別にOASを登録する必要がある。
これは恐らく元のOASを見せてしまうと、API Packageに含まれない操作も含まれてしまうためだと考えられる。
なので、上記手順でAPI Packageを公開してDev Portal上でView APIsをクリックしてもは以下のように表示される。

公開後の動作確認
各API Packageを公開したら、Dev Portal上でアプリケーションを作成してAPIを呼び出してみる。
今回便宜上Auto Approvalを有効化しているが、実際の運用では申請されたアプリケーションを管理者が承認するフローとなり、パートナーはPartner API Packageのみ利用でき、社内向けはOrg API Packageのみ利用できるようにすると捉えるとよい。
最初にパートナー向けにAPIキーを発行する。
Portal上で公開されたAPI Packageの下にあるView APIsを選択し、右上のUse this APIをクリックする。
Application nameにPartner Appと入力し、Create and use APIをクリックする。
するとAPIキーが表示されるので、これをコピーしておく。

同じ手順でOrg API Packageに対してもAPIキーを発行する。Application nameはOrg Appとする。
APIキーが発行できたら、実際にAPIを呼び出してみる。
APIキーを環境変数に設定する。
PARTNER_API_KEY='PARTNER_API_KEY_VALUE'
ORG_API_KEY='ORG_API_KEY_VALUE'
まずパートナー向けのAPIキーを使って、Flights APIにアクセスしてみる。
curl -i http://localhost:8000/flights -H "apikey: $PARTNER_API_KEY"
結果としては200が返ってくるが、レスポンスヘッダを見ると流量制限が掛かっていることが分かる。
RateLimit-Remaining: 4
RateLimit-Limit: 5
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 4
RateLimit-Reset: 31
6回アクセスしてみる。
for((i=0;i<6;i++)); do curl -i http://localhost:8000/flights -H "apikey: $PARTNER_API_KEY" ; done
すると6回目で429が返ってきてレート制限に引っかかっていることがわかる。
{"message":"API rate limit exceeded"}
次にBilling APIにアクセスしてみる。
curl -i http://localhost:8000/billing -H "apikey: $PARTNER_API_KEY"
こちらについては権限がないのでそもそもアクセスできないことがわかる。
HTTP/1.1 403 Forbidden
Date: Wed, 13 May 2026 01:56:30 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 93
X-Kong-Response-Latency: 17
Server: kong/3.14.0.1-enterprise-edition
X-Kong-Request-Id: 7a0b2d337aabeb24d740f9165fbe1a26
{
"message":"Operation not authorized",
"request_id":"7a0b2d337aabeb24d740f9165fbe1a26"
}
同様に社内向けのAPIキーを使ってBilling APIとFlights APIの両方にアクセスしてみる。
curl -i http://localhost:8000/billing -H "apikey: $ORG_API_KEY"
curl -i http://localhost:8000/flights -H "apikey: $ORG_API_KEY"
こちらに関しては両方ともアクセスでき、流量制限も掛かっていないことが確認できる。
まとめ
API packagesを使うと、同じGateway ServiceやRoute設定を利用者ごとに権限を分けて公開したり流量制限を掛けられることが確認できた。
今回の検証では、Partners API packageではFlightsのみを公開し、Org API packageではBillingとFlightsの両方を公開した。Partner AppのAPIキーではFlightsにはアクセスできるがBillingには403となり、Org AppのAPIキーでは両方にアクセスできた。また、Partners API packageにはpackage-level rate limitを設定し、429が返ることも確認できた。
注意点としてはAPIに登録したOASはAPI packageのDev Portal表示用specとして自動継承されないため、package単位でOASを生成・登録する必要がある点には注意が必要である。
備考:OperationレベルのRate Limiting
今回扱わなかったが、OperationレベルでRate Limitingを設定する場合、API Packages内のOperationsの以下から設定できる。

API PackagesのEditからだと設定できないので注意。

