buster/packages/secrets
dal 1dcaaca339
get rid of env and other crap
2025-08-25 00:37:35 -06:00
..
src get rid of env and other crap 2025-08-25 00:37:35 -06:00
.gitignore set up infiscal and remove test and env packages 2025-08-24 22:30:45 -06:00
README.md set up infiscal and remove test and env packages 2025-08-24 22:30:45 -06:00
biome.json set up infiscal and remove test and env packages 2025-08-24 22:30:45 -06:00
package.json set up infiscal and remove test and env packages 2025-08-24 22:30:45 -06:00
tsconfig.json set up infiscal and remove test and env packages 2025-08-24 22:30:45 -06:00
vitest.config.ts feat: migrate AI package from process.env to @buster/secrets 2025-08-24 23:42:12 -06:00

README.md

@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

pnpm add @buster/secrets

Usage

Basic Usage

import { getSecret } from '@buster/secrets';

// Replace process.env calls
const apiKey = await getSecret('API_KEY');
const dbUrl = await getSecret('DATABASE_URL');

Synchronous Usage (Limited)

import { getSecretSync } from '@buster/secrets';

// Only works with .env values or pre-loaded Infisical secrets
const apiKey = getSecretSync('API_KEY');

Preload Secrets at Startup

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:

# 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)

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)

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:

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.