@eqxjs/kms
v2.1.1
Published
For get Azure keyvault secret
Keywords
Readme
@eqxjs/kms
A NestJS module for Azure Key Vault secret management with built-in caching support.
Description
This library provides a simple and efficient way to interact with Azure Key Vault secrets in your NestJS applications. It includes automatic caching mechanisms to reduce API calls and improve performance.
Features
- ✅ Get secrets from Azure Key Vault with optional versioning
- ✅ Set secrets to Azure Key Vault
- ✅ List secret versions for a given secret
- ✅ JWT Token verification using public keys stored in Key Vault
- ✅ Built-in caching with configurable TTL
- ✅ Cache management (enable/disable/clear)
- ✅ Azure authentication using DefaultAzureCredential
- ✅ Smart cache expiration based on secret expiration dates
Installation
npm install @eqxjs/kmsPrerequisites
- NestJS application (v11+)
- Azure Key Vault instance
- Azure credentials configured (Managed Identity, Service Principal, or Azure CLI)
Configuration
Set the following environment variables:
# Optional: Cache time in seconds (default: 3600 seconds = 1 hour)
KEYVAULT_CACHE_TIME=3600Usage
1. Import the Module
Import KeyManagementModule in your NestJS application:
import { Module } from '@nestjs/common';
import { KeyManagementModule } from '@eqxjs/kms';
@Module({
imports: [
KeyManagementModule,
// other modules...
],
})
export class AppModule {}2. Inject the Service
Inject KeyManagementService into your services or controllers:
import { Injectable } from '@nestjs/common';
import { KeyManagementService } from '@eqxjs/kms';
@Injectable()
export class MyService {
constructor(
private readonly keyManagementService: KeyManagementService
) {}
}3. Get a Secret
Retrieve a secret from Azure Key Vault:
async getSecret() {
const keyvaultURL = 'https://your-keyvault.vault.azure.net/';
const secretName = 'my-secret';
try {
const secret = await this.keyManagementService.getSecret(
keyvaultURL,
secretName
);
console.log('Secret value:', secret.value);
console.log('Secret properties:', secret.properties);
return secret;
} catch (error) {
console.error('Error fetching secret:', error);
throw error;
}
}4. Get a Specific Secret Version
Retrieve a specific version of a secret:
async getSecretVersion() {
const keyvaultURL = 'https://your-keyvault.vault.azure.net/';
const secretName = 'my-secret';
const version = 'abc123def456'; // specific version ID
const secret = await this.keyManagementService.getSecret(
keyvaultURL,
secretName,
{ version }
);
return secret;
}5. Set a Secret
Create or update a secret in Azure Key Vault:
async setSecret() {
const keyvaultURL = 'https://your-keyvault.vault.azure.net/';
const secretName = 'my-secret';
const secretValue = 'super-secret-value';
const secret = await this.keyManagementService.setSecret(
keyvaultURL,
secretName,
secretValue
);
console.log('Secret created/updated:', secret.name);
return secret;
}6. Set a Secret with Options
Create a secret with additional properties:
async setSecretWithOptions() {
const keyvaultURL = 'https://your-keyvault.vault.azure.net/';
const secretName = 'my-secret';
const secretValue = 'super-secret-value';
const expiryDate = new Date();
expiryDate.setFullYear(expiryDate.getFullYear() + 1); // Expires in 1 year
const secret = await this.keyManagementService.setSecret(
keyvaultURL,
secretName,
secretValue,
{
contentType: 'text/plain',
enabled: true,
expiresOn: expiryDate,
tags: {
environment: 'production',
application: 'my-app'
}
}
);
return secret;
}7. List Secret Versions
List all versions of a specific secret:
async listSecretVersions() {
const keyvaultURL = 'https://your-keyvault.vault.azure.net/';
const secretName = 'my-secret';
const versions = this.keyManagementService.listSecretVersion(
keyvaultURL,
secretName
);
for await (const version of versions) {
console.log('Version ID:', version.version);
console.log('Created on:', version.createdOn);
console.log('Updated on:', version.updatedOn);
console.log('Enabled:', version.enabled);
}
}8. Verify JWT Token
Verify a JWT token using a public key stored in Key Vault:
async verifyToken(token: string) {
const keyvaultURL = 'https://your-keyvault.vault.azure.net/';
const secretName = 'jwt-public-key';
try {
const result = await this.keyManagementService.verifyJWTTokenBySecret(
keyvaultURL,
secretName,
token,
{
algorithms: ['RS256'],
issuer: 'https://your-issuer.com',
audience: 'your-audience'
}
);
if (result.result) {
console.log('Token is valid');
return true;
}
} catch (error) {
console.error('Token verification failed:', error);
return false;
}
}Note: The public key secret should be stored in JWKS format:
{
"keys": [
{
"kty": "RSA",
"n": "0vx7agoebGcQSuuPiLJXZ...",
"e": "AQAB",
"kid": "1",
"use": "sig"
}
]
}9. Cache Management
Control caching behavior:
// Disable cache
async disableCaching() {
this.keyManagementService.disableCache();
console.log('Cache disabled');
}
// Enable cache
async enableCaching() {
this.keyManagementService.enableCache();
console.log('Cache enabled');
}
// Clear cache
async clearCache() {
await this.keyManagementService.clearCache();
console.log('Cache cleared');
}Complete Example
import { Injectable } from '@nestjs/common';
import { KeyManagementService } from '@eqxjs/kms';
@Injectable()
export class DatabaseService {
constructor(
private readonly keyManagementService: KeyManagementService
) {}
async getDatabaseConnection() {
const keyvaultURL = process.env.KEYVAULT_URL;
// Get database credentials from Key Vault
const dbUsername = await this.keyManagementService.getSecret(
keyvaultURL,
'db-username'
);
const dbPassword = await this.keyManagementService.getSecret(
keyvaultURL,
'db-password'
);
const connectionString = await this.keyManagementService.getSecret(
keyvaultURL,
'db-connection-string'
);
return {
username: dbUsername.value,
password: dbPassword.value,
connectionString: connectionString.value
};
}
async rotatePassword(newPassword: string) {
const keyvaultURL = process.env.KEYVAULT_URL;
// Update password in Key Vault
await this.keyManagementService.setSecret(
keyvaultURL,
'db-password',
newPassword,
{
contentType: 'password',
tags: {
rotatedAt: new Date().toISOString()
}
}
);
// Clear cache to force refresh
await this.keyManagementService.clearCache();
}
}API Reference
KeyManagementService
Methods
getSecret(keyvaultURL: string, secretName: string, secretOpt?: GetSecretOptions): Promise<KeyVaultSecret>
Retrieves a secret from Azure Key Vault. Results are cached based on the configured cache time.
Parameters:
keyvaultURL: The Azure Key Vault URLsecretName: The name of the secretsecretOpt: (Optional) Options including version
Returns: Promise<KeyVaultSecret>
setSecret(keyvaultURL: string, secretName: string, secretValue: string, secretOpt?: SetSecretOptions): Promise<KeyVaultSecret>
Creates or updates a secret in Azure Key Vault. Automatically updates the cache.
Parameters:
keyvaultURL: The Azure Key Vault URLsecretName: The name of the secretsecretValue: The secret valuesecretOpt: (Optional) Additional options like contentType, enabled, expiresOn, tags
Returns: Promise<KeyVaultSecret>
listSecretVersion(keyvaultURL: string, secretName: string, secretOpt?: ListPropertiesOfSecretVersionsOptions): AsyncIterable<SecretProperties>
Lists all versions of a specific secret.
Parameters:
keyvaultURL: The Azure Key Vault URLsecretName: The name of the secretsecretOpt: (Optional) Listing options
Returns: AsyncIterable<SecretProperties>
verifyJWTTokenBySecret(keyURL: string, secretName: string, jwtToken: string, verifyoptions?: jwt.VerifyOptions): Promise<VerifyResult>
Verifies a JWT token using a public key stored in Key Vault.
Parameters:
keyURL: The Azure Key Vault URLsecretName: The name of the secret containing the public key (JWKS format)jwtToken: The JWT token to verifyverifyoptions: (Optional) JWT verification options
Returns: Promise<VerifyResult>
disableCache(): void
Disables caching and clears the current cache.
enableCache(): void
Enables caching.
clearCache(): Promise<void>
Clears all cached secrets.
Cache Behavior
- Default cache time: 1 hour (3600 seconds)
- Configurable via
KEYVAULT_CACHE_TIMEenvironment variable - For secrets with expiration dates, cache time is automatically adjusted to the earlier of:
- Configured cache time
- Time until secret expiration
- Cache is automatically updated when secrets are set
- Cache keys format:
- Latest version:
secretName:latest - Specific version:
secretName:versionId
- Latest version:
Authentication
This library uses Azure's DefaultAzureCredential, which supports multiple authentication methods in order:
- Environment variables
- Managed Identity
- Azure CLI
- Azure PowerShell
- Interactive browser
For production, it's recommended to use Managed Identity.
Error Handling
All methods throw errors that should be caught and handled appropriately:
try {
const secret = await this.keyManagementService.getSecret(
keyvaultURL,
secretName
);
} catch (error) {
console.error('Failed to retrieve secret:', error.message);
// Handle error appropriately
}License
ISC
Author
Atit Plangson
Keywords
- Azure Key Vault
- NestJS
- Secret Management
- KMS
- AIS
