nestjs-infisical-sdk
Version:
A NestJS module for Infisical Node SDK
306 lines (253 loc) • 10.1 kB
Markdown
<p align="center">
<img src="https://github.com/user-attachments/assets/fe2a0806-fbf0-4540-b5ae-ae18fdc06391" alt="image" width=400px />
</p>
</br>
This library uses the official Infisical SDK. What we’ve done is make the integration with NestJS easier, making your life a lot simpler, It’s written in pure TypeScript, and we’ve fully utilized type safety. you can easily inject the Infisical SDK as a service.
NOTE: This is not a official library!
## Installation
To install the package, run:
### With npm
```bash
npm install nestjs-infisical-sdk
```
### With yarn
```bash
yarn add nestjs-infisical-sdk
```
### With pnpm
```bash
pnpm install nestjs-infisical-sdk
```
### With bun (Not tested yet!)
```bash
bun add nestjs-infisical-sdk
```
## Example .env
```bash
INFISICAL_SITE_URL=https://app.infisical.com #default url
INFISICAL_CLIENT_ID=your-client-id
INFISICAL_CLIENT_SECRET=your-client-secret
INFISICAL_ACCESS_TOKEN=your-access-token
INFISICAL_AWS_IAM_LOGIN=your-aws-iam-identity-id
```
| Property | Type | Description |
| ------------------------ | --------- | --------------------------------------------------------------------------------------------------- |
| `clientId` | `string` | The client ID of your Machine Identity. |
| `clientSecret` | `string` | The client secret of your Machine Identity. |
| `projectId` | `string` | The project ID of your Infisical project. . _(Optional)_ |
| `environment` | `string` | The environment in which to operate (e.g., "dev", "stg", "prod"). _(Optional)_ |
| `siteUrl` | `string` | The site URL for your Infisical instance. Defaults to `"https://app.infisical.com"`. _(Optional)_ |
| `renewToken` | `boolean` | Whether to renew the authentication token that is currently set. _(Optional)_ |
| `setManuallyAccessToken` | `string` | Manually set the access token for authentication. _(Optional)_ |
| `awsIamLogin` | `string` | The ID of your AWS IAM identity for authentication. _(Optional)_ |
| `renewAwsIamToken` | `boolean` | Whether to renew the AWS IAM authentication token that is currently set. _(Optional)_ |
| `injectIntoProcessEnv` | `boolean` | Determines fetched secrets should be injected into `process.env`. Defaults to `false`. _(Optional)_ |
| `watchEnvFile` | `boolean` | Automatically watches your `.env`. file, Default is: `false`. _(Optional)_ |
## Options
```typescript
interface InfisicalOptions {
/**
* The client ID of your Machine Identity.
*/
clientId: string;
/**
* The client secret of your Machine Identity.
*/
clientSecret: string;
/**
* The project ID of your Infisical project.
* Used to fetch secrets from the correct project and inject them into `process.env`.
*/
projectId?: string;
/**
* The environment in which to operate (e.g., "dev", "stg", "prod").
*/
environment?: string;
/**
* The site URL for your Infisical instance. Defaults to "https://app.infisical.com".
*/
siteUrl?: string;
/**
* Whether to renew the authentication token that is currently set.
*/
renewToken?: boolean;
/**
* Manually set the access token for authentication.
*/
setManuallyAccessToken?: string;
/**
* The ID of your AWS IAM identity for authentication.
*/
awsIamLogin?: string;
/**
* Whether to renew the AWS IAM authentication token that is currently set.
*/
renewAwsIamToken?: boolean;
/**
* Determines whether fetched secrets should be injected into `process.env`.
* If `true`, secrets will be automatically set in `process.env`.
* If `false`, secrets will only be returned and not modified.
* Defaults to `false`.
*/
injectIntoProcessEnv?: boolean;
/**
* The path to the environment file to watch for changes.
* Default is ".env".
*/
watchEnvFile?: boolean;
}
```
## Register
```typescript
import { Module } from '@nestjs/common';
import { InfisicalModule } from 'nestjs-infisical-sdk';
@Module({
imports: [
InfisicalModule.register({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
siteUrl: 'https://app.infisical.com', // Optional
environment: 'dev', // Optional
renewToken: true, // Optional
setManuallyAccessToken: 'your-access-token', // Optional
awsIamLogin: 'your-aws-iam-identity-id', // Optional
renewAwsIamToken: true, // Optional,
injectIntoProcessEnv: true, // Optional
watchEnvFile: true //Optional
})
]
})
export class AppModule {}
```
## Async Register
```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { InfisicalModule } from 'nestjs-infisical-sdk';
@Module({
imports: [
ConfigModule.forRoot(),
InfisicalModule.registerAsync({
useFactory: async (configService: ConfigService) => ({
clientId: configService.get<string>('INFISICAL_CLIENT_ID'),
clientSecret: configService.get<string>('INFISICAL_CLIENT_SECRET'),
siteUrl: configService.get<string>('INFISICAL_SITE_URL'), // Optional
environment: configService.get<string>('INFISICAL_ENVIRONMENT'), // Optional
renewToken: false, // Optional
setManuallyAccessToken: configService.get<string>('INFISICAL_ACCESS_TOKEN'), // Optional
awsIamLogin: configService.get<string>('INFISICAL_AWS_IAM_LOGIN'), // Optional
renewAwsIamToken: false, // Optional
injectIntoProcessEnv: true, // Optional
watchEnvFile: true //Optional
}),
inject: [ConfigService]
})
]
})
export class AppModule {}
```
## Inject The Service
```typescript
import { Injectable, Logger } from '@nestjs/common';
import {
CreateDynamicSecretResult,
CreateSecretResult,
DeleteDynamicSecretResult,
DeleteSecretResult,
DynamicSecretProviders,
GetSecretResult,
InfisicalService,
InjectInfisical,
ListSecretsResult,
UpdateSecretResult
} from 'nestjs-infisical-sdk';
@Injectable()
export class AppService {
private readonly logger = new Logger(AppService.name);
constructor(@InjectInfisical() private readonly infiscalService: InfisicalService) {}
public async getSecret(secretName: string): Promise<GetSecretResult> {
this.logger.log(`Getting secret: ${secretName}`);
const secretResponse = await this.infiscalService.secrets().getSecret({
environment: 'dev',
secretName,
projectId: process.env.INFISICAL_PROJECT_ID
});
this.logger.log(`Secret retrieved: ${JSON.stringify(secretResponse)}`);
return secretResponse;
}
public async createSecret(secretName: string, secretValue: string): Promise<CreateSecretResult> {
this.logger.log(`Creating secret: ${secretName}`);
const secret = await this.infiscalService.secrets().createSecret(secretName, {
environment: 'dev',
secretValue,
projectId: process.env.INFISICAL_PROJECT_ID
});
this.logger.log(`Secret created: ${JSON.stringify(secret)}`);
return secret;
}
public async updateSecret(secretName: string, secretValue: string): Promise<UpdateSecretResult> {
this.logger.log(`Updating secret: ${secretName}`);
const secret = await this.infiscalService.secrets().updateSecret(secretName, {
environment: 'dev',
secretValue,
projectId: process.env.INFISICAL_PROJECT_ID
});
this.logger.log(`Secret updated: ${JSON.stringify(secret)}`);
return secret;
}
public async deleteSecret(secretName: string): Promise<DeleteSecretResult> {
this.logger.log(`Deleting secret: ${secretName}`);
const secret = await this.infiscalService.secrets().deleteSecret(secretName, {
environment: 'dev',
projectId: process.env.INFISICAL_PROJECT_ID
});
this.logger.log(`Secret deleted: ${JSON.stringify(secret)}`);
return secret;
}
public async listSecrets(): Promise<ListSecretsResult> {
this.logger.log('Listing secrets');
const secrets = await this.infiscalService.secrets().listSecrets({
environment: 'dev',
projectId: process.env.INFISICAL_PROJECT_ID
});
this.logger.log(`Secrets listed: ${JSON.stringify(secrets)}`);
return secrets;
}
public async createDynamicSecret(): Promise<CreateDynamicSecretResult> {
const createDynamicSecret = await this.infiscalService.dynamicSecrets().create({
provider: {
type: DynamicSecretProviders.Redis,
inputs: {
host: 'localhost',
port: 6379,
username: 'user1',
password: '12345612356',
creationStatement: `ACL SETUSER {{user1}} on >{{123456123456}} ~* &* +@all`,
revocationStatement: `ACL DELUSER {{user1}}`
}
},
defaultTTL: '1h',
environmentSlug: 'dev',
name: 'dynamic-secret-name',
projectSlug: 'project-slug'
});
this.logger.log(`Dynamic secret created: ${JSON.stringify(createDynamicSecret)}`);
return createDynamicSecret;
}
public async deleteDynamicSecret(dynamicSecretName: string): Promise<DeleteDynamicSecretResult> {
const deleteDynamicSecret = await this.infiscalService
.dynamicSecrets()
.delete(dynamicSecretName, {
environmentSlug: 'dev',
projectSlug: 'project-slug'
});
return deleteDynamicSecret;
}
}
```
## Example Nest.js Project
Looking for a working example?
[NestJS Infisical Example](https://github.com/c4nzin/nestjs-infisical-example)
## Contribute
We welcome contributions! Feel free to open an issue or submit a pull request.
For more details, visit the [GitHub repository](https://github.com/c4nzin/nestjs-infisical-sdk).