API GatewayでSecret Managerを使用する方法
Shirui Zhao
January 13, 2023
Secretとは何か?
IT環境において、Secret(シークレット)とは、システムやアプリケーションが認証や暗号化アルゴリズムの入力として使用する、人間以外の特権的な認証情報のことです。例えば、プログラムがデータベースに接続するために必要なパスワードや、暗号化通信のためのキー/証明書などがSecretに該当します。
一般的なSecretの種類には以下があります:
- 暗号化キー
- クラウドサービスのアクセス認証情報
- アプリケーションプログラミングインターフェース(API)キー
- アクセストークン
- SSH(セキュアシェル)キー
Secret Manager
Secret Managerは、Secretのライフサイクル全体を通じて、その保存、取得、ローテーション、監査を行います。HashiCorp Vaultは、最も一般的に使用されるSecret Managerサービスの1つであり、その動作原理は以下の通りです(画像はHashiCorp公式サイトより):
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の再起動も効果的に回避できます。
以下では、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サービスを統合しました。その動作シーケンスは以下の通りです:
以下では、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のアドレスやその他の接続情報を設定します:
- APISIX SecretリソースのIDは「gateway」です。詳細はこちらを参照してください。
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でキー情報を管理する方法を説明しました。