secrets-injector v1.1.4
Secrets-Injector
Secrets-Injector is an npm package that simplifies the process of fetching environment variables from AWS Secrets Manager and injecting them into process.env during the build process of a NestJS application. It helps you securely manage and use sensitive configuration data in your application, without having to manually manage environment files.
Table of Contents
Features
- Fetch environment variables from AWS Secrets Manager.
- Inject the secrets directly into
process.envduring the build process. - Seamlessly integrate with NestJS applications.
- Simple, secure, and easy to configure.
Installation
To install secrets-injector, use the following command:
npm i secrets-injector @aws-sdk/client-secrets-managerIf you're having trouble configuring secrets-injector, you can clone the repository and run a sample app:
git clone https://github.com/Anubhavjain786/secrets-injector.git
cd secrets-injector/samples/quick-start
npm install
npm run start:devQuick start
To get started, import AWSSecretsManagerModule into the root AppModule and use the forRoot() method to configure it. This method accepts the object as AWSSecretsManagerModuleOptions, you can also checkout samples
import { Module } from '@nestjs/common';
import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager';
import {
AWSSecretsManagerModule,
AWSSecretsManagerModuleOptions,
} from 'secrets-injector';
import { AppService } from './app.service';
import { AppController } from './app.controller';
import { AWSDBCredentialsService } from './aws-secrets.service';
const AWSSecretsManagerProps: AWSSecretsManagerModuleOptions = {
secretsManager: new SecretsManagerClient({
region: 'ap-south-1',
}),
};
@Module({
imports: [
AWSSecretsManagerModule.forRoot(AWSSecretsManagerProps),
AWSDBCredentialsService,
],
controllers: [AppController],
providers: [AppService, AWSDBCredentialsService],
})
export class AppModule {}Create the Secrets Manager Service
Now we have getSecretsByID method on AWSSecretsService from we can retrive aws secrets using name or ARN
import { Injectable } from '@nestjs/common';
import { AWSSecretsService } from 'secrets-injector';
interface DBCredentials {
host: string;
port: number;
user: string;
password: string;
database: string;
}
@Injectable()
export class AWSDBCredentialsService {
constructor(private readonly secretsRetrieverService: AWSSecretsService) {}
async getDBCredentials(): Promise<DBCredentials> {
return await this.secretsRetrieverService.getSecretsByID<DBCredentials>(
'db-credentials',
); // where db-credentials is the secret id
}
}Set process env variables from aws secrets manager
We also can able to set value on process on starting, which allows us to retrive secrets using process.env or @nest/config module
import { Module } from '@nestjs/common';
import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager';
import {
AWSSecretsManagerModule,
AWSSecretsManagerModuleOptions,
} from 'secrets-injector';
import { AppService } from './app.service';
import { AppController } from './app.controller';
const AWSSecretsManagerProps: AWSSecretsManagerModuleOptions = {
secretsManager: new SecretsManagerClient({
region: 'ap-south-1',
}),
isSetToEnv: true, // set all secrets to env variables which will be available in process.env or @nest/config module
secretsSource: 'test/sm', // OR array or secrets name or ARN [ "db/prod/config" ,"app/prod/config"],
};
@Module({
imports: [AWSSecretsManagerModule.forRoot(AWSSecretsManagerProps)],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Afterward, Aws secrets from provided secretsSource can be access via process.env for @nestjs/config module
Async configuration
Caveats: because the way Nest works, you can't inject dependencies exported from the root module itself (using
exports). If you useforRootAsync()and need to inject a service, that service must be either imported using theimportsoptions or exported from a global module. Maybe you need to asynchronously pass your module options, for example when you need a configuration service. In such case, use theforRootAsync()method, returning an options object from theuseFactorymethod:
import { Module } from '@nestjs/common';
import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager';
import { AWSSecretsManagerModule } from 'secrets-injector';
import { AppService } from './app.service';
import { AppController } from './app.controller';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
AWSSecretsManagerModule.forRootAsync({
useFactory: (configService: ConfigService) => ({
secretsManager: new SecretsManagerClient({
region: configService.get('AWS_REGION'),
}),
isSetToEnv: true, // set all secrets to env variables which will be available in process.env or @nest/config module
secretsSource: [
configService.get('AWS_SECRET_ID'), // name or array of secret names
],
isDebug: configService.get('NODE_ENV') === 'development',
}),
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}The factory might be async, can inject dependencies with inject option and import other modules using the imports option.
Options
Configuration options parameter for AWSSecretsManagerModule is defined as AWSSecretsManagerModuleOptions interface
export interface AWSSecretsManagerModuleOptions {
secretsManager: SecretsManagerClient;
isSetToEnv?: boolean;
secretsArn?: string | string[];
isDebug?: boolean;
}which is available for import from secrets-injector module
import { AWSSecretsManagerModuleOptions } from 'secrets-injector';Contributing
New features and bugfixes are always welcome! In order to contribute to this project, follow a few easy steps:
- Fork this repository and clone it on your machine
- Open the local repository with Visual Studio Code with the remote development feature enabled (install the Remote Development extension)
- Create a branch (e.g.,
my-awesome-feature) and make your changes. - Run the following commands to ensure the code is formatted and passes lint checks:
npm run lint
npm run format
npm run build- Push your changes and open a pull request
Stay in touch
- Author - Anubhav Jain
- Github - Anubhavjain786
- Twitter - @anubhavjain660
License
secrets-injector is is MIT licensed. See Licensed.