Azure Key Vaultで作成した証明書をサービスプリンシパルに登録して認証する

#はじめに
オンプレミス環境のアプリケーションからAzureのサービスにアクセスするには、サービスプリンシパルを使用することが推奨されています。サービスプリンシパルを使用することで対話型ログオンでユーザー名/パスワードを入力したりアプリケーションにパスワードをハードコードしたりすることなく、Azureのサービスを利用することが可能になります。サービスプリンシパルで使用できる認証にはパスワードベースの認証（アプリケーションシークレット）と証明書ベースの認証がありますが、証明書ベースの認証を利用することでアプリケーションからよりセキュアにサービスプリンシパルを使用することができます。

すでに認証局（CA）や証明書の配布など公開鍵基盤（PKI）の仕組みを持っていればそれを利用することができますが、そうでない場合は新規にActive Directory証明書サービス（AD CS）などを構築して管理する必要があります。今回はPKIのためのインフラを運用していくための手間をかけずに証明書の発行を行うために、Azure Key Vaultで作成した証明書をサービスプリンシパルで利用するための手順について説明します。

#Azure サービスプリンシパルとは
Azure サービスプリンシパルとは、Azure Active Directory（Azure AD）で管理されるアカウントの一種です。サービスプリンシパルはAzure ADテナントに存在し、そのテナント内に存在するAzureリソースに対する必要なアクセス権を設定することができます。なおここでは詳しく触れませんが、アプリケーションがAzure VM上などで稼働している場合はサービスプリンシパルではなくマネージドIDを利用するとより便利に認証をあつかうことができます。

#Azure Key Vaultとは
Azure Key Vaultとは、アプリケーションやサービスで利用する暗号化キー、証明書やトークンなどのシークレットを安全に格納し利用できるようにするサービスです。Azure Key Vaultを使用することで、以下のようなことが実現できます。

- シークレット管理：パスワードやデータベース接続文字列などのシークレットを安全に格納し、アクセスを制御します。
- キー管理：データの暗号化に使用する暗号化キーの作成と管理をおこなうことができます。
- 証明書管理：SSL/TLS証明書のプロビジョニング、管理、デプロイを簡単におこなうことができます。

#Azure Key Vaultで証明書を作成する
ここでは、Azure Key Vaultのコンテナを作成し、証明書の機能を使用してサービスプリンシパルでの認証に使用する証明書を作成していきます。Key Vaultコンテナの作成は、Azure PortalやAzure CLI、Azure PowerShellなどから行うことが可能ですがここではAzure CLIによる手順を紹介しています。また、Key Vaultでは証明機関と連携して証明書を連携および更新することが可能ですが、この手順では自己署名証明書を使用しています。なお、作成するKey Vaultの名前はユニークである必要があります。

```shell:AzureCLI
#Key Vaultのコンテナを作成するためのリソースグループの作成
az group create --name "ExampleResourceGroup" --location japaneast

#Key Vaultを作成
az keyvault create --name "MyExampleVault" --resource-group "ExampleResourceGroup" --location japaneast

#証明書をKey Vaultに登録
az keyvault certificate create --vault-name "MyExampleVault" -n "ExampleCertificate" -p "$(az keyvault certificate get-default-policy)"

#登録した証明書のエクスポート
az keyvault certificate download --vault-name "MyExampleVault" -n "ExampleCertificate" -f cert.pem 

#証明書の秘密鍵をエクスポート
az keyvault secret download --vault-name "MyExampleVault" -f secret.pfx
```
登録した証明書を使用してサービスプリンシパルにサインインするためには、先ほどエクスポートした秘密鍵をpem形式に変換し、証明書とあわせて1つのファイルにする必要があります。まずは、秘密鍵のpfxファイルをpem形式に変換します。

```shell:openssl
openssl pkcs12 -in secret.pfx -nocerts --nodes -out secret.pem
```
証明書と秘密鍵のpemファイルをテキストエディタなどで開き、作成したpemファイルが以下のような形式になるようにあわせて編集します。

```text:secretcert.pem
-----BEGIN PRIVATE KEY-----
myPrivateKeyValue
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
myCertificateValue
-----END CERTIFICATE-----
```

#サービスプリンシパルの作成と証明書のインポート
Azureのサービスプリンシパルを作成し、先ほどの手順で作成した証明書を使用してAzureリソースにアクセスできるようにします。Key Vaultに格納されている証明書を使用してサービスプリンシパルを作成し、適切なロールを割り当てます。この例では、閲覧者ロールを追加して共同作成者ロールを削除しています。

```shell:AzureCLI
#サービスプリンシパルの作成
az ad sp create-for-rbac --name ServicePrincipalName --cert "ExampleCertificate" --keyvault "MyExampleVault"

#作成したサービスプリンシパルの一覧からアプリケーションIDとテナントIDの取得
az ad sp list --show-mine --query "[].{id:appId, tenant:appOwnerTenantId}"

#サービスプリンシパルへのロールの割り当て
az role assignment create --assignee APP_ID --role Reader
az role assignment delete --assignee APP_ID --role Contributor
```

または、サービスプリンシパルの作成時に自己署名証明書を作成してそのままKey Vaultに格納することもできます。この場合も証明書および秘密鍵をKey Vaultからダウンロードしてpem形式に変換する必要があります。

```shell:AzureCLI
az ad sp create-for-rbac --name ServicePrincipalName --create-cert --cert "ExampleCertificate" --keyvault "MyExampleVault"
```

#証明書を使用したサービスプリンシパルへのサインイン
証明書を使用してサービスプリンシパルにサインインするためには、アプリケーションID、テナントIDおよび証明書ファイルへのパスが必要になります。以下のAPP_IDおよびTENANT_IDには実際のIDを、/path/to/certを、先ほど作成した秘密鍵および証明書ファイルのパスに置き換えて実行します。

```shell:AzureCLI
az login --service-principal --username APP_ID --tenant TENANT_ID --password /path/to/cert
```
#まとめ
この記事では、Azure CLIを使用してAzure Key Vaultで作成した証明書を使用してサービスプリンシパルを作成し、サインインする方法について確認しました。より詳細なオプションに関する情報、またはAzureポータルから同様の操作を行う方法などについては参考情報にあるドキュメントを参照してください。


#参考情報
クイック スタート:Azure CLI を使用して Azure Key Vault から証明書の設定と取得を行う
https://docs.microsoft.com/ja-jp/azure/key-vault/certificates/quick-create-cli

クイック スタート:Azure portal を使用して Azure Key Vault から証明書の設定と取得を行う
https://docs.microsoft.com/ja-jp/azure/key-vault/certificates/quick-create-portal

Azure CLI で Azure サービス プリンシパルを作成する
https://docs.microsoft.com/ja-jp/cli/azure/create-an-azure-service-principal-azure-cli

方法:リソースにアクセスできる Azure AD アプリケーションとサービス プリンシパルをポータルで作成する
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-create-service-principal-portal