.NET とか Node.js で KeyVault を触る

KeyValult の値をコードから触りたい場合。

.NET の場合

こうする。

var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(new AzureServiceTokenProvider().KeyVaultTokenCallback)

App Service からは MSI で認証しにいく*1。ローカルなら、Visual Studio が Azure で認証した内容が保存していて、クライアントを new するときに勝手にその情報を使いまわしてくれる。

.NET を使用した Azure Key Vault に対するサービス間認証 | Microsoft Docs

あとは client. で Tab ポチポチしたらだいたいわかる。 VS 最高。

Node.js の場合

npm から azure-keyvault をインストール。

npm i azure-keyvault

インポート。

import msRestAzure = require('ms-rest-azure');
import KeyVault = require('azure-keyvault');

App Service からは MSI で認証する。環境変数MSI_ENDPOINT とか MSI_SECRET とかが入ってるのでそれを参照できる。

const client = await msRestAzure.loginWithAppServiceMSI({ msiEndpoint: process.env.MSI_ENDPOINT, msiSecret: process.env.MSI_SECRET, resource: 'https://vault.azure.net' });

ローカルの場合。こちらは VS / .NET のときと違って、勝手に解決してくれない。

interactiveLogin を使って画面からインタラクティブにもやれるが、バックエンドを想定するとこう。 Azure のログインユーザー名とパスワードを生で環境変数にセットする、というのは良い気分ではないが((CLI から az login した認証情報を使いまわせたりするのかな))。。。

const client = await msRestAzure.loginWithUsernamePassword(process.env.KeyVaultLocalUsername, process.env.KeyVaultLocalPassword);

というわけで、合わせてこうなる。

const client = new KeyVault.KeyVaultClient(
  process.env.MSI_ENDPOINT 
    ? await msRestAzure.loginWithAppServiceMSI({ msiEndpoint: process.env.MSI_ENDPOINT, msiSecret: process.env.MSI_SECRET, resource: 'https://vault.azure.net' })
    : await msRestAzure.loginWithUsernamePassword(process.env.KeyVaultLocalUsername, process.env.KeyVaultLocalPassword));

Secret にセットするときはこんなかんじ。すでに存在したらバージョンが increment される。

const result = await client.setSecret('VAULT_URL', 'SECRET_NAME', 'SECRET');

result の中身はこんなかんじになる。

{ 
  value: 'SECRET',
  id: 'https:\\KEY_VAULT_NAME.vault.azure.net\secrets\SECRET_NAME\VERSION',
  attributes: 
  { 
    enabled: true,
    created: 2018-09-04T07:03:25.000Z,
    updated: 2018-09-04T07:03:25.000Z,
    recoveryLevel: 'Purgeable' 
  } 
}

*1:なので App Service で MSI を有効化し、 KeyVault の Access Policies からその MSI を許可しとく必要がある