Quickstart: Azure Key Vault certificate client library for JavaScript
Article 08/07/2024
10 contributors
Feedback
In this article
Prerequisites
Sign in to Azure
Create new Node.js application
Install Key Vault packages
Grant access to your key vault
Set environment variables
Authenticate and create a client
Code example
Run the sample application
Integrating with App Configuration
Next steps
Show 7 more
Get started with the Azure Key Vault certificate client library for JavaScript. Azure Key Vault is a cloud service that provides a secure store for certificates. You can securely store keys, passwords, certificates, and other secrets. Azure key vaults may be created and managed through the Azure portal. In this quickstart, you learn how to create, retrieve, and delete certificates from an Azure key vault using the JavaScript client library.
Key Vault client library resources:
API reference documentation | Library source code | Package (npm)
For more information about Key Vault and certificates, see:
This quickstart assumes you're running Azure CLI .
Run the login
command.
az login
If the CLI can open your default browser, it will do so and load an Azure sign-in page.
Otherwise, open a browser page at https://aka.ms/devicelogin and enter the
authorization code displayed in your terminal.
Sign in with your account credentials in the browser.
Create new Node.js application
Create a Node.js application that uses your key vault.
In a terminal, create a folder named key-vault-node-app
and change into that folder:
mkdir key-vault-node-app && cd key-vault-node-app
Initialize the Node.js project:
npm init -y
Install Key Vault packages
Using the terminal, install the Azure Key Vault secrets library, @azure/keyvault-certificates for Node.js.
npm install @azure/keyvault-certificates
Install the Azure Identity client library, @azure/identity , to authenticate to a Key Vault.
npm install @azure/identity
Grant access to your key vault
To gain permissions to your key vault through Role-Based Access Control (RBAC) , assign a role to your "User Principal Name" (UPN) using the Azure CLI command az role assignment create .
az role assignment create --role "Key Vault Certificate Officer" --assignee "<upn>" --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.KeyVault/vaults/<your-unique-keyvault-name>"
Replace <upn>, <subscription-id>, <resource-group-name> and <your-unique-keyvault-name> with your actual values. Your UPN will typically be in the format of an email address (e.g., username@domain.com).
Set environment variables
This application is using key vault endpoint as an environment variable called KEY_VAULT_URL
.
set KEY_VAULT_URL=<your-key-vault-endpoint>
Windows PowerShell
$Env:KEY_VAULT_URL="<your-key-vault-endpoint>"
export KEY_VAULT_URL=<your-key-vault-endpoint>
Authenticate and create a client
Application requests to most Azure services must be authorized. Using the DefaultAzureCredential method provided by the Azure Identity client library is the recommended approach for implementing passwordless connections to Azure services in your code. DefaultAzureCredential
supports multiple authentication methods and determines which method should be used at runtime. This approach enables your app to use different authentication methods in different environments (local vs. production) without implementing environment-specific code.
In this quickstart, DefaultAzureCredential
authenticates to key vault using the credentials of the local development user logged into the Azure CLI. When the application is deployed to Azure, the same DefaultAzureCredential
code can automatically discover and use a managed identity that is assigned to an App Service, Virtual Machine, or other services. For more information, see Managed Identity Overview .
In this code, the endpoint of your key vault is used to create the key vault client. The endpoint format looks like https://<your-key-vault-name>.vault.azure.net
but may change for sovereign clouds. For more information about authenticating to key vault, see Developer's Guide .
This code uses the following Key Vault Certificate classes and methods :
Create new text file and paste the following code into the index.js file.
const { CertificateClient, DefaultCertificatePolicy } = require("@azure/keyvault-certificates");
const { DefaultAzureCredential } = require("@azure/identity");
async function main() {
// If you're using MSI, DefaultAzureCredential should "just work".
// Otherwise, 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 CertificateClient(keyVaultUrl, credential);
const uniqueString = new Date().getTime();
const certificateName = `cert${uniqueString}`;
// Creating a self-signed certificate
const createPoller = await client.beginCreateCertificate(
certificateName,
DefaultCertificatePolicy
);
const pendingCertificate = createPoller.getResult();
console.log("Certificate: ", pendingCertificate);
// To read a certificate with their policy:
let certificateWithPolicy = await client.getCertificate(certificateName);
// Note: It will always read the latest version of the certificate.
console.log("Certificate with policy:", certificateWithPolicy);
// To read a certificate from a specific version:
const certificateFromVersion = await client.getCertificateVersion(
certificateName,
certificateWithPolicy.properties.version
);
// Note: It will not retrieve the certificate's policy.
console.log("Certificate from a specific version:", certificateFromVersion);
const updatedCertificate = await client.updateCertificateProperties(certificateName, "", {
tags: {
customTag: "value"
}
});
console.log("Updated certificate:", updatedCertificate);
// Updating the certificate's policy:
await client.updateCertificatePolicy(certificateName, {
issuerName: "Self",
subject: "cn=MyOtherCert"
});
certificateWithPolicy = await client.getCertificate(certificateName);
console.log("updatedCertificate certificate's policy:", certificateWithPolicy.policy);
// delete certificate
const deletePoller = await client.beginDeleteCertificate(certificateName);
const deletedCertificate = await deletePoller.pollUntilDone();
console.log("Recovery Id: ", deletedCertificate.recoveryId);
console.log("Deleted Date: ", deletedCertificate.deletedOn);
console.log("Scheduled Purge Date: ", deletedCertificate.scheduledPurgeDate);
}
main().catch((error) => {
console.error("An error occurred:", error);
process.exit(1);
});
Run the sample application
Run the app:
node index.js
The create and get methods return a full JSON object for the certificate:
{
"keyId": undefined,
"secretId": undefined,
"name": "YOUR-CERTIFICATE-NAME",
"reuseKey": false,
"keyCurveName": undefined,
"exportable": true,
"issuerName": 'Self',
"certificateType": undefined,
"certificateTransparency": undefined
},
"properties": {
"createdOn": 2021-11-29T20:17:45.000Z,
"updatedOn": 2021-11-29T20:17:45.000Z,
"expiresOn": 2022-11-29T20:17:45.000Z,
"id": "https://YOUR-KEY-VAULT-NAME-ENDPOINT/certificates/YOUR-CERTIFICATE-NAME/YOUR-CERTIFICATE-VERSION",
"enabled": false,
"notBefore": 2021-11-29T20:07:45.000Z,
"recoveryLevel": "Recoverable+Purgeable",
"name": "YOUR-CERTIFICATE-NAME",
"vaultUrl": "https://YOUR-KEY-VAULT-NAME-ENDPOINT",
"version": "YOUR-CERTIFICATE-VERSION",
"tags": undefined,
"x509Thumbprint": undefined,
"recoverableDays": 90
}
}
Create new text file and paste the following code into the index.ts file.
import {
CertificateClient,
DefaultCertificatePolicy,
KeyVaultCertificate,
DeletedCertificate,
CertificatePolicy,
KeyVaultCertificateWithPolicy,
} from "@azure/keyvault-certificates";
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 printCertificate(
certificate: KeyVaultCertificate | KeyVaultCertificateWithPolicy
): void {
console.log("-- printCertificate ---------------------------");
// if policy is defined, it's a KeyVaultCertificateWithPolicy
if ((certificate as KeyVaultCertificateWithPolicy).policy) {
const { name, properties, policy } =
certificate as KeyVaultCertificateWithPolicy;
const { createdOn, updatedOn, expiresOn, vaultUrl, version, tags } =
properties;
console.log("Certificate: ", {
name,
createdOn,
updatedOn,
expiresOn,
vaultUrl,
version,
});
console.log("Certificate Policy: ", policy);
printObjectProperties(tags);
return;
} else {
const { name, properties } = certificate;
const { createdOn, updatedOn, expiresOn, vaultUrl, version, tags } =
properties;
console.log("Certificate: ", {
name,
createdOn,
updatedOn,
expiresOn,
vaultUrl,
version,
});
printObjectProperties(tags);
}
}
// Object properties are tags and CertificatePolicy
function printObjectProperties(obj: Record<string, any>): void {
if (!obj) return;
console.log("-- printObjectProperties ---------------------------");
Object.entries(obj).forEach(([key, value]) => {
if (key === "lifetimeActions") {
console.log(`${key}: ${JSON.stringify(value)}`);
} else {
console.log(`${key}: ${value}`);
}
});
}
function printDeletedCertificate(deletedCertificate: DeletedCertificate): void {
const { recoveryId, deletedOn, scheduledPurgeDate } = deletedCertificate;
console.log("Deleted Certificate: ", {
recoveryId,
deletedOn,
scheduledPurgeDate,
});
}
async function main(): Promise<void> {
// Create a new CertificateClient
const client = new CertificateClient(keyVaultUrl, credential);
// Create a unique certificate name
const uniqueString = new Date().getTime().toString();
const certificateName = `cert${uniqueString}`;
// Creating a self-signed certificate
const createPoller = await client.beginCreateCertificate(
certificateName,
DefaultCertificatePolicy
);
// Get the created certificate
const pendingCertificate = await createPoller.getResult();
printCertificate(pendingCertificate);
// Get certificate by name
let certificateWithPolicy = await client.getCertificate(certificateName);
printCertificate(pendingCertificate);
// Get certificate by version
const certificateFromVersion = await client.getCertificateVersion(
certificateName,
certificateWithPolicy.properties.version!
);
printCertificate(certificateFromVersion);
// Update properties of the certificate
const updatedCertificate = await client.updateCertificateProperties(
certificateName,
certificateWithPolicy.properties.version!,
{
tags: {
customTag: "my value",
},
}
);
printCertificate(updatedCertificate);
// Updating the certificate's policy
const certificatePolicy = await client.updateCertificatePolicy(
certificateName,
{
issuerName: "Self",
subject: "cn=MyOtherCert",
}
);
printObjectProperties(certificatePolicy);
// Get certificate again to see the updated policy
certificateWithPolicy = await client.getCertificate(certificateName);
printCertificate(certificateWithPolicy);
// Delete certificate
const deletePoller = await client.beginDeleteCertificate(certificateName);
const deletedCertificate = await deletePoller.pollUntilDone();
printDeletedCertificate(deletedCertificate);
}
main().catch((error) => {
console.error("An error occurred:", error);
process.exit(1);
});
Run the sample application
Build the TypeScript app:
tsc
Run the app:
node index.js
The create and get methods return a full JSON object for the certificate:
{
"keyId": undefined,
"secretId": undefined,
"name": "YOUR-CERTIFICATE-NAME",
"reuseKey": false,
"keyCurveName": undefined,
"exportable": true,
"issuerName": 'Self',
"certificateType": undefined,
"certificateTransparency": undefined
},
"properties": {
"createdOn": 2021-11-29T20:17:45.000Z,
"updatedOn": 2021-11-29T20:17:45.000Z,
"expiresOn": 2022-11-29T20:17:45.000Z,
"id": "https://YOUR-KEY-VAULT-NAME-ENDPOINT/certificates/YOUR-CERTIFICATE-NAME/YOUR-CERTIFICATE-VERSION",
"enabled": false,
"notBefore": 2021-11-29T20:07:45.000Z,
"recoveryLevel": "Recoverable+Purgeable",
"name": "YOUR-CERTIFICATE-NAME",
"vaultUrl": "https://YOUR-KEY-VAULT-NAME-ENDPOINT",
"version": "YOUR-CERTIFICATE-VERSION",
"tags": undefined,
"x509Thumbprint": undefined,
"recoverableDays": 90
}
}
Integrating with App Configuration
The Azure SDK provides a helper method, parseKeyVaultCertificateIdentifier , to parse the given Key Vault certificate ID, which is necessary if you use App Configuration references to Key Vault. App Config stores the Key Vault certificate ID. You need the parseKeyVaultCertificateIdentifier method to parse that ID to get the certificate name. Once you have the certificate name, you can get the current certificate using code from this quickstart.
In this quickstart, you created a key vault, stored a certificate, and retrieved that certificate. To learn more about Key Vault and how to integrate it with your applications, continue on to these articles.