npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@phantasm0009/secure-env

v1.0.3

Published

End-to-end secret management with encrypted .env files, git protection, and runtime validation

Readme

@phantasm0009/secure-env

🔐 End-to-end secret management for Node.js applications with encrypted .env files, git protection, and runtime validation.

Features

  • 🔐 Encrypted Environment Files - AES-256-GCM encryption with secure key generation
  • 🛡️ Git Protection - Pre-commit hooks prevent accidental commits of sensitive files
  • Runtime Validation - Zod-like schema validation for environment variables
  • ☁️ Cloud KMS Support - AWS KMS and Google Cloud KMS integration
  • 🚀 Zero Dependencies - Production-ready with Node.js 18+ built-ins
  • 📦 Multiple Formats - Support for .env.local, .env.production, etc.

Installation

npm install @phantasm0009/secure-env

Quick Start

1. Basic Setup

Create a .env file with your secrets:

# .env
API_KEY=your-secret-api-key-here
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
DEBUG=true
PORT=3000

2. Encrypt Your Environment File

# Generate encryption key and encrypt .env
npx secure-env encrypt

# This creates:
# - .env.key (keep this secret!)
# - .env.encrypted (safe to commit)

3. Setup Git Protection

# Install pre-commit hooks and update .gitignore
npx secure-env setup-git

4. Load and Validate in Your Application

const { SecureEnv, envSchema, string, number, boolean } = require('@phantasm0009/secure-env');

// Define validation schema
const schema = envSchema({
  PORT: number().min(3000).max(8000),
  API_KEY: string().length(32),
  DEBUG: boolean(),
  DATABASE_URL: string().regex(/^postgresql:\/\//)
});

// Load and validate environment
const secureEnv = new SecureEnv();
const env = secureEnv.load(schema);

console.log('Validated environment:', env);
// Output: { PORT: 3000, API_KEY: 'your-secret-api-key-here', DEBUG: true, ... }

CLI Commands

Encryption Commands

# Encrypt .env file (creates .env.encrypted and .env.key)
secure-env encrypt

# Encrypt specific file
secure-env encrypt .env.production

# Decrypt to .env
secure-env decrypt

# Decrypt to specific file
secure-env decrypt --output .env.development

# Generate new encryption key
secure-env generate-key

# Use custom key path
secure-env encrypt --key-path ./keys/production.key

Validation Commands

# Check if required variables are present
secure-env check PORT API_KEY DATABASE_URL

# Validate against schema file
secure-env validate schema.js

Git Protection

# Setup git hooks and .gitignore protection
secure-env setup-git

API Reference

SecureEnv Class

const { SecureEnv } = require('@phantasm0009/secure-env');
const secureEnv = new SecureEnv();

// Encryption/Decryption
secureEnv.encryptFile('.env', '.env.encrypted');
secureEnv.decryptFile('.env.encrypted', '.env');

// Key management
const key = secureEnv.generateKey();
secureEnv.saveKey(key, '.env.key');

// Load with validation
const env = secureEnv.load(schema, { override: true });

// Setup git protection
secureEnv.setupGitProtection();

Schema Validation

Build validation schemas with chainable methods:

const { envSchema, string, number, boolean } = require('@phantasm0009/secure-env');

const schema = envSchema({
  // String validation
  API_KEY: string()
    .length(32)                    // Exact length
    .regex(/^[a-zA-Z0-9]+$/)      // Pattern matching
    
  USERNAME: string()
    .min(3)                       // Minimum length
    .max(20),                     // Maximum length
    
  // Number validation  
  PORT: number()
    .min(3000)                    // Minimum value
    .max(8000)                    // Maximum value
    .int(),                       // Must be integer
    
  TIMEOUT: number()
    .min(0),
    
  // Boolean validation
  DEBUG: boolean(),
  ENABLED: boolean()
});

Environment Loading

const { loadEnv } = require('@phantasm0009/secure-env');

// Load with options
const env = loadEnv({
  path: './config',        // Directory to search
  override: true,          // Override existing values
  debug: true             // Log loaded files
});

Manual Validation

const { validateEnv, checkRequired } = require('@phantasm0009/secure-env');

// Validate against schema
const validated = validateEnv(process.env, schema);

// Check required variables
const result = checkRequired(['API_KEY', 'DATABASE_URL']);
if (!result.valid) {
  console.error('Missing:', result.missing);
}

Real-World Examples

Express.js Application

const express = require('express');
const { SecureEnv, envSchema, string, number, boolean } = require('@phantasm0009/secure-env');

// Define schema for your app
const schema = envSchema({
  PORT: number().min(3000).max(8000),
  NODE_ENV: string().regex(/^(development|production|test)$/),
  JWT_SECRET: string().min(32),
  DATABASE_URL: string().regex(/^postgresql:\/\//),
  REDIS_URL: string().regex(/^redis:\/\//),
  DEBUG: boolean()
});

// Load and validate environment
const secureEnv = new SecureEnv();
const env = secureEnv.load(schema);

const app = express();

app.get('/', (req, res) => {
  res.json({ 
    message: 'Server running securely!',
    environment: env.NODE_ENV,
    debug: env.DEBUG 
  });
});

app.listen(env.PORT, () => {
  console.log(`Server running on port ${env.PORT}`);
});

Next.js Application

// next.config.js
const { SecureEnv, envSchema, string, number, boolean } = require('@phantasm0009/secure-env');

const schema = envSchema({
  NEXT_PUBLIC_API_URL: string().regex(/^https?:\/\//),
  DATABASE_URL: string(),
  NEXTAUTH_SECRET: string().min(32),
  NEXTAUTH_URL: string().regex(/^https?:\/\//),
  NODE_ENV: string().regex(/^(development|production|test)$/)
});

const secureEnv = new SecureEnv();
const env = secureEnv.load(schema);

module.exports = {
  env: {
    CUSTOM_KEY: env.NEXT_PUBLIC_API_URL,
  },
  // ... other Next.js config
};

Docker Deployment

# Dockerfile
FROM node:18-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./
RUN npm ci --only=production

# Copy source code
COPY . .

# Decrypt environment file during build
RUN npx secure-env decrypt --output .env

# Start application
CMD ["npm", "start"]
# Build with encrypted env file
docker build -t myapp .

# Or mount key at runtime
docker run -v $(pwd)/.env.key:/app/.env.key myapp

CI/CD Pipeline

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Create encryption key
        run: echo "${{ secrets.ENV_KEY }}" > .env.key
        
      - name: Decrypt environment
        run: npx secure-env decrypt
        
      - name: Run tests
        run: npm test
        
      - name: Deploy
        run: npm run deploy

File Hierarchy

The loader searches for environment files in this order (later files override earlier ones):

  1. .env
  2. .env.local
  3. .env.development / .env.production / .env.test
  4. .env.development.local / .env.production.local / .env.test.local

Security Best Practices

Key Management

# Generate strong keys for different environments
secure-env generate-key --key-path .env.development.key
secure-env generate-key --key-path .env.production.key

# Encrypt environment-specific files
secure-env encrypt .env.development --key-path .env.development.key
secure-env encrypt .env.production --key-path .env.production.key

Git Protection

The git protection feature automatically:

  • Prevents commits of .env* files
  • Prevents commits of *.key files
  • Updates .gitignore with secure patterns
  • Shows helpful error messages when protection is triggered

Production Deployment

For production environments, consider using cloud KMS:

const { createKMSProvider } = require('@phantasm0009/secure-env');

// AWS KMS
const kms = createKMSProvider('aws', {
  region: 'us-east-1',
  keyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
});

// Google Cloud KMS  
const kms = createKMSProvider('google', {
  projectId: 'my-project',
  keyRingId: 'my-keyring',
  keyId: 'my-key'
});

Error Handling

const { SecureEnv } = require('@phantasm0009/secure-env');

try {
  const secureEnv = new SecureEnv();
  const env = secureEnv.load(schema);
  console.log('Environment loaded successfully');
} catch (error) {
  if (error.message.includes('Environment validation failed')) {
    console.error('❌ Configuration errors:');
    console.error(error.message);
    process.exit(1);
  }
  
  if (error.message.includes('Encryption key not found')) {
    console.error('❌ Missing encryption key. Run: npx secure-env generate-key');
    process.exit(1);
  }
  
  throw error;
}

Advanced Usage

Custom Validation Messages

const schema = envSchema({
  EMAIL: string().regex(
    /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
    'Must be a valid email address'
  ),
  
  API_VERSION: string().regex(
    /^v\d+$/,
    'Must be in format v1, v2, etc.'
  ),
  
  PORT: number()
    .min(1024, 'Port must be above 1024')
    .max(65535, 'Port must be below 65535')
});

Multiple Environment Files

// Load specific environment configurations
const devEnv = loadEnv({ 
  path: './environments/development',
  debug: true 
});

const prodEnv = loadEnv({ 
  path: './environments/production',
  override: true 
});

Schema Composition

const baseSchema = envSchema({
  NODE_ENV: string().regex(/^(development|production|test)$/),
  DEBUG: boolean()
});

const databaseSchema = envSchema({
  DATABASE_URL: string().regex(/^postgresql:\/\//),
  DB_POOL_SIZE: number().min(1).max(20)
});

const apiSchema = envSchema({
  API_KEY: string().length(32),
  API_TIMEOUT: number().min(1000)
});

// Combine schemas
const fullSchema = envSchema({
  ...baseSchema,
  ...databaseSchema,
  ...apiSchema
});

Testing

Run the test suite:

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run specific test file
node --test test/encryption.test.js

Troubleshooting

Common Issues

Q: "Encryption key not found" error

# Generate a new key
npx secure-env generate-key

# Or specify custom path
npx secure-env generate-key --key-path ./custom/path/.env.key

Q: Git hooks not working

# Reinstall git hooks
npx secure-env setup-git

# Check if .git/hooks/pre-commit exists and is executable
ls -la .git/hooks/pre-commit

Q: Validation errors

# Check which variables are missing
npx secure-env check API_KEY DATABASE_URL PORT

# Validate against schema file
npx secure-env validate ./config/schema.js

Q: Environment not loading

// Enable debug mode to see which files are loaded
const env = loadEnv({ debug: true });

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Add tests for new functionality
  4. Ensure all tests pass: npm test
  5. Commit changes: git commit -m 'Add amazing feature'
  6. Push to branch: git push origin feature/amazing-feature
  7. Submit a pull request

License

MIT License - see LICENSE file for details.

Security

For security issues, please email [email protected] instead of using GitHub issues.

Changelog

v1.0.0

  • Initial release
  • AES-256-GCM encryption for .env files
  • Git protection with pre-commit hooks
  • Runtime validation with schema system
  • CLI tools for encryption/decryption
  • Cloud KMS integration support
  • Comprehensive test suite