Azure Key Vault は、アプリケーションが利用するシークレットを安全に保管してくれるサービスです。シークレットには、DBの接続文字列、API のアクセスキー、証明書などの情報があります。
アプリケーションで Azure Key Vault から接続文字列を取得するには、Azure Active Directory のサービスプリンシパルが必要となり、ソースコードに決め打ちしない構成やサービスプリンシパルの有効期間の管理など、少し手間がかかります。
Managed Service Identity(MSI)を使うことで、このあたりの煩わしさを解消できるようになっていたので、まとめておきます。
Azure Key Vault を作成する
Azure Portal を開いて、Azure Key Vault を作成します。特に説明は必要ないと思います。
続いて、シークレットを作成します。今回は、SQL の接続文字列を想定したシークレット(SqlConnection)を追加しました。
Azure Key Vault 側の準備は、これで完了です。
ローカル開発環境で接続文字列を取得する
Managed Service Identity(MSI)を利用すると、認証資格情報をアプリケーションに含めずに、Azure の各サービスへ認証を行うことができます。
今回は、ASP.NET Core で作成した Web アプリケーションで試してみます。Visual Studio のテンプレートから作成したシンプルな MVC アプリケーションです。
MSI を使って Azure Key Vault に接続するための2つの NuGet ライブラリをインストールします。
Install-Package Microsoft.Azure.KeyVault -Version 3.0.3 Install-Package Microsoft.Azure.Services.AppAuthentication -Version 1.0.3
HomeController クラスで、MSI を使って Azure Key Vault から接続文字列を取得するコードを書きます。
vaultBaseUrl は、先ほど作成した Azure Key Vault のURL です。AzureServiceTokenProvider を使って KeyVaultClient をインスタンス化している部分がポイントです。
public class HomeController : Controller { public async Task<IActionResult> About() { var vaultBaseUrl = "https://xxx.vault.azure.net/"; var provider = new AzureServiceTokenProvider(); using (var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback))) { var secret = await client.GetSecretAsync(vaultBaseUrl, "SqlConnection"); ViewData["Message"] = secret.Value; } return View(); } }
ローカル開発環境で Visual Studio からデバッグ実行してみます。Azure Key Vault に作成したシークレット(SqlConnection)の値が取得できたことがわかります。
ここで疑問に思うのが、ローカル開発環境からシークレットを取得できた理由です。
最近の Visual Studio では、Azure サービス認証に登録されたアカウントのトークンを使って AzureServiceTokenProvider が生成されるようになっているので、Visual Studio から Azure Web Apps にデプロイなどの機能を使っていれば、特に意識せずに Azure Key Vault に作成したシークレットを取得することができます。
環境によってこの方法が利用できない場合には、環境変数「AzureServicesAuthConnectionString」を使いましょう。設定する値については、こちらを参照してください。
Azure Web Apps で接続文字列を取得する
先ほど作成した ASP.NET Core の Web アプリケーションを Azure Web Apps にデプロイしてみます。
Azure Web Apps の MSI を有効にしておきます。このタイミングで、サービスプリンシパルが追加されます。
続いて、Azure Key Vault の Access policies で、Azure Web Apps のサービスプリンシパルを許可します。必要最低限のパーミッションとして、シークレットの Get だけを許可しました。忘れずに Save ボタンで保存ましょう。
ASP.NET Core の Web アプリケーションを Azure Web Apps にデプロイし、結果を確認します。
Azure Key Vault に作成したシークレット(SqlConnection)の値が取得できたことがわかります。
まとめ
アプリケーションを開発する際には、DBの接続文字列、API のアクセスキー、証明書などのシークレットは手間をかけずに安全に管理したいところです。MSI と Azure Key Vault を組み合わせて使うことで、このあたりの煩わしさを解消できます。パブリックなリポジトリでシークレットを公開してしまう事故を防ぐためにも、しっかりとアーキテクチャで考慮しておきたい事項です。