@aletheia-js/node
v0.1.1
Published
Annotation-driven secret & configuration library for Node.js/TypeScript
Maintainers
Readme
Aletheia Node.js
___ __ __ _______ __ __ .___________. ______ .__ __.
/ \ | | | | | \ | | | | | | / __ \ | \ | |
/ ^ \ | | | | | .--. || | | | `---| |----`| | | | | \| |
/ /_\ \ | | | | | | | || | | | | | | | | | | . ` |
/ _____ \ | `--' | | '--' || `--. | | | | | `--' | | |\ |
/__/ \__\ \______/ |_______/ |______||__| |__| \______/ |__| \__|
Node.js & TypeScript EditionAnnotation-driven secret & configuration library for Node.js/TypeScript
Author: Mwangii K.
Aletheia provides a simple, elegant way to manage secrets and configuration in Node.js applications. It supports multiple secret providers (Environment Variables, Files, AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault) with automatic caching and decorator-based injection.
Features
- 🔐 Multiple Providers: Environment Variables, Files, AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault
- 💉 Decorator-Based Injection: Use
@Secretdecorator for automatic secret injection - 🔄 Provider Chain: Configure multiple providers with automatic fallback
- ⚡ Caching: Built-in TTL-based caching to reduce API calls
- 🛡️ Type-Safe: Full TypeScript support
- 🧵 Async/Await: Modern async API
- 🔍 Circular Reference Detection: Prevents infinite loops
- 📚 Comprehensive Documentation: See Wiki for detailed guides
Installation
npm install @aletheia/nodeOptional Peer Dependencies
For cloud providers, install the corresponding SDK:
# AWS Secrets Manager
npm install @aws-sdk/client-secrets-manager
# Google Cloud Secret Manager
npm install @google-cloud/secret-manager
# HashiCorp Vault
npm install node-vaultFor framework integrations, install the corresponding packages:
# Express.js integration
npm install express @types/express
# NestJS integration
npm install @nestjs/common @nestjs/coreQuick Start
1. Initialize Aletheia
import { Aletheia } from '@aletheia/node';
await Aletheia.initialize({
providers: ['ENV', 'FILE'],
file: { path: './secrets.json' }
});2. Get Secrets
import { Aletheia } from '@aletheia/node';
const secret = await Aletheia.getSecret('DATABASE_PASSWORD');
console.log(secret);3. Use Decorators
import { Aletheia, Secret } from '@aletheia/node';
class DatabaseConfig {
@Secret('DATABASE_URL')
private url!: string;
@Secret({ value: 'DATABASE_PASSWORD', required: true })
private password!: string;
async init() {
await Aletheia.injectSecrets(this);
}
}
const config = new DatabaseConfig();
await config.init();Providers
Environment Variables
await Aletheia.initialize({ providers: ['ENV'] });
// Reads from process.envFile Provider
await Aletheia.initialize({
providers: ['FILE'],
file: { path: './secrets.json' }
});secrets.json:
{
"DATABASE_PASSWORD": "secret123",
"API_KEY": "key456"
}AWS Secrets Manager
await Aletheia.initialize({
providers: ['AWS'],
aws: {
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
}
});Google Cloud Secret Manager
await Aletheia.initialize({
providers: ['GCP'],
gcp: {
projectId: 'my-project-id',
credentialsPath: process.env.GOOGLE_APPLICATION_CREDENTIALS
}
});HashiCorp Vault
await Aletheia.initialize({
providers: ['VAULT'],
vault: {
url: 'http://vault:8200',
token: process.env.VAULT_TOKEN,
path: 'secret/data/myapp'
}
});Configuration via Environment Variables
# Provider order (comma-separated)
export ALETHEIA_PROVIDERS=ENV,FILE,AWS
# Cache TTL in seconds
export ALETHEIA_CACHE_TTL=3600
# File provider
export FILE_PATH=./secrets.json
# AWS provider
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=your-key
export AWS_SECRET_ACCESS_KEY=your-secret
# GCP provider
export GCP_PROJECT_ID=my-project
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
# Vault provider
export VAULT_URL=http://vault:8200
export VAULT_TOKEN=your-token
export VAULT_PATH=secret/data/myappAdvanced Usage
Provider Chain
Configure multiple providers with automatic fallback:
await Aletheia.initialize({
providers: ['VAULT', 'AWS', 'FILE', 'ENV']
});Aletheia will try each provider in order until a secret is found.
Caching
All providers are automatically wrapped in a cache:
await Aletheia.initialize({
providers: ['AWS'],
cacheTtl: 3600 // 1 hour cache
});Custom Providers
import { SecretProvider, CachedProvider } from '@aletheia/node';
class MyCustomProvider implements SecretProvider {
async getSecret(key: string): Promise<string | null> {
// Your logic here
return null;
}
supports(key: string): boolean {
return true;
}
}
const cached = new CachedProvider(new MyCustomProvider(), 3600);Framework Integration
Express.js
import express from 'express';
import { aletheia } from '@aletheia/node/express';
const app = express();
app.use(aletheia({ providers: ['ENV'] }));
app.get('/api/config', async (req, res) => {
const secret = await req.aletheia?.getSecret('API_KEY');
res.json({ apiKey: secret });
});See Express Integration Guide for details.
NestJS
import { Module } from '@nestjs/common';
import { Injectable, OnModuleInit } from '@nestjs/common';
import { AletheiaModule, AletheiaConfig, Secret } from '@aletheia/node/nestjs';
@Module({
imports: [AletheiaModule.forRoot({ providers: ['ENV'] })],
})
export class AppModule {}
@Injectable()
export class ConfigService extends AletheiaConfig implements OnModuleInit {
@Secret('DATABASE_URL')
databaseUrl!: string;
async onModuleInit() {
await super.onModuleInit(); // Automatically injects secrets
}
}See NestJS Integration Guide for details.
Documentation
Comprehensive documentation is available in the Wiki:
- Getting Started - Installation and basic usage
- Providers - Detailed provider documentation
- Secret Injection - Using decorators
- Error Handling - Exception handling guide
- Advanced Usage - Custom providers and patterns
- Common Issues - Troubleshooting guide
- Express Integration - Express.js integration
- NestJS Integration - NestJS integration
Error Handling
import { SecretNotFoundException, InvalidSecretKeyException } from '@aletheia/node';
try {
const secret = await Aletheia.getSecret('MY_SECRET');
} catch (error) {
if (error instanceof SecretNotFoundException) {
console.error('Secret not found:', error.key);
} else if (error instanceof InvalidSecretKeyException) {
console.error('Invalid key:', error.message);
}
}TypeScript Support
Full TypeScript support with type safety:
import { Aletheia, Secret } from '@aletheia/node';
class Config {
@Secret('DATABASE_URL')
private databaseUrl!: string; // Type-safe
async init() {
await Aletheia.injectSecrets(this);
}
}Requirements
- Node.js >= 18.0.0
- TypeScript >= 4.0 (optional but recommended)
Optional Framework Dependencies
For framework integrations, install the corresponding packages:
# For Express.js
npm install express @types/express
# For NestJS
npm install @nestjs/common @nestjs/coreLicense
Apache License 2.0 - see LICENSE file for details.
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
Status
✅ Production Ready - Core features are complete and tested. Framework integrations are available for Express.js and NestJS.
Related Projects
- Aletheia Java - Java version of Aletheia with Spring Boot and Quarkus support
Made with ❤️ by Mwangii K.
