#!/usr/bin/env node
/**
* Test script for Azure Key Vault Secret Manager integration
*
* This script demonstrates how to use the Azure Key Vault secret manager
* and provides examples of secret naming, authentication, and retrieval.
*
* Prerequisites:
* 1. Azure Key Vault created with appropriate secrets
* 2. Service Principal with Key Vault access OR Managed Identity configured
* 3. Environment variables set for authentication
*
* Usage:
* node scripts/test-azure-secrets.js
*
* Environment Variables:
* SECRET_MANAGER_TYPE=azure
* AZURE_KEY_VAULT_URL=https://your-vault.vault.azure.net/
* AZURE_CLIENT_ID=your-app-id (for service principal)
* AZURE_CLIENT_SECRET=your-client-secret (for service principal)
* AZURE_TENANT_ID=your-tenant-id (for service principal)
*/
import { SecretManager } from '../lib/config/secret-manager.js';
/**
* Test Azure Key Vault secret retrieval functionality
*/
async function testAzureSecrets() {
console.log('π§ͺ Testing Azure Key Vault Secret Manager Integration\n');
// Log safe computed values instead of raw env vars to avoid CodeQL warnings
console.log('π Environment Configuration:');
console.log(
` SECRET_MANAGER_TYPE: ${process.env.SECRET_MANAGER_TYPE === 'azure' ? 'azure' : 'NOT SET'}`
);
console.log(` AZURE_KEY_VAULT_URL: ${process.env.AZURE_KEY_VAULT_URL || 'NOT SET'}`);
console.log(` AZURE_CLIENT_ID: ${process.env.AZURE_CLIENT_ID ? '***SET***' : 'NOT SET'}`);
console.log(
` AZURE_CLIENT_SECRET: ${process.env.AZURE_CLIENT_SECRET ? '***SET***' : 'NOT SET'}`
);
console.log(` AZURE_TENANT_ID: ${process.env.AZURE_TENANT_ID || 'NOT SET'}\n`);
if (process.env.SECRET_MANAGER_TYPE !== 'azure') {
console.log('β SECRET_MANAGER_TYPE must be set to "azure" for this test');
console.log(' export SECRET_MANAGER_TYPE="azure"\n');
return;
}
if (!process.env.AZURE_KEY_VAULT_URL) {
console.log('β AZURE_KEY_VAULT_URL is required');
console.log(' export AZURE_KEY_VAULT_URL="https://your-vault.vault.azure.net/"\n');
return;
}
try {
// Initialize the Secret Manager
console.log('π§ Initializing Secret Manager...');
const secretManager = new SecretManager({
secretSource: 'azure',
azureVaultUrl: process.env.AZURE_KEY_VAULT_URL
});
// Test 1: Health Check
console.log('\nπ₯ Testing Azure Key Vault Health Check...');
const health = await secretManager.healthCheck();
console.log(' Health Status:', JSON.stringify(health, null, 2));
if (health.status !== 'healthy') {
console.log(
'β Health check failed. Check your Azure authentication and Key Vault permissions.'
);
return;
}
console.log('β
Azure Key Vault connection healthy');
// Test 2: Secret Name Conversion
console.log('\nπ Testing Secret Name Conversion...');
const testNames = [
'SQL_SERVER_HOST',
'SQL_SERVER_PORT',
'SQL_SERVER_USER',
'SQL_SERVER_PASSWORD',
'CUSTOM_SECRET_NAME'
];
console.log(' Environment Variable β Azure Key Vault Secret Name:');
for (const envName of testNames) {
const azureName = secretManager.convertToAzureSecretName(envName);
console.log(` ${envName} β ${azureName}`);
}
// Test 3: Individual Secret Retrieval
console.log('\nπ Testing Individual Secret Retrieval...');
const testSecrets = ['SQL_SERVER_HOST', 'SQL_SERVER_PORT', 'SQL_SERVER_USER'];
for (const secretName of testSecrets) {
try {
console.log(` Retrieving ${secretName}...`);
const secretValue = await secretManager.getSecret(secretName);
if (secretValue) {
console.log(
` β
${secretName}: Retrieved (${typeof secretValue}, ${secretValue.length} chars)`
);
} else {
console.log(` β οΈ ${secretName}: Not found or empty`);
}
} catch (error) {
console.log(` β ${secretName}: Failed - ${error.message}`);
}
}
// Test 4: Multiple Secrets Retrieval
console.log('\nπ¦ Testing Multiple Secrets Retrieval...');
try {
const multipleSecrets = await secretManager.getSecrets([
'SQL_SERVER_HOST',
'SQL_SERVER_PORT',
'SQL_SERVER_DATABASE',
'SQL_SERVER_USER'
]);
console.log(' Multiple secrets results:');
for (const [name, value] of Object.entries(multipleSecrets)) {
if (value) {
console.log(` β
${name}: Retrieved (${typeof value}, ${value.length} chars)`);
} else {
console.log(` β οΈ ${name}: Not found or empty`);
}
}
} catch (error) {
console.log(` β Multiple secrets retrieval failed: ${error.message}`);
}
// Test 5: Database Configuration
console.log('\nβοΈ Testing Complete Database Configuration...');
try {
const dbConfig = await secretManager.getDatabaseConfig();
const maskedConfig = SecretManager.maskSecrets(dbConfig);
console.log(' Database configuration loaded:');
console.log(' ', JSON.stringify(maskedConfig, null, 4));
console.log(' β
Database configuration retrieved successfully');
} catch (error) {
console.log(` β Database configuration failed: ${error.message}`);
}
// Test 6: Cache Testing
console.log('\nπΎ Testing Secret Caching...');
try {
const startTime = Date.now();
await secretManager.getSecret('SQL_SERVER_HOST');
const firstCallTime = Date.now() - startTime;
const cachedStartTime = Date.now();
await secretManager.getSecret('SQL_SERVER_HOST');
const cachedCallTime = Date.now() - cachedStartTime;
console.log(` First call (fresh): ${firstCallTime}ms`);
console.log(` Second call (cached): ${cachedCallTime}ms`);
if (cachedCallTime < firstCallTime) {
console.log(' β
Caching appears to be working (faster second call)');
} else {
console.log(' β οΈ Caching may not be working as expected');
}
} catch (error) {
console.log(` β Cache testing failed: ${error.message}`);
}
// Test 7: Error Handling
console.log('\nπ¨ Testing Error Handling...');
try {
console.log(' Testing non-existent secret...');
const nonExistentSecret = await secretManager.getSecret('NONEXISTENT_SECRET_NAME');
if (nonExistentSecret === null) {
console.log(' β
Non-existent secret correctly returned null');
} else {
console.log(' β οΈ Non-existent secret returned unexpected value:', nonExistentSecret);
}
} catch (error) {
console.log(` β
Non-existent secret correctly threw error: ${error.message}`);
}
// Test 8: Fallback Testing
console.log('\nπ Testing Environment Variable Fallback...');
try {
// Set a test environment variable
process.env.TEST_FALLBACK_SECRET = 'fallback-value';
const fallbackValue = await secretManager.getSecret('TEST_FALLBACK_SECRET');
if (fallbackValue === 'fallback-value') {
console.log(' β
Environment variable fallback working correctly');
} else {
console.log(' β οΈ Environment variable fallback returned:', fallbackValue);
}
// Clean up
delete process.env.TEST_FALLBACK_SECRET;
} catch (error) {
console.log(` β Fallback testing failed: ${error.message}`);
}
console.log('\nπ Azure Key Vault Secret Manager Test Completed Successfully!');
} catch (error) {
console.error('\nβ Test failed with error:', error);
console.error('Stack trace:', error.stack);
}
}
/**
* Display usage information and examples
*/
function displayUsage() {
console.log(`
π Azure Key Vault Test Script
This script tests the Azure Key Vault integration with comprehensive examples.
π Setup Requirements:
1. Azure Key Vault with secrets:
az keyvault secret set --vault-name "your-vault" --name "SQL-SERVER-HOST" --value "localhost"
az keyvault secret set --vault-name "your-vault" --name "SQL-SERVER-PORT" --value "1433"
az keyvault secret set --vault-name "your-vault" --name "SQL-SERVER-USER" --value "testuser"
2. Environment Variables (Service Principal):
export SECRET_MANAGER_TYPE="azure"
export AZURE_KEY_VAULT_URL="https://your-vault.vault.azure.net/"
export AZURE_CLIENT_ID="your-app-id"
export AZURE_CLIENT_SECRET="your-client-secret"
export AZURE_TENANT_ID="your-tenant-id"
3. Or for Managed Identity (on Azure resources):
export SECRET_MANAGER_TYPE="azure"
export AZURE_KEY_VAULT_URL="https://your-vault.vault.azure.net/"
π― What This Script Tests:
β
Azure authentication and connectivity
β
Secret name conversion (underscores β hyphens)
β
Individual and bulk secret retrieval
β
Database configuration assembly
β
Caching functionality
β
Error handling and fallback behavior
β
Health monitoring
π For detailed setup instructions, see:
docs/AZURE-SECRETS-GUIDE.md
`);
}
// Main execution
if (import.meta.url === `file://${process.argv[1]}`) {
// Check for help argument
if (process.argv.includes('--help') || process.argv.includes('-h')) {
displayUsage();
process.exit(0);
}
// Run the test
testAzureSecrets().catch(error => {
console.error('\nπ₯ Fatal error during test execution:', error);
process.exit(1);
});
}