@biocomputingup/infisical-secrets-loader
v1.0.1
Published
A small library to load secrets from infisical into a JSON shaped object to be injected into your config service. Designed to work with NestJS config module
Readme
Infisical Secrets Loader
A lightweight Node.js library to load secrets from Infisical and transform them into a structured JavaScript object. Designed to work seamlessly with NestJS config modules.
Installation
npm install @biocomputingup/infisical-secrets-loader
# or
yarn add @biocomputingup/infisical-secrets-loaderRequirements: Node.js 20+
Quick Start
import { loadSecretsFromInfisical, LogLevel } from '@biocomputingup/infisical-secrets-loader';
const config = await loadSecretsFromInfisical({
baseUrl: 'https://infisical.example.com',
environment: 'production',
projectId: '550e8400-e29b-41d4-a716-446655440000',
auth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
},
});
console.log(config); // { secret1: 'value1', secret2: 'value2', ... }Configuration
LoadConfig Shape
interface LoadConfig {
// Required
baseUrl: string; // Infisical instance URL (e.g., https://infisical.example.com)
environment: string; // Environment name (e.g., 'development', 'production')
projectId: string; // UUID of your Infisical project
auth: {
clientId: string; // Infisical machine identity client ID
clientSecret: string; // Infisical machine identity client secret
};
// Optional
mode?: 'rootOnly' | 'flat' | 'nested'; // Secret retrieval mode (default: 'rootOnly')
logger?: Logger; // Custom logger (default: console)
logLevel?: 'debug' | 'info' | 'warn' | 'error'; // Log level (default: 'debug')
}Retrieval Modes
Secrets are organized in Infisical using paths. This library offers three modes to transform them:
rootOnly (default)
Returns only secrets in the root directory, ignoring secrets in subfolders.
Infisical:
/API_KEY
/db/HOST
/db/PORT
Result: { API_KEY: '...' }flat
Flattens the entire secret structure into a single-level object. Last secret loaded wins on key collision..
Result: { API_KEY: '...', HOST: '...', PORT: '...' }nested
Preserves the folder structure using nested objects.
Result: {
API_KEY: '...',
db: { HOST: '...', PORT: '...' }
}Error Handling
The library throws typed errors for different failure scenarios:
import {
InfisicalError,
InfisicalAuthError,
InfisicalConfigError,
InfisicalFetchError,
} from '@biocomputingup/infisical-secrets-loader';
try {
const secrets = await loadSecretsFromInfisical(config);
} catch (err) {
if (err instanceof InfisicalAuthError) {
console.error('Authentication failed:', err.message);
} else if (err instanceof InfisicalConfigError) {
console.error('Invalid configuration:', err.details?.errors);
} else if (err instanceof InfisicalFetchError) {
console.error('Failed to fetch secrets:', err.cause);
} else if (err instanceof InfisicalError) {
console.error('Infisical error:', err.code, err.details);
}
}Error Types
- InfisicalAuthError: Authentication with Infisical failed
- InfisicalConfigError: Invalid configuration passed to
loadSecretsFromInfisical - InfisicalFetchError: Failed to fetch secrets from Infisical
- InfisicalParseError: Failed to parse secrets response
All errors extend InfisicalError with properties:
code: Unique error code (e.g., 'INFISICAL_AUTH_ERROR')cause: Original error if availabledetails: Additional context (e.g., validation errors)
Logging
Customize logging behavior by passing a logger and log level:
import { LogLevel } from '@biocomputingup/infisical-secrets-loader';
const secrets = await loadSecretsFromInfisical({
// ... config
logLevel: LogLevel.info,
logger: console, // or your custom logger
});Log Levels: debug, info, warn, error, silent
Custom loggers must implement:
interface Logger {
debug: (message: string, meta?: Record<string, unknown>) => void;
info: (message: string, meta?: Record<string, unknown>) => void;
warn: (message: string, meta?: Record<string, unknown>) => void;
error: (message: string, meta?: Record<string, unknown>) => void;
}NestJS Integration
Use with NestJS ConfigModule:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { loadSecretsFromInfisical } from '@biocomputingup/infisical-secrets-loader';
@Module({
imports: [
ConfigModule.forRoot({
load: [
async () => {
return await loadSecretsFromInfisical({
baseUrl: process.env.INFISICAL_BASE_URL!,
environment: process.env.INFISICAL_ENVIRONMENT!,
projectId: process.env.INFISICAL_PROJECT_ID!,
auth: {
clientId: process.env.INFISICAL_CLIENT_ID!,
clientSecret: process.env.INFISICAL_CLIENT_SECRET!,
},
mode: 'nested',
});
},
],
}),
],
})
export class AppModule {}Exported Types & Utilities
// Main function
export { loadSecretsFromInfisical };
// Error classes
export {
InfisicalError,
InfisicalAuthError,
InfisicalConfigError,
InfisicalFetchError,
InfisicalParseError,
};
// Logger utilities
export { LogLevel, createLogger };
export type { Logger };
// Types
export type { LoadConfig };
export { TRetrievalMode };License
MIT
