-
Notifications
You must be signed in to change notification settings - Fork 0
4. Basic Usage Guide
This section guides you through the fundamental steps to integrate NestJS Secrets into your application, load configuration files (with and without secrets), and access your configuration values.
NestJS Secrets loads configuration from YAML or JSON files. You can specify multiple files; they will be merged, with values from later files taking precedence over earlier ones. This is useful for environment-specific overrides.
First, create your configuration file(s). For example, a settings.yaml:
# settings.yaml
application:
name: My Awesome App
port: 3000
database:
host: db.example.com
port: 5432
username: db-user
# This value will be fetched from a secret manager
password: 'arn:aws:ssm:us-east-1:123456789012:parameter/myapplication/dev/api_key' # Example for AWS Parameter Store
featureFlags:
newDashboard: trueIn this example, arn:aws:ssm:us-east-1:123456789012:parameter/myapplication/dev/api_key is a reference to a secret. NestJS Secrets will automatically resolve this to its actual value if a suitable secret provider is configured. The specific reference format depends on the cloud provider (details in Section 4: Using with Cloud Providers).
You can also have environment-specific files, like settings.local.yaml, to override values for local development:
# settings.local.yaml
application:
port: 3001 # Override port for local development
database:
# Override password for local development, perhaps a non-secret or different reference
password: 'localdevpassword'Import and configure SecretsModule in your root AppModule. The forRoot() method initializes the configuration system, loading your files and setting up secret resolution if a provider client is supplied.
If you only need to load and merge local configuration files (YAML/JSON) without resolving any external secrets, you can set up the module like this:
// app.module.ts
import {Module} from '@nestjs/common';
import {SecretsModule} from '@floracodex/nestjs-secrets';
@Module({
imports: [
SecretsModule.forRoot({
// Optional: specify a subdirectory for your config files
// root: './config',
files: ['settings.yaml', 'settings.local.yaml'],
// Makes ConfigService available globally
isGlobal: true,
// Enables caching of configuration values
cache: true
})
// IMPORTANT: Do NOT add ConfigModule.forRoot() here if using SecretsModule.forRoot()
]
})
export class AppModule {
}To resolve secret references (like 'arn:aws:ssm:us-east-1:123456789012:parameter/myapplication/api_key') from cloud providers, you need to provide an initialized SDK client for that provider.
-
Auto-detection (Recommended for built-in providers):
NestJS Secretscan often automatically determine which secret provider to use based on the SDK client you provide.Example for Google Cloud Secret Manager:
// app.module.ts import {Module} from '@nestjs/common'; import {SecretsModule} from '@floracodex/nestjs-secrets'; import {SecretManagerServiceClient} from '@google-cloud/secret-manager'; @Module({ imports: [ SecretsModule.forRoot({ files: ['settings.yaml', 'settings.local.yaml'], isGlobal: true, cache: true, // Provide the SDK client for Google Cloud Secret Manager // The `provider: 'GoogleSecretManagerProvider'` will be inferred client: new SecretManagerServiceClient() }) // Remeber, do NOT add ConfigModule.forRoot() here ] }) export class AppModule { }
-
Explicit Provider Declaration:
You can also explicitly declare the provider name. This can be useful for clarity or if there's any ambiguity.
// app.module.ts import { Module } from '@nestjs/common'; import { SecretsModule } from '@floracodex/nestjs-secrets'; import { SecretManagerServiceClient } from '@google-cloud/secret-manager'; @Module({ imports: [ SecretsModule.forRoot({ files: ['settings.yaml', 'settings.local.yaml'], isGlobal: true, cache: true, provider: 'GoogleSecretManagerProvider', // Explicitly name the provider client: new SecretManagerServiceClient() }) ] }) export class AppModule {}
When you use SecretsModule.forRoot(), it handles the necessary setup of NestJS's configuration system internally, including applying options like isGlobal, cache, ignoreEnvFile, etc., that you might recognize from @nestjs/config. Therefore, you should not also call ConfigModule.forRoot() from @nestjs/config in the same module imports (e.g., your root AppModule). Doing so might lead to conflicts or unexpected behavior with how ConfigService is provided and configured.
If you opt for an advanced setup where you manually use SecretsLoaderService with a factory pattern (covered in the Advanced Usage section), you will then be responsible for setting up ConfigModule.forRoot() yourself.
-
files: An array of configuration file paths to load (e.g.,['settings.yaml', 'settings.dev.yaml']). Later files override earlier ones. -
root(optional): The base directory for configuration files. Defaults to the project root. -
isGlobal(optional, from@nestjs/config): Iftrue,ConfigServiceis available globally without needing to importSecretsModulein other modules. -
cache(optional, from@nestjs/config): Iftrue, resolved configuration (including secrets) is cached for performance. -
client(optional): An initialized SDK client instance for your cloud secret manager (e.g.,new SecretManagerServiceClient()for Google Cloud,new SSMClient()for AWS SSM). If provided, and provider is not a custom instance, the library will attempt to use this client to resolve secrets, often auto-detecting the provider type. -
provider(optional):- Can be a string identifier for a built-in provider (e.g.,
'GoogleSecretManagerProvider','AwsParameterStoreProvider'). Use with aclient. - Can be an instance of a custom secret provider (see Advanced Usage), in which case
clientis typically omitted.
- Can be a string identifier for a built-in provider (e.g.,
If neither a client (for a built-in provider) nor a custom provider instance is supplied, NestJS Secrets will still load and merge your configuration files but will not attempt to resolve any secret reference strings. Specific examples for each supported cloud provider are below.
Once SecretsModule is configured (and typically made global via isGlobal: true), you can inject and use the standard NestJS ConfigService to access your configuration values anywhere in your application. Resolved secret values are available just like any other configuration key.
// any.service.ts
import {Injectable} from '@nestjs/common';
import {ConfigService} from '@nestjs/config';
@Injectable()
export class AnyService {
private dbHost: string;
private dbPassword_resolved: string; // Will contain the actual password if resolved
constructor(private configService: ConfigService) {
// Access simple configuration values
const appName = this.configService.get<string>('application.name');
this.dbHost = this.configService.get<string>('database.host');
// Access a value that was potentially resolved from a secret manager
this.dbPassword_resolved = this.configService.get<string>('database.password');
console.log('Application Name:', appName);
console.log('Database Host:', this.dbHost);
// console.log('Database Password (Resolved):', this.dbPassword_resolved);
// Note: Be cautious logging sensitive values, even in development!
}
getDatabaseConfig() {
return {
host: this.configService.get('database.host'),
port: this.configService.get<number>('database.port'),
username: this.configService.get('database.username'),
password: this.configService.get('database.password') // Already resolved!
};
}
}This approach leverages NestJS's built-in dependency injection and configuration handling, allowing NestJS Secrets to seamlessly provide resolved secrets without changing how you typically access configuration.