API GatewayでSecret Managerを使用する方法

Shirui Zhao

January 13, 2023

Technology

Secretとは何か?

IT環境において、Secret(シークレット)とは、システムやアプリケーションが認証や暗号化アルゴリズムの入力として使用する、人間以外の特権的な認証情報のことです。例えば、プログラムがデータベースに接続するために必要なパスワードや、暗号化通信のためのキー/証明書などがSecretに該当します。

一般的なSecretの種類には以下があります:

  • 暗号化キー
  • クラウドサービスのアクセス認証情報
  • アプリケーションプログラミングインターフェース(API)キー
  • アクセストークン
  • SSH(セキュアシェル)キー

Secret Manager

Secret Managerは、Secretのライフサイクル全体を通じて、その保存、取得、ローテーション、監査を行います。HashiCorp Vaultは、最も一般的に使用されるSecret Managerサービスの1つであり、その動作原理は以下の通りです(画像はHashiCorp公式サイトより):

Secret Manager

HashiCorp Vault以外にも、AWS、Google、AzureなどのクラウドプロバイダーがSecret Managerサービスを提供しています。

Secret Managerを使用してアプリケーションを構築することで、セキュリティが強化されるだけでなく、以下の機能も提供されます

  • アプリケーションに影響を与えることなく、複数のマシンで簡単にSecretを更新できる。
  • 開発者はSecretの保存に過度に注意を払う必要がなく、ビジネスロジック自体に集中できる。
  • Secretのローテーションや失効を、アプリケーションの再デプロイや中断なしに行える。
  • Secret Managerは柔軟で詳細な監査ログを提供し、すべてのユーザーアクセスの履歴を追跡できるため、監査やコンプライアンス要件を容易に満たすことができる。

API GatewayでのSecret Managerの使用

ビジネストラフィックの入り口であるAPI Gatewayには、認証用のAPIキーやトークンなど、大量のSecret情報が含まれることが多いため、API GatewayにSecret Managerを統合することが非常に重要です

API GatewayでのSecretの使用シナリオ

Key Authは、API Gatewayにおけるシンプルな認証方法です。ユーザーは事前にキーを設定し、クライアントがAPIリクエストを行う際に、設定されたキーを対応するリクエストヘッダーに書き込むか、リクエストパラメータとしてアクセスして認証を通過します。しかし、キーの漏洩はよくあることで、キーは設定ファイルに保存されたり、コード内の変数として保存されたりすることがあります。キーが適切に保存されていない場合、GitHubなどの公開コードリポジトリにキーが表示されることもあり、セキュリティ上の大きな脅威となります。管理者は、キーの漏洩による深刻な被害を防ぐため、定期的にこれらのキーを更新することがよくあります。しかし、一部の静的キーについては、各マシンで個別に設定ファイルを更新することも、サービスの安定性に大きな脅威を与える可能性があります。

API GatewayへのSecret Managerの統合

Secret ManagerをAPI Gatewayに統合することで、Key Auth認証用の事前設定キーをSecret Managerサービスに保存し、キーの漏洩による一連の問題を効果的に解決できます。 API Gatewayは単なるキーの利用者であり、キーの実際の値は外部のSecret Managerサービスに保存されます。さらに、API Gatewayはキーへの参照のみを保持するため、API Gatewayがハッキングされたとしても、コードや設定ファイルから実際のキーを取得することはできません。また、キーの値を更新する必要がある場合、API Gatewayのコードや設定を変更することなく、Secret Manager内で更新するだけで済むため、API Gatewayの再起動も効果的に回避できます。

api gateway Secret Manager

以下では、Apache APISIXを例に、API GatewayでKey Authの事前設定キーをSecret Managerに保存する方法を示します。

Apache APISIXを使用したSecret Managerの実践例

Apache APISIXは、動的でリアルタイム、高性能なAPI Gatewayであり、ロードバランシング、動的なアップストリーム、カナリアリリース、細かいルーティング、レートリミット、サービスデグレード、サーキットブレーカー、認証、可観測性など、数百の機能を提供します。

バージョン3.1.0では、Apache APISIXはAPISIX Secretを導入し、さまざまなSecret Managerサービスを統合しました。その動作シーケンスは以下の通りです:

apisix Secret Manager

以下では、VaultをSecret Managerサービスとして使用します。Key Auth認証を使用して、Apache APISIXでキーを保存する方法を説明します。

Vaultでのキーの作成

キーを作成する前に、Vaultサービスを起動する必要があります。このセクションでは、Apache APISIXエコシステムでVaultを使用するためのベストプラクティスを共有するため、Vault自体の設定については詳しく説明しません。詳細はこちらを参照してください。

Vaultで対応するキーを作成するには、以下のコマンドを使用できます:

vault secrets enable -version=1 -path=apisix kv

vault kv put apisix/jack auth-key=secret-key

上記のコマンドを実行すると、apisix/jackパスの下にauth-keyという名前のキーが作成され、その値はsecret-keyとなります。

APISIXでの設定

まず、Admin APIを使用してSecretリソースを追加し、Vaultのアドレスやその他の接続情報を設定します:

  1. APISIX SecretリソースのIDは「gateway」です。詳細はこちらを参照してください。
  2. prefixフィールドはVault内のキーのパスで、tokenフィールドはVaultのトークンです。
curl http://127.0.0.1:9180/apisix/admin/secrets/vault/gateway \
-H 'X-API-KEY: Your-API-KEY' -X PUT -d '
{
  "uri": "https://127.0.0.1:8200",
  "prefix": "apisix",
  "token": "hvs.chjDFWvZRcihoq2vpSsVenmR"
}'

次に、key-authプラグインを使用してコンシューマーを作成し、対応するルートまたはサービスに対してKey Auth認証を実行します。キーフィールドはAPISIX Secretリソースを参照します:

curl http://127.0.0.1:9180/apisix/admin/consumers \
-H 'X-API-KEY: Your-API-KEY' -X PUT -d '
{
  "username": "jack",
  "plugins": {
    "key-auth": {
      "key": "$secret://vault/gateway/jack/auth-key"
    }
  }
}'

上記の2つのステップを経て、ユーザーのリクエストがkey-authプラグインにヒットすると、Secretコンポーネントはユーザーが設定したSecret Managerを提供されたインターフェースを通じて呼び出し、Vault内のキーの実際の値を取得します。キーの値が見つからない場合、プラグインはエラーを記録し、Key Auth検証を失敗させます。

次に、Key Auth認証を実行するためのルートを作成します:

curl -i "http://127.0.0.1:9180/apisix/admin/routes" -H 'X-API-KEY: Your-API-KEY' -X PUT -d '
{
  "id": "getting-started-ip",
  "uri": "/ip",
  "plugins": {
    "key-auth": {}
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "httpbin.org:80": 1
    }
  }
}'

最後に、キーなしでAPI Gatewayにリクエストを送信し、結果を確認します:

curl -i "http://127.0.0.1:9080/ip"

結果は以下のようになります:

HTTP/1.1 401 Unauthorized
...

{"message":"Missing API key found in request"}

次に、キー付きでAPI Gatewayにリクエストを送信し、結果を確認します:

curl -i "http://127.0.0.1:9080/ip" -H 'apikey: secret-key'

結果は以下のようになります:

HTTP/1.1 200 OK
...

{
  "origin": "127.0.0.1, 59.172.90.243"
}

さらに、Apache APISIXは環境変数をシンプルなSecret Managerサービスに拡張しており、Vaultに接続するためのAPISIXトークンも環境変数に保存できます。そのため、APISIXを起動する前に、以下のコマンドで環境変数を設定できます:

export VAULT_TOKEN="root"

Secretリソースを追加する際に環境変数を参照します:

curl http://127.0.0.1:9180/apisix/admin/secrets/vault/1
-H 'X-API-KEY: Your-API-KEY' -X PUT -d '
{
  "uri": "https://127.0.0.1:8200",
  "prefix": "apisix",
  "token": "$ENV://VAULT_TOKEN"
}'

上記の手順を経ることで、Key Auth認証に必要なキーをVaultに保存し、プラグインの設定時に平文で表示する必要がなくなります。

結論

API Gatewayには大量のSecret情報が存在します。Secret Managerを使用してSecretを管理することで、API Gateway内に平文のSecret情報が存在しないことを保証し、API Gatewayのセキュリティと安定性を効果的に向上させることができます。 世界で最も活発なオープンソースAPI GatewayであるApache APISIXも、Secret Managerを強力にサポートしています。 この記事では、Key Auth認証を使用して、APISIXでキー情報を管理する方法を説明しました。

API Gatewayに関する詳細情報は、ブログをご覧いただくか、お問い合わせください。

Tags: