mirror of https://github.com/buster-so/buster.git
141 lines
3.4 KiB
Markdown
141 lines
3.4 KiB
Markdown
|
# @buster/secrets
|
||
|
|
||
|
Centralized secrets management for the Buster monorepo using Infisical with local `.env` fallback support.
|
||
|
|
||
|
## Features
|
||
|
|
||
|
- **Priority-based secret resolution**: `.env` file → Infisical (real-time fetch)
|
||
|
- **Real-time fetching**: Always gets the latest secret values from Infisical
|
||
|
- **Lazy initialization**: Only connects to Infisical when needed
|
||
|
- **Automatic .env loading**: Loads from monorepo root automatically
|
||
|
- **Backward compatible**: Works with existing `.env` files
|
||
|
- **Type-safe**: Full TypeScript support
|
||
|
|
||
|
## Installation
|
||
|
|
||
|
```bash
|
||
|
pnpm add @buster/secrets
|
||
|
```
|
||
|
|
||
|
## Usage
|
||
|
|
||
|
### Basic Usage
|
||
|
|
||
|
```typescript
|
||
|
import { getSecret } from '@buster/secrets';
|
||
|
|
||
|
// Replace process.env calls
|
||
|
const apiKey = await getSecret('API_KEY');
|
||
|
const dbUrl = await getSecret('DATABASE_URL');
|
||
|
```
|
||
|
|
||
|
### Synchronous Usage (Limited)
|
||
|
|
||
|
```typescript
|
||
|
import { getSecretSync } from '@buster/secrets';
|
||
|
|
||
|
// Only works with .env values or pre-loaded Infisical secrets
|
||
|
const apiKey = getSecretSync('API_KEY');
|
||
|
```
|
||
|
|
||
|
### Preload Secrets at Startup
|
||
|
|
||
|
```typescript
|
||
|
import { preloadSecrets } from '@buster/secrets';
|
||
|
|
||
|
// Load all secrets at app startup
|
||
|
await preloadSecrets();
|
||
|
|
||
|
// Now getSecretSync will work for all secrets
|
||
|
const apiKey = getSecretSync('API_KEY');
|
||
|
```
|
||
|
|
||
|
## Configuration
|
||
|
|
||
|
### Local Development with .env
|
||
|
|
||
|
No configuration needed! Just use your existing `.env` file at the monorepo root.
|
||
|
|
||
|
### Using Infisical
|
||
|
|
||
|
Set these environment variables to enable Infisical:
|
||
|
|
||
|
```bash
|
||
|
# Required
|
||
|
INFISICAL_CLIENT_ID=your-client-id
|
||
|
INFISICAL_CLIENT_SECRET=your-client-secret
|
||
|
INFISICAL_PROJECT_ID=your-project-id
|
||
|
|
||
|
# Optional (defaults to 'development')
|
||
|
INFISICAL_ENVIRONMENT=development|staging|production
|
||
|
|
||
|
# Optional (for self-hosted Infisical)
|
||
|
INFISICAL_SITE_URL=https://your-infisical-instance.com
|
||
|
```
|
||
|
|
||
|
## Migration Guide
|
||
|
|
||
|
### Before (using process.env)
|
||
|
|
||
|
```typescript
|
||
|
export function getGitHubAppCredentials() {
|
||
|
const appId = process.env.GITHUB_APP_ID;
|
||
|
if (!appId) {
|
||
|
throw new Error('GITHUB_APP_ID not set');
|
||
|
}
|
||
|
return { appId };
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### After (using getSecret)
|
||
|
|
||
|
```typescript
|
||
|
import { getSecret } from '@buster/secrets';
|
||
|
|
||
|
export async function getGitHubAppCredentials() {
|
||
|
const appId = await getSecret('GITHUB_APP_ID');
|
||
|
return { appId };
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## How It Works
|
||
|
|
||
|
1. **Environment Variables**: First checks `process.env` (includes `.env` file values)
|
||
|
2. **Infisical**: If not found locally, fetches from Infisical in real-time (if configured)
|
||
|
3. **Error**: Throws if secret not found anywhere
|
||
|
|
||
|
No caching - always gets the latest values!
|
||
|
|
||
|
## Testing
|
||
|
|
||
|
For testing, you can create a custom instance:
|
||
|
|
||
|
```typescript
|
||
|
import { createSecretManager } from '@buster/secrets';
|
||
|
|
||
|
const testManager = createSecretManager({
|
||
|
environment: 'test',
|
||
|
clientId: 'test-client',
|
||
|
clientSecret: 'test-secret',
|
||
|
projectId: 'test-project'
|
||
|
});
|
||
|
|
||
|
const secret = await testManager.getSecret('TEST_SECRET');
|
||
|
```
|
||
|
|
||
|
## Best Practices
|
||
|
|
||
|
1. **Use async `getSecret()` by default** - It handles all cases
|
||
|
2. **Preload at startup** - Call `preloadSecrets()` in your app initialization
|
||
|
3. **Keep .env for local dev** - Easier for developers, no Infisical setup needed
|
||
|
4. **Use Infisical in CI/Production** - Centralized secrets management
|
||
|
|
||
|
## Environment Priority
|
||
|
|
||
|
The package respects this priority order:
|
||
|
|
||
|
1. **Memory cache** (fastest)
|
||
|
2. **process.env / .env file** (local override)
|
||
|
3. **Infisical** (centralized source)
|
||
|
|
||
|
This allows developers to override any Infisical secret locally by setting it in their `.env` file.
|