Konnect Config Storeを使ってみる

Konnectに[Konnect Config Store](https://docs.konghq.com/konnect/gateway-manager/configuration/config-store/)という機能が追加された。
今まで機密情報を格納するためにHashicorpのVaultやAWSのSecret Managerなどと連携して、そこにあるデータを取ってくるような仕組みが用意されていた。
ただ、この機密情報の格納庫はKong側には用意されていなかったので、利用者は別で用意する必要があった。
（環境変数で渡す方法もあるが、機密情報を更新すると再起動が必要だったり使い勝手が悪かった）
今回、この格納庫をKonnect側で用意したものがKonnect Config Storeとなる。

これを試しに使ってみたところ、少しハマりポイントがあったので備忘録がてら使い方を残しておく。

## 検証内容
ここでは[AI Proxy Plugin](https://docs.konghq.com/hub/kong-inc/ai-proxy/)の中にある、OpenAIにアクセスするためのトークンをKonnect Config Storeに格納して、機密情報（OpenAIのアクセストークン）をdeckのYAMLに書かずにPluginを有効化することを確かめる。

検証に使ったYAMLは以下となる。
```yaml:openai.yaml
_format_version: "3.0"
_konnect:
  control_plane_name: default
services:
- host: localhost
  name: openai-api
  port: 8000
  routes:
  - methods:
    - POST
    name: openai-api_openai-chat
    paths:
    - ~/openai-chat$
    plugins:
    - config:
        auth:
          header_name: Authorization
          header_value: '{vault://openai/KONG_OPENAI_AUTH_HEADER}'
        model:
          name: gpt-4
          options:
            max_tokens: 512
            temperature: 1
          provider: openai
        route_type: llm/v1/chat
      name: ai-proxy
      tags:
      - ai-proxy
    tags:
    - ai-proxy
  tags:
  - ai-proxy
```

Konnect Config Storeの指定方法については後ほど解説する。

## Konnect Config Storeの作成
Konnect Config StoreはUIからでもAPIからでも設定できるが、ここではUIでの設定方法を説明する。
Konnectでの機密情報を管理する機能は各ControlPlaneの`Vaults`から設定できる。
新規作成はControlPlaneを開いて左サイドバーの`Vaults`から`+ New Vaults`をクリックする。
すると以下のような作成画面に遷移する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/e564ac18-8268-d1b8-5cbe-a3fddbd5d0de.png)

`Vault Configuration`のところでAWSのSecret ManagerだったりHashicorpのVaultだったりが選択できるが、ここで今回`Konnect`が選べるようになってるのでこれを選択する。
また`General Information`の`Prefix`が名前的なものになるので、今回はOpenAIのトークンを格納するため`openai`と入れてSaveする。

次に作成した`openai`をクリックすると、格納する機密情報のKeyとValueを管理する画面になる。
ここで`+ Store New Secret`で新規にKeyとValueが追加できるのでクリックする。
すると以下のようなKeyとValueを入力する画面になる。ここではAI Proxy Pluginで使うOpenAIへの認証ヘッダの内容を入れたいので、以下のような感じで設定してSaveする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/d914d64d-7c70-b24e-e69e-0b54e828e9a9.png)

- Key: `KONG_OPENAI_AUTH_HEADER`
- Value: `Bearer <OpenAIの認証トークン>`

Konnect Config Storeの特徴として、Valueは一度格納すると見ることは出来ない。
もし誤ったものを入れても確認は出来ないのでその点は注意。

保存後、UIからKeyが確認できる。
またdeckだと以下のような感じで確認できる。
```yaml
vaults:
- config:
    config_store_id: b71217d7-327c-448a-9168-e2b0923945cf
  name: konnect
  prefix: openai
```
以上で機密情報の格納手順は終了となる

## Konnect Config Storeの利用
冒頭で紹介したdeckのYAML(openai.yaml)をGatewayに適用する。
なお、deckをKonnectに利用するにあたり、以下のファイルを作成している。
```yaml:~/.deck.yaml
konnect-addr: https://us.api.konghq.com
konnect-token: kpat_ER1WQ0rnxxxx
konnect-control-plane-name: default
```
`konnect-token`を各自のトークンに書き換えてもらえば、リージョンが同じならここで示す手順が同じように利用できると思う。

Konnect Config Storeの利用方法だが、先ほど紹介したYAMLの以下の部分が呼び出し箇所となる。
```yaml
header_value: '{vault://openai/KONG_OPENAI_AUTH_HEADER}'
```
ここで大きな注意点なのだが、通常Vaultの呼び出しは文法的に以下のようになる。
```yaml
vault://<Vaultの種類(例：env)>/VaultのPrefix/Secret名
```
ただ、Konnect Config Storeの場合は以下のようになる。
```yaml
vault://VaultのPrefix/Secret名
```
（公式ドキュメントでは11/9時点では`vault://konnect/...`となっているが、これは誤りで`konnect`は予約語となっていて作成できない。）
そのため、`openai`という箱の下に`KONG_OPENAI_AUTH_HEADER`というSecretのKeyを作成したので`vault://openai/KONG_OPENAI_AUTH_HEADER`というパスで呼び出すのが正しいことになる。
仕様としてちょっと微妙なので、将来的に変わるかもしれない。
このYAMLを適用するには以下のコマンドで適用できる。
```sh
deck gateway sync --select-tag ai-proxy ./ai-proxy.yaml
```
タグを指定することでControlPlane内の既存の設定を残したままYAMLの内容をKonnectに反映する。
反映するとService、Route、Pluginが作成され、Pluginでは以下のように指定した値が確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/7a4ad053-8b24-9293-1839-c3bac8dbed2d.png)

実際に動作確認する。環境変数`PROXY`にDataPlaneのURLを設定し、以下のようにOpenAIに問い合わせをする。
```sh
curl -k --compressed -X POST ${PROXY}/openai-chat   -H "Content-Type: application/json" -d '{
    "messages": [{
    "role": "user",
    "content": "あなたの名前を教えてもらっていいですか?"
  }] }' | jq .
```
すると以下のような結果が返ってきた。
```yaml
"content": "私の名前はOpenAIです。人工知能アシスタントとして、あなたの質問に答えたり、情報を提供したりすることが私の仕事です。",
```
正常なレスポンスが受け取れており、問題なくトークンがKonnect Config Storeから引っ張ってこれているようだ。

これまではSecret管理は別のサービスを用意する必要があって少し面倒だったが、今後はKonnectだけで完結できそうなので楽が出来そうだ。