クイックスタート: JavaScript 用 Azure Key Vault キー クライアント ライブラリ
JavaScript 用 Azure Key Vault キー クライアント ライブラリを使ってみます。 Azure Key Vault は、暗号化キーのセキュリティで保護されたストアを提供するクラウド サービスです。 キー、パスワード、証明書、およびその他のシークレットを安全に保管することができます。 Azure Key Vault は、Azure Portal を使用して作成および管理できます。 このクイックスタートでは、JavaScript キー クライアント ライブラリを使用して Azure キー コンテナーにキーを作成し、それを取得および削除する方法について説明します。
Key Vault クライアント ライブラリのリソースは、次のとおりです。
API リファレンスのドキュメント | ライブラリのソース コード | パッケージ (npm)
Key Vault とキーの詳細については、以下を参照してください。
前提条件
- Azure サブスクリプション - 無料アカウントを作成します。
- 現在の Node.js LTS。
- Azure CLI
- 既存の Key Vault - 次を使用して作成できます。
- Azure サブスクリプション - 無料アカウントを作成します。
- 現在の Node.js LTS。
- TypeScript 5 以降
- Azure CLI。
- 既存の Key Vault - 次を使用して作成できます。
このクイックスタートでは、Azure CLI を実行していることを前提としています。
Azure へのサインイン
login
コマンドを実行します。az login
CLI で既定のブラウザーを開くことができる場合、開いたブラウザに Azure サインイン ページが読み込まれます。
それ以外の場合は、 https://aka.ms/devicelogin でブラウザー ページを開き、ターミナルに表示されている認証コードを入力します。
ブラウザーでアカウントの資格情報を使用してサインインします。
新しい Node.js アプリケーションを作成する
キー コンテナーを使用する Node.js アプリケーションを作成します。
ターミナルで、
key-vault-node-app
という名前のフォルダーを作成し、そのフォルダーに移動します。mkdir key-vault-node-app && cd key-vault-node-app
Node.js プロジェクトを初期化します。
npm init -y
Key Vault パッケージをインストールする
ターミナルを使用して、Node.js 用の Azure Key Vault シークレット クライアント ライブラリ @azure/keyvault-keys をインストールします。
npm install @azure/keyvault-keys
Key Vault の認証を行うために、Azure ID クライアント ライブラリ @azure/identity パッケージをインストールします。
npm install @azure/identity
キー コンテナーへのアクセス許可を付与する
ロールベースのアクセス制御 (RBAC) を使用してキー コンテナーに対するアクセス許可を取得するには、Azure CLI コマンドの az role assignment create を使用して、"ユーザー プリンシパル名" (UPN) にロールを割り当てます。
az role assignment create --role "Key Vault Crypto Officer" --assignee "<upn>" --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.KeyVault/vaults/<your-unique-keyvault-name>"
<upn>、<subscription-id>、<resource-group-name>、<your-unique-keyvault-name> は実際の値に置き換えます。 UPN は一般的に、メール アドレスの形式を取ります (例: username@domain.com)。
環境変数の設定
このアプリケーションでは、KEY_VAULT_URL
という環境変数として、キー コンテナー エンドポイントを使います。
set KEY_VAULT_URL=<your-key-vault-endpoint>
クライアントの認証と作成
ほとんどの Azure サービスに対するアプリケーション要求は、認可される必要があります。 Azure ID クライアント ライブラリによって提供される DefaultAzureCredential メソッドを使うことは、コード内の Azure サービスへのパスワードレス接続を実装するための推奨される方法です。 DefaultAzureCredential
は複数の認証方法をサポートしており、実行時に使用する方法が決定されます。 このアプローチを採用すると、環境固有のコードを実装することなく、異なる環境 (ローカルと運用環境) で異なる認証方法をアプリに使用できます。
このクイックスタートでは、DefaultAzureCredential
は Azure CLI にログインしたローカル開発ユーザーの資格情報を使って、キー コンテナーに対して認証されます。 アプリケーションが Azure にデプロイされると、同じDefaultAzureCredential
コードで、App Service、仮想マシン、またはその他のサービスに割り当てられているマネージド ID を自動的に検出して使用できます。 詳細については、マネージド ID の概要に関するページを参照してください。
このコードでは、キー コンテナーのエンドポイントを使って、キー コンテナー クライアントを作成します。 エンドポイントの形式は https://<your-key-vault-name>.vault.azure.net
のようになりますが、ソブリン クラウドでは変わる可能性があります。 キー コンテナーに対する認証の詳細については、開発者ガイドを参照してください。
コードの例
以下のコード サンプルでは、クライアントの作成、シークレットの設定、シークレットの取得、シークレットの削除を行う方法を示します。
このコードでは、次の Key Vault Secret クラスとメソッドを使用します。
アプリのフレームワークを設定する
新しいテキスト ファイルを作成し、次のコードを index.js ファイルに貼り付けます。
const { KeyClient } = require("@azure/keyvault-keys"); const { DefaultAzureCredential } = require("@azure/identity"); async function main() { // DefaultAzureCredential expects the following three environment variables: // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant // - AZURE_CLIENT_SECRET: The client secret for the registered application const credential = new DefaultAzureCredential(); const keyVaultUrl = process.env["KEY_VAULT_URL"]; if(!keyVaultUrl) throw new Error("KEY_VAULT_URL is empty"); const client = new KeyClient(keyVaultUrl, credential); const uniqueString = Date.now(); const keyName = `sample-key-${uniqueString}`; const ecKeyName = `sample-ec-key-${uniqueString}`; const rsaKeyName = `sample-rsa-key-${uniqueString}`; // Create key using the general method const result = await client.createKey(keyName, "EC"); console.log("key: ", result); // Create key using specialized key creation methods const ecResult = await client.createEcKey(ecKeyName, { curve: "P-256" }); const rsaResult = await client.createRsaKey(rsaKeyName, { keySize: 2048 }); console.log("Elliptic curve key: ", ecResult); console.log("RSA Key: ", rsaResult); // Get a specific key const key = await client.getKey(keyName); console.log("key: ", key); // Or list the keys we have for await (const keyProperties of client.listPropertiesOfKeys()) { const key = await client.getKey(keyProperties.name); console.log("key: ", key); } // Update the key const updatedKey = await client.updateKeyProperties(keyName, result.properties.version, { enabled: false }); console.log("updated key: ", updatedKey); // Delete the key - the key is soft-deleted but not yet purged const deletePoller = await client.beginDeleteKey(keyName); await deletePoller.pollUntilDone(); const deletedKey = await client.getDeletedKey(keyName); console.log("deleted key: ", deletedKey); // Purge the key - the key is permanently deleted // This operation could take some time to complete console.time("purge a single key"); await client.purgeDeletedKey(keyName); console.timeEnd("purge a single key"); } main().catch((error) => { console.error("An error occurred:", error); process.exit(1); });
サンプル アプリケーションの実行
アプリを実行します。
node index.js
create および get メソッドにより、キーの完全な JSON オブジェクトが返されます。
"key": { "key": { "kid": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION", "kty": "YOUR-KEY-TYPE", "keyOps": [ ARRAY-OF-VALID-OPERATIONS ], ... other properties based on key type }, "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION", "name": "YOUR-KEY-NAME", "keyOperations": [ ARRAY-OF-VALID-OPERATIONS ], "keyType": "YOUR-KEY-TYPE", "properties": { "tags": undefined, "enabled": true, "notBefore": undefined, "expiresOn": undefined, "createdOn": 2021-11-29T18:29:11.000Z, "updatedOn": 2021-11-29T18:29:11.000Z, "recoverableDays": 90, "recoveryLevel": "Recoverable+Purgeable", "exportable": undefined, "releasePolicy": undefined, "vaultUrl": "https://YOUR-KEY-VAULT-ENDPOINT", "version": "YOUR-KEY-VERSION", "name": "YOUR-KEY-VAULT-NAME", "managed": undefined, "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION" } }
index.ts という名前の新しいテキスト ファイルを作成して、次のコードを貼り付けます。
import { KeyClient, KeyVaultKey, KeyProperties, DeletedKey, } from "@azure/keyvault-keys"; import { DefaultAzureCredential } from "@azure/identity"; import "dotenv/config"; const credential = new DefaultAzureCredential(); // Get Key Vault name from environment variables // such as `https://${keyVaultName}.vault.azure.net` const keyVaultUrl = process.env.KEY_VAULT_URL; if (!keyVaultUrl) throw new Error("KEY_VAULT_URL is empty"); function printKey(keyVaultKey: KeyVaultKey): void { const { name, key, id, keyType, keyOperations, properties } = keyVaultKey; console.log("Key: ", { name, key, id, keyType }); const { vaultUrl, version, enabled, expiresOn }: KeyProperties = properties; console.log("Key Properties: ", { vaultUrl, version, enabled, expiresOn }); console.log("Key Operations: ", keyOperations.join(", ")); } async function main(): Promise<void> { // Create a new KeyClient const client = new KeyClient(keyVaultUrl, credential); // Create unique key names const uniqueString = Date.now().toString(); const keyName = `sample-key-${uniqueString}`; const ecKeyName = `sample-ec-key-${uniqueString}`; const rsaKeyName = `sample-rsa-key-${uniqueString}`; // Create a EC key const ecKey = await client.createKey(keyName, "EC"); printKey(ecKey); // Elliptic curve key const ec256Key = await client.createEcKey(ecKeyName, { curve: "P-256", }); printKey(ec256Key); // RSA key const rsa2048Key = await client.createRsaKey(rsaKeyName, { keySize: 2048, }); printKey(rsa2048Key); // Get a key const key = await client.getKey(keyName); printKey(key); // Get properties of all keys for await (const keyProperties of client.listPropertiesOfKeys()) { const iteratedKey = await client.getKey(keyProperties.name); printKey(iteratedKey); } // Update key properties - disable key const updatedKey = await client.updateKeyProperties( keyName, ecKey.properties.version, { enabled: false, } ); printKey(updatedKey); // Delete key (without immediate purge) const deletePoller = await client.beginDeleteKey(keyName); await deletePoller.pollUntilDone(); // Get a deleted key const deletedKey = await client.getDeletedKey(keyName); console.log("deleted key: ", deletedKey.name); // Purge a deleted key console.time("purge a single key"); await client.purgeDeletedKey(keyName); console.timeEnd("purge a single key"); } main().catch((error) => { console.error("An error occurred:", error); process.exit(1); });
サンプル アプリケーションの実行
TypeScript アプリをビルドします。
tsc
アプリを実行します。
node index.js
create および get メソッドにより、キーの完全な JSON オブジェクトが返されます。
"key": { "key": { "kid": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION", "kty": "YOUR-KEY-TYPE", "keyOps": [ ARRAY-OF-VALID-OPERATIONS ], ... other properties based on key type }, "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION", "name": "YOUR-KEY-NAME", "keyOperations": [ ARRAY-OF-VALID-OPERATIONS ], "keyType": "YOUR-KEY-TYPE", "properties": { "tags": undefined, "enabled": true, "notBefore": undefined, "expiresOn": undefined, "createdOn": 2021-11-29T18:29:11.000Z, "updatedOn": 2021-11-29T18:29:11.000Z, "recoverableDays": 90, "recoveryLevel": "Recoverable+Purgeable", "exportable": undefined, "releasePolicy": undefined, "vaultUrl": "https://YOUR-KEY-VAULT-ENDPOINT", "version": "YOUR-KEY-VERSION", "name": "YOUR-KEY-VAULT-NAME", "managed": undefined, "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION" } }
App Configuration との統合
Azure SDK は、指定された Key Vault キー ID を解析するヘルパー メソッド parseKeyVaultKeyIdentifier を提供します。 これは、Key Vault への App Configuration の参照を使用する場合に必要です。 App Config には、Key Vault キー ID が格納されます。 キー名を取得するには、その ID を解析するための parseKeyVaultKeyIdentifier メソッドが必要です。 キー名を取得すると、このクイック スタートのコードを使用して現在のキー値を取得できます。
次のステップ
このクイックスタートでは、キー コンテナーを作成し、キーを格納して、そのキーを取得しました。 Key Vault およびアプリケーションとの統合方法の詳細については、引き続き以下の記事を参照してください。
- Azure Key Vault の概要を確認する
- Azure Key Vault キーの概要を確認する
- キー コンテナーへのアクセスをセキュリティで保護する方法
- 「Azure Key Vault 開発者ガイド」を参照する
- Key Vault のセキュリティの概要を確認する