Node.jsでAzure Key Vaultに格納されたシークレットを取得してみる(超簡単) 

# はじめに
従来のソフトウェア開発において、本番環境でのパスワードや暗号鍵、デジタル証明書、APIキーなどといったシークレットは環境変数に保管してアプリケーションからアクセスします。しかしクラウドサービスを利用したモダンなソフトウェア開発においては、アプリケーションは様々な実行環境に分散していて、それぞれ個別に設定ファイルを用意し、環境変数を設定する必要があります。Azure Key Vaultを利用すると、そのようなシークレットをクラウド上で一元管理することができ、それらの情報に対するアクセスをAzure ADによる認証で保護することができます。今回の記事では、Node.jsを用いて、Azure Key Vault上に保存されているシークレットにアクセスする方法をまとめていきたいと思います。

# Azure Key Vault リソースを作成する

Azure Key Vault リソースをAzure CLI を使用して作成していきます。

Azure Portal を使用したAzure Key Vault リソースの作成方法は以下の公式の記事を参考にしてください。

https://learn.microsoft.com/ja-jp/azure/key-vault/general/quick-create-portal

以下のスクリプトは、Azure上に、リソースグループ、Azure Key Vaultリソースを作成して、最後にAzure Key Vaultの名前を.envファイルとして、生成してくれます。.envファイルはNode.jsから環境変数として読み込まれます。

```bash
#!/bin/bash

let randomIdentifier=$RANDOM*$RANDOM

# resource group
readonly AZ_RESOURCE_GROUP="myTestingRG${randomIdentifier}"
readonly AZ_RESOURCE_GROUP_LOCATION="japaneast"
# key vault
readonly AZ_KEY_VAULT_NAME="nicekeyvault${randomIdentifier}"
readonly AZ_KEY_VAULT_LOCATION="japaneast"

echo "Creating Resource Group..."
az group create \
    --name ${AZ_RESOURCE_GROUP} \
    --location ${AZ_RESOURCE_GROUP_LOCATION}
echo "Done! ${AZ_RESOURCE_GROUP} has been created."

echo "Creating Azure Key Vault resource..."
az keyvault create \
    --name ${AZ_KEY_VAULT_NAME} \
    --resource-group ${AZ_RESOURCE_GROUP} \
    --location ${AZ_KEY_VAULT_LOCATION}
echo "Done! ${AZ_KEY_VAULT_NAME} has been created."

out=$(
    cat <<EOF
    AZ_KEY_VAULT_NAME=${AZ_KEY_VAULT_NAME}
EOF
)
echo ${out} >.env
echo "Done! All required resources have just been successfully created!"
```

shell scriptファイルを作成して、実行権限を付与します。

```bash
touch init.sh && chmod +x init.sh
```

あとは、上記のshell scriptの内容をコピペして、以下のように実行してください。

```bash
./init.sh
```

# Azure Key Vault にシークレットを追加する
データベース接続のための認証情報や、3rdパーティー製のAPI キーなどは開発者以外に、非技術者の管理者が直接管理することが多々あるので、今回はAzure Portalからシークレットを追加します。もちろんCLIやコードからのシークレットの追加もできます。

![Screen Shot 2022-12-01 at 13.44.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822052/45c7989b-f04a-2b0e-7e3f-c69ee5b590a8.png)
![Screen Shot 2022-12-01 at 13.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822052/ee1b5d68-ab38-5356-8588-555f0dc5d45d.png)
![Screen Shot 2022-12-01 at 13.45.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822052/180b7e6f-8d5f-0ce8-c7e0-d77fef343799.png)
![Screen Shot 2022-12-01 at 13.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822052/ca08bf51-4def-39a6-d4ec-724be1a3220e.png)
![Screen Shot 2022-12-01 at 13.47.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822052/a913ae17-931c-433e-9a6d-990192776ef2.png)
![Screen Shot 2022-12-01 at 13.47.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822052/9dd5c6d9-185f-a9a3-dad0-94c7321b948a.png)

# Node.jsプロジェクトの作成

```bash
proj=try-azure-key-vault
```

```bash
mkdir ${proj} && cd ${proj}
```

```bash
npm init -y
```

以下の`package.json`をコピペしてください。

```json:package.json
{
  "name": "try-azure-key-vault",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node src/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@azure/identity": "3.1.1",
    "@azure/keyvault-secrets": "4.6.0",
    "dotenv": "16.0.3"
  }
}
```

`package.json`ファイルに基づいて、ライブラリーをインストールします。

インストールするライブラリは以下の通りです。

- `@azure/identity`はAure ADに対して認証を行うために使用します。Azure Key VaultはAzure ADによって保護されています。
- `@azure/keyvault-secrets` はAzure Key Vaultとやり取りをするために使用します。このライブラリーを使用すれば、とてもシンプルなAPIを通して、シークレットの取得ができます。
- `dotnev`は.envファイルから環境変数の読み込みを行うために使用します。

```bash
npm i
```

```bash
mkdir src && touch src/index.js
```

`src/index.js`に以下のコードをコピペしてください。

```js:src/index.js
const { SecretClient } = require("@azure/keyvault-secrets");
const { DefaultAzureCredential } = require("@azure/identity");

const dotenv = require("dotenv");
// azure CLIのスクリプト実行後に生成された.envファイルを読み込む
dotenv.config();

async function main() {
  // 現在Azure CLIでログインしているユーザーを元に認証オブジェクトを生成する
  const credential = new DefaultAzureCredential();
  const keyVaultName = process.env.AZ_KEY_VAULT_NAME;
  // Azure Key VaultにアクセスするためのURL
  const keyVaultURL = `https://${keyVaultName}.vault.azure.net`;

  const secretName = "testSecret";

  // Azure Key VaultのURLとAzure AD認証のためのオブジェクトからクライアントを生成
  const client = new SecretClient(keyVaultURL, credential);

  // シークレットと紐付けたキーを使用して、シーレットの値を取得する
  const secret = await client.getSecret(secretName);
  console.log({ secret });
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
```

`package.json`の`start` scriptを実行します。

```bash
npm run start
```

成功すると、以下のように`secret`オブジェクトが取得できます。このオブジェクトの`value`セクションにシークレットの値が格納されています。

```bash
> try-azure-key-vault@1.0.0 start
> node src/index.js

{
  secret: {
    value: 'helloFromKeyVault',
    name: 'testSecret',
    properties: {
      expiresOn: undefined,
      createdOn: 2022-12-06T05:56:10.000Z,
      updatedOn: 2022-12-06T05:56:10.000Z,
      enabled: true,
      notBefore: undefined,
      recoverableDays: 90,
      recoveryLevel: 'Recoverable+Purgeable',
      id: 'https://nicekeyvault200341674.vault.azure.net/secrets/testSecret/1f7dbe8362e24e25a526d136cc19dc67',
      contentType: undefined,
      tags: {},
      managed: undefined,
      vaultUrl: 'https://nicekeyvault200341674.vault.azure.net',
      version: '1f7dbe8362e24e25a526d136cc19dc67',
      name: 'testSecret',
      certificateKeyId: undefined
    }
  }
}
```
# おわりに
Azure Key Vaultを使用すれば、安全にAzure AD認証に保護されたシークレット管理を実現できます。Azure Key Vaultにアクセスするための、SDKはC#, Java, Node.jsなど様々な言語に対応しており、比較的簡単にシークレットをコードから所得できます。クラウドを用いたモダンなシステム開発において、必須のサービスだと言えると思います。