@cemiar/keyvault-sdk
v1.0.9
Published
Cemiar package to handle key vault service
Keywords
Readme
@cemiar/keyvault-sdk
A TypeScript SDK for managing Azure Key Vault secrets with support for both single and multiple vault connections.
This package replaces the following legacy library:
| Legacy Package | Replaced By |
|----------------|-------------|
| cemiar-keyvault | KeyVaultManager / KeyVaultFactory |
Installation
npm install @cemiar/keyvault-sdkFeatures
- KeyVaultManager: Singleton pattern for single Key Vault connection
- KeyVaultFactory: Factory pattern for managing multiple Key Vault connections
- Support for local development using Azure CLI credentials
- Support for service principal authentication in production
Usage
Single Key Vault (KeyVaultManager)
Use KeyVaultManager when your application only needs to connect to one Key Vault.
import { KeyVaultManager } from '@cemiar/keyvault-sdk';
// Initialize once at application startup
// Option 1: Local development (uses Azure CLI credentials)
KeyVaultManager.initialize({
keyVaultUrl: 'https://my-vault.vault.azure.net',
useDefaultCred: true,
});
// Option 2: Production with service principal
KeyVaultManager.initialize({
keyVaultUrl: 'https://my-vault.vault.azure.net',
tenantId: 'your-tenant-id',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});
// Use anywhere in your application
const manager = KeyVaultManager.getInstance();
const secret = await manager.loadSecret('my-secret');Multiple Key Vaults (KeyVaultFactory)
Use KeyVaultFactory when your application needs to connect to multiple Key Vaults simultaneously.
import { KeyVaultFactory } from '@cemiar/keyvault-sdk';
const factory = new KeyVaultFactory();
// Register multiple vaults
factory.registerVault({
name: 'primary',
keyVaultUrl: 'https://primary-vault.vault.azure.net',
useDefaultCred: true,
makeDefault: true,
});
factory.registerVault({
name: 'secondary',
keyVaultUrl: 'https://secondary-vault.vault.azure.net',
tenantId: 'your-tenant-id',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});
// Load secrets from specific vaults
const primarySecret = await factory.loadSecretFromVault('primary', 'my-secret');
const secondarySecret = await factory.loadSecretFromVault('secondary', 'other-secret');
// Or use the default vault
const secret = await factory.loadSecret('my-secret');
// Create secrets
await factory.createSecretInVault('primary', 'new-secret', 'secret-value');
// List registered vaults
const vaults = factory.listRegisteredVaults(); // ['primary', 'secondary']
// Change default vault
factory.setDefaultVault('secondary');
// Unregister a vault
factory.unregisterVault('secondary');Authentication Options
Local Development
For local development, set useDefaultCred: true to use Azure CLI credentials:
{
keyVaultUrl: 'https://my-vault.vault.azure.net',
useDefaultCred: true
}Make sure you're logged in via Azure CLI:
az loginService Principal (Production)
For production environments, use service principal credentials:
{
keyVaultUrl: 'https://my-vault.vault.azure.net',
tenantId: 'your-tenant-id',
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
}API Reference
KeyVaultManager
| Method | Description |
| --------------------------------------- | ------------------------------------- |
| initialize(options) | Initialize the singleton instance |
| getInstance() | Get the singleton instance |
| loadSecret(secretName) | Load a secret from the vault |
| createSecret(secretName, secretValue) | Create a new secret |
| getSecretClient() | Get the underlying Azure SecretClient |
| getOptions() | Get the current connection options |
KeyVaultFactory
| Method | Description |
| --------------------------------------------------------- | ------------------------------------------------ |
| registerVault(options) | Register a new Key Vault connection |
| unregisterVault(name) | Remove a vault from the registry |
| setDefaultVault(name) | Set the default vault |
| getSecretClient(name?) | Get SecretClient for a specific or default vault |
| loadSecret(secretName) | Load a secret from the default vault |
| loadSecretFromVault(vaultName, secretName) | Load a secret from a specific vault |
| createSecret(secretName, secretValue) | Create a secret in the default vault |
| createSecretInVault(vaultName, secretName, secretValue) | Create a secret in a specific vault |
| listRegisteredVaults() | List all registered vault names |
| getDefaultVaultName() | Get the name of the default vault |
Types
interface KeyVaultAuthOptions {
useDefaultCred?: boolean;
tenantId?: string;
clientId?: string;
clientSecret?: string;
}
interface KeyVaultConnectionOptions extends KeyVaultAuthOptions {
keyVaultUrl: string;
}
interface VaultRegistrationOptions extends KeyVaultConnectionOptions {
name: string;
makeDefault?: boolean;
}Requirements
- Node.js >= 18.16.0
- npm >= 9.5.1
Migration Guide
From cemiar-keyvault
Update package.json
{
"dependencies": {
- "cemiar-keyvault": "^1.0.3",
+ "@cemiar/keyvault-sdk": "^1.0.0"
}
}Update imports
- import { KeyVaultManager } from "cemiar-keyvault";
+ import { KeyVaultManager } from "@cemiar/keyvault-sdk";Constructor changes
The old library used a direct constructor with hardcoded tenant ID. The new SDK uses a flexible initialization pattern:
// Before (cemiar-keyvault)
- const kv = new KeyVaultManager(
- "https://my-vault.vault.azure.net",
- "your-client-id",
- "your-client-secret"
- );
// After (@cemiar/keyvault-sdk) - Production
+ KeyVaultManager.initialize({
+ keyVaultUrl: "https://my-vault.vault.azure.net",
+ tenantId: "your-tenant-id", // Now configurable!
+ clientId: "your-client-id",
+ clientSecret: "your-client-secret"
+ });
+ const kv = KeyVaultManager.getInstance();
// After (@cemiar/keyvault-sdk) - Local development (NEW!)
+ KeyVaultManager.initialize({
+ keyVaultUrl: "https://my-vault.vault.azure.net",
+ useDefaultCred: true // Uses Azure CLI credentials
+ });
+ const kv = KeyVaultManager.getInstance();Method mapping
| cemiar-keyvault | @cemiar/keyvault-sdk | Notes |
|-----------------|----------------------|-------|
| new KeyVaultManager(url, id, secret) | KeyVaultManager.initialize(options) | ⚠️ Changed to singleton pattern |
| getSecret(secretName) | loadSecret(secretName) | ⚠️ Renamed |
| updateSecretConfigValue(secretsMap) | (see below) | ⚠️ Manual migration required |
| (not available) | createSecret(name, value) | ➕ New method |
| (not available) | getSecretClient() | ➕ New method |
| (not available) | getOptions() | ➕ New method |
Migrating updateSecretConfigValue
The old updateSecretConfigValue method loaded multiple secrets into process.env. Here's how to achieve the same with the new SDK:
// Before (cemiar-keyvault)
- const secretsMap = new Map([
- ["DB_PASSWORD", "database-password-key"],
- ["API_KEY", "api-key-secret"]
- ]);
- await kv.updateSecretConfigValue(secretsMap);
// After (@cemiar/keyvault-sdk)
+ const kv = KeyVaultManager.getInstance();
+ const secretsMap = new Map([
+ ["DB_PASSWORD", "database-password-key"],
+ ["API_KEY", "api-key-secret"]
+ ]);
+
+ await Promise.all(
+ Array.from(secretsMap.entries()).map(async ([envKey, secretKey]) => {
+ process.env[envKey] = await kv.loadSecret(secretKey);
+ })
+ );Or create a helper function:
async function loadSecretsToEnv(secretsMap: Map<string, string>): Promise<void> {
const kv = KeyVaultManager.getInstance();
await Promise.all(
Array.from(secretsMap.entries()).map(async ([envKey, secretKey]) => {
process.env[envKey] = await kv.loadSecret(secretKey);
})
);
}New features in @cemiar/keyvault-sdk
1. Configurable Tenant ID
The old library had a hardcoded tenant ID. The new SDK lets you configure it:
KeyVaultManager.initialize({
keyVaultUrl: "https://my-vault.vault.azure.net",
tenantId: "your-tenant-id", // Your own tenant
clientId: "your-client-id",
clientSecret: "your-client-secret"
});2. Local Development Support
Use Azure CLI credentials for local development without exposing secrets:
KeyVaultManager.initialize({
keyVaultUrl: "https://my-vault.vault.azure.net",
useDefaultCred: true
});3. Multiple Key Vaults (KeyVaultFactory)
The new SDK supports connecting to multiple Key Vaults simultaneously:
import { KeyVaultFactory } from "@cemiar/keyvault-sdk";
const factory = new KeyVaultFactory();
factory.registerVault({
name: "primary",
keyVaultUrl: "https://primary-vault.vault.azure.net",
useDefaultCred: true,
makeDefault: true
});
factory.registerVault({
name: "secondary",
keyVaultUrl: "https://secondary-vault.vault.azure.net",
tenantId: "tenant-id",
clientId: "client-id",
clientSecret: "client-secret"
});
const secret1 = await factory.loadSecretFromVault("primary", "secret-name");
const secret2 = await factory.loadSecretFromVault("secondary", "secret-name");4. Create Secrets
The new SDK supports creating secrets (not just reading):
const kv = KeyVaultManager.getInstance();
await kv.createSecret("new-secret", "secret-value");Quick migration example
- import { KeyVaultManager } from "cemiar-keyvault";
+ import { KeyVaultManager } from "@cemiar/keyvault-sdk";
- const kv = new KeyVaultManager(
- process.env.KEYVAULT_URL,
- process.env.CLIENT_ID,
- process.env.CLIENT_SECRET
- );
+ KeyVaultManager.initialize({
+ keyVaultUrl: process.env.KEYVAULT_URL!,
+ tenantId: process.env.TENANT_ID!,
+ clientId: process.env.CLIENT_ID!,
+ clientSecret: process.env.CLIENT_SECRET!
+ });
+ const kv = KeyVaultManager.getInstance();
- const dbPassword = await kv.getSecret("database-password");
+ const dbPassword = await kv.loadSecret("database-password");Install and test
npm install
npm run buildLicense
ISC
