@multisystemsuite/secure-env
v0.0.9
Published
Lightweight secret protection for Git — scan, encrypt, validate, and decrypt .env files across monorepos
Maintainers
Readme
@multisystemsuite/secure-env
Prevent secrets from being committed, pushed, leaked, or misconfigured in Git — while keeping an excellent developer experience.
Inspired by Mozilla SOPS, git-crypt, dotenvx, and AWS Secrets Manager — but lightweight and easy to adopt.
Table of Contents
- Vision (V1)
- Quick Start
- Installation
- Zero-Config Setup
- Git Workflow
- Encryption Format
- Repository Scanning
- Monorepo Support
- CLI Reference
- npm Scripts
- Runtime API
- Sync Runtime (dotenv + Zod)
- Framework Integration
- Docker Support
- Kubernetes / ECS / EKS
- AWS Integration
- CI/CD Integration
- Configuration
- Key Management
- Audit Logs
- Key Rotation
- Validation
- Plaintext Protection
- Generated Files
- Advanced Features
- Programmatic API
- Troubleshooting
- Project Structure
- Success Criteria
- Roadmap
- Development
- License
Vision (V1)
What V1 Does
| Feature | Description |
|---------|-------------|
| Repository-wide .env scanning | Finds every env file in monorepos |
| AES-256-GCM encryption | Per-variable ENC(...) with PBKDF2 + random IV |
| Runtime decryption | Service-aware loaders for Node.js apps |
| Git hooks | Husky pre-commit encrypt + pre-push validate |
| Docker support | SECURE_ENV_KEY at container runtime |
| AWS Secrets Manager | Cloud key provider |
| AWS KMS | Cloud key provider |
| Validation | Plaintext detection, integrity checks |
| Key rotation | Re-encrypt with new key, preserve old version |
| Audit logs | .secure-env-audit.log |
What V1 Does Not Include (Future Versions)
Compliance engines, security dashboards, VS Code extensions, analytics platforms, and enterprise governance systems are planned for later releases — not required to protect your secrets today.
Quick Start
npm install @multisystemsuite/secure-env
npx secure-env init
git add .
git commit -m "update"
git pushThat's it. Secrets are encrypted on commit and validated on push automatically.
Production: set SECURE_ENV_KEY in Docker, Kubernetes, or CI — never commit secure-env.key.
Installation
npm install @multisystemsuite/secure-envRequirements: Node.js 18+
Zero-Config Setup
npx secure-env initWhat init Does Automatically
| Step | Action |
|------|--------|
| ✓ | Creates .secure-env.json |
| ✓ | Generates secure-env.key (local dev key) |
| ✓ | Installs Husky |
| ✓ | Creates .husky/pre-commit |
| ✓ | Creates .husky/pre-push |
| ✓ | Updates .gitignore |
| ✓ | Adds secure:* scripts to package.json |
| ✓ | Scans repository for .env* files |
Options
npx secure-env init --force # Overwrite existing config
npx secure-env init --interactive # Interactive setup wizard
npx secure-env init --no-install-hooks # Skip HuskyGenerated .gitignore Entries
After init, these are added automatically:
secure-env.key
secure-env.key.*
.secure-env-audit.log
.secure-env-backups/
.secure-env-incident-report.txt
.secure-env-lockdown.json
.env
.env.local
.env.production
.env.development
.env.staging
.env.qa
.env.uat
.env.testEncrypted
.envfiles are committed (values areENC(...)). Plaintext copies above are gitignored.
Git Workflow
Use Git normally. No manual encryption steps.
git add .
git commit -m "feature"
git pushPre-Commit (auto-generated)
#!/bin/sh
npx secure-env encrypt --all || exit 1
git add .
npx secure-env validate || exit 1On every commit:
- Scan repository for
.env*files - Encrypt all plaintext values →
ENC(...) - Stage encrypted files
- Validate — abort commit if errors remain
Pre-Push (auto-generated)
#!/bin/sh
npx secure-env validate --strict || exit 1On every push:
- Validate repository encryption
- Detect plaintext secrets
- Verify integrity
- Block push if validation fails
Encryption Format
Variable names stay visible. Only values are encrypted.
# Before
DB_PASSWORD=password123
# After
DB_PASSWORD=ENC(eyJ2IjoxLCJrdiI6MS...)| Property | Value | |----------|-------| | Algorithm | AES-256-GCM | | Key derivation | PBKDF2 (per variable) | | IV | Random per secret | | Authentication | GCM auth tag | | Integrity | Validation on decrypt |
Repository Scanning
Detected Files
.env .env.local .env.development .env.production
.env.staging .env.qa .env.uat .env.test .env.*Scanned Directories
apps/ services/ packages/ libs/ modules/Example Layout
repo/
├── .env
├── apps/admin/.env
├── apps/qc/.env
├── services/auth/.env
├── services/api/.env
└── packages/sharedlib/.envIgnored
node_modules .git dist build coverage .next .cache out .turbo .nxnpx secure-env scanMonorepo Support
Automatically detects monorepo tooling:
| Tool | Detection File |
|------|------------------|
| Nx | nx.json |
| Turborepo | turbo.json |
| Lerna | lerna.json |
| PNPM Workspaces | pnpm-workspace.yaml |
| Yarn Workspaces | package.json → workspaces |
Service directories (configurable in .secure-env.json):
apps/ services/ packages/ libs/ modules/Each service loads only its own env files at runtime — not the entire monorepo.
CLI Reference
Core Commands (V1)
| Command | Description |
|---------|-------------|
| secure-env init | Initialize project |
| secure-env scan | Scan for env files |
| secure-env encrypt | Encrypt plaintext values |
| secure-env decrypt | Decrypt (local dev) |
| secure-env validate | Validate encryption |
| secure-env rotate | Rotate key + re-encrypt |
| secure-env report | Security report |
| secure-env doctor | Diagnose setup |
| secure-env hooks install | Install Git hooks |
| secure-env hooks uninstall | Remove Git hooks |
Advanced Commands
| Command | Description |
|---------|-------------|
| secure-env rollback | Restore from .secure-env-backups/ |
| secure-env impact | Show affected services from env changes |
| secure-env lockdown | Emergency disable decryption |
| secure-env vscode | Generate VS Code settings |
Command Options
# init
npx secure-env init --force --interactive --no-install-hooks
# encrypt
npx secure-env encrypt --all # Encrypt entire repo (hook default)
npx secure-env encrypt --dry-run # Preview without writing
npx secure-env encrypt --stage # git add encrypted files
npx secure-env encrypt --verbose # Verbose logging
npx secure-env encrypt -r ./path # Custom root directory
# decrypt
npx secure-env decrypt --dry-run
npx secure-env decrypt --stdout # Write to stdout
# validate
npx secure-env validate # Standard validation
npx secure-env validate --strict # Strict mode (pre-push hook)
npx secure-env validate --push # Pre-push validation flow
# rotate
npx secure-env rotate --dry-run
# report
npx secure-env report --format json
npx secure-env report -o report.json
npx secure-env report --compliance # Include compliance checks
# rollback
npx secure-env rollback --list
npx secure-env rollback --backup-id <id>
# impact
npx secure-env impact
npx secure-env impact --file services/api/.env
# lockdown
npx secure-env lockdown --reason "incident"
npx secure-env lockdown --deactivate
# doctor
npx secure-env doctor --fixnpm Scripts
After init, these scripts are added to your root package.json:
{
"scripts": {
"secure:init": "npx secure-env init",
"secure:encrypt": "npx secure-env encrypt --all",
"secure:decrypt": "npx secure-env decrypt",
"secure:validate": "npx secure-env validate",
"secure:scan": "npx secure-env scan",
"secure:report": "npx secure-env report",
"secure:doctor": "npx secure-env doctor",
"secure:hooks": "npx secure-env hooks install",
"secure:rollback": "npx secure-env rollback",
"secure:impact": "npx secure-env impact",
"secure:lockdown": "npx secure-env lockdown"
}
}Usage:
npm run secure:encrypt
npm run secure:validate
npm run secure:scan
npm run secure:report
npm run secure:doctor
npm run secure:hooksRuntime API
Import from @multisystemsuite/secure-env:
| Function | Use Case |
|----------|----------|
| loadServiceEnv() | Recommended — async, service-aware |
| loadServiceEnvSync() | Sync — Express, NestJS, ts-node-dev |
| loadAllSecureEnv() | Admin/migration — loads entire repo |
| loadSecureEnv() | Single file |
Service-Aware Loading
Service at services/admin-api loads:
.env (repo root — shared defaults)
services/admin-api/.env
services/admin-api/.env.local
services/admin-api/.env.productionDoes NOT load services/qc-api/.env or apps/admin/.env.
import { loadServiceEnv } from '@multisystemsuite/secure-env';
await loadServiceEnv({ servicePath: process.cwd() });
console.log(process.env.DB_PASSWORD); // decryptedSync Loading (before Zod / dotenv validation)
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync({ servicePath: process.cwd() });
// Now run Zod schema validation...Node Preload Hook (recommended for Express / NestJS)
{
"scripts": {
"dev": "ts-node-dev -r @multisystemsuite/secure-env/register src/index.ts",
"start": "node -r @multisystemsuite/secure-env/register dist/index.js"
}
}Decrypts env before any application code runs.
Package Exports
| Import | Purpose |
|--------|---------|
| @multisystemsuite/secure-env | Core API + CLI |
| @multisystemsuite/secure-env/register | Node -r preload hook |
| @multisystemsuite/secure-env/vite | Vite plugin |
| @multisystemsuite/secure-env/express | Express helper |
| @multisystemsuite/secure-env/react | Create React App / Webpack |
Full Runtime Functions
| Function | Sync/Async | Description |
|----------|------------|-------------|
| loadServiceEnv() | Async | Load + decrypt current service env files |
| loadServiceEnvSync() | Sync | Same as above — use before Zod/dotenv |
| loadAllSecureEnv() | Async | Load entire repo (admin scripts only) |
| loadSecureEnv() | Async | Load a single env file |
| decryptProcessEnvSync() | Sync | Decrypt ENC(...) already in process.env |
| decryptProcessEnvInPlace() | Sync | Low-level in-place decrypt with key |
| hasEncryptedProcessEnv() | Sync | Returns true if any env value is still ENC(...) |
| resolveMasterKeySync() | Sync | Resolve key from env var or file |
Sync Runtime (dotenv + Zod)
If your app uses dotenv + Zod (or any env validator), encrypted values look like ENC(...) in process.env until decrypted. Validation fails unless you decrypt first.
Error you may see
Invalid enum value. Expected 'development', received 'ENC(eyJ2Ijox...)'
Expected number, received nanOption 1 — Node preload hook (recommended)
{
"scripts": {
"dev": "ts-node-dev -r @multisystemsuite/secure-env/register src/index.ts",
"start": "node -r @multisystemsuite/secure-env/register dist/index.js"
}
}Option 2 — Top of env.ts (before Zod)
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync({ servicePath: process.cwd() });
// then dotenv.config() and zod parse...Option 3 — dotenv already loaded ENC(...) values
import { decryptProcessEnvSync } from '@multisystemsuite/secure-env';
decryptProcessEnvSync();Requirements
.secure-env.jsonat repo rootSECURE_ENV_KEYorsecure-env.keyin project root- Cloud providers (AWS KMS, Secrets Manager) require async
await loadServiceEnv()
Framework Integration
Express
import express from 'express';
import { loadExpressEnv } from '@multisystemsuite/secure-env/express';
loadExpressEnv({ servicePath: process.cwd() });
const app = express();
app.listen(process.env.PORT ?? 3000);Or use the preload hook — no code changes in index.ts:
{ "scripts": { "start": "node -r @multisystemsuite/secure-env/register dist/index.js" } }See examples/express/.
NestJS
Option A — preload hook (recommended):
{
"scripts": {
"start:dev": "nest start --watch -e \"node -r @multisystemsuite/secure-env/register\"",
"start:prod": "node -r @multisystemsuite/secure-env/register dist/main.js"
}
}Option B — top of main.ts:
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
loadServiceEnvSync({ servicePath: process.cwd() });
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();With @nestjs/config + Zod: call loadServiceEnvSync() before ConfigModule reads env, or use the preload hook.
Fastify
import Fastify from 'fastify';
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync();
const app = Fastify();
app.listen({ port: Number(process.env.PORT) || 3000 });Node.js / ts-node / ts-node-dev
node -r @multisystemsuite/secure-env/register dist/main.js
ts-node-dev -r @multisystemsuite/secure-env/register src/index.tsVite + React / Vue / Svelte
Use the Vite plugin to decrypt VITE_* variables at build time.
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { secureEnvVitePlugin } from '@multisystemsuite/secure-env/vite';
export default defineConfig({
plugins: [
secureEnvVitePlugin({ servicePath: process.cwd() }),
react(),
],
});// src/App.tsx — works as normal
const apiUrl = import.meta.env.VITE_API_URL;Important: Only put public-safe values in frontend .env files (VITE_API_URL, VITE_APP_NAME). Never put DB_PASSWORD, JWT_SECRET, or API keys in VITE_* variables — they are embedded in the client bundle.
# apps/admin/.env — safe for Vite
VITE_API_URL=https://api.example.com
VITE_APP_NAME=Admin PortalSee examples/vite/.
Create React App (Webpack)
CRA reads REACT_APP_* at build time. Decrypt before webpack runs:
// scripts/load-env.ts
import { injectReactEnv } from '@multisystemsuite/secure-env/react';
injectReactEnv({ prefix: 'REACT_APP_' });{
"scripts": {
"prestart": "node --import tsx scripts/load-env.ts",
"prebuild": "node --import tsx scripts/load-env.ts",
"start": "react-scripts start",
"build": "react-scripts build"
}
}See examples/react/.
Next.js
Server-side secrets (API routes, Server Components, middleware):
// instrumentation.ts (Next.js 13+)
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
export function register() {
loadServiceEnvSync({ servicePath: process.cwd() });
}Or preload hook in package.json:
{
"scripts": {
"dev": "node -r @multisystemsuite/secure-env/register node_modules/next/dist/bin/next dev",
"start": "node -r @multisystemsuite/secure-env/register node_modules/next/dist/bin/next start"
}
}Client-side (NEXT_PUBLIC_*): only public values — same rule as Vite. Never expose server secrets via NEXT_PUBLIC_.
# apps/web/.env.local
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=ENC(...) # server-only, never NEXT_PUBLIC_Nuxt 3
// nuxt.config.ts
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync({ servicePath: process.cwd() });
export default defineNuxtConfig({
runtimeConfig: {
dbPassword: process.env.DB_PASSWORD,
public: {
apiUrl: process.env.NUXT_PUBLIC_API_URL,
},
},
});Use NUXT_PUBLIC_* only for browser-safe values.
Angular
// src/main.ts — before bootstrapApplication
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync();
import { bootstrapApplication } from '@angular/platform-browser';
// ...For build-time public vars, use a pre-build script with injectReactEnv({ prefix: 'NG_APP_' }) if using custom webpack env injection.
Remix
// entry.server.tsx (top of file)
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync();Or use the -r @multisystemsuite/secure-env/register preload in dev/start scripts.
Frontend vs Backend Secrets
| Location | Safe Variables | Never Put Here |
|----------|----------------|----------------|
| services/api/.env | DB_PASSWORD, JWT_SECRET, API_KEY | — |
| apps/admin/.env | VITE_API_URL, VITE_APP_NAME | DB_PASSWORD, JWT_SECRET |
| Docker / K8s | SECURE_ENV_KEY (runtime injection) | Hardcoded keys |
Git hooks encrypt all .env files. Runtime loaders decrypt only the current service. Frontend build plugins decrypt only VITE_* / REACT_APP_* prefixes.
Docker Support
export SECURE_ENV_KEY=$(cat secure-env.key)
docker compose up -ddocker-compose.yml:
services:
api:
build: .
ports:
- "3000:3000"
environment:
NODE_ENV: production
SECURE_ENV_KEY: ${SECURE_ENV_KEY}
volumes:
- ./services/api/.env:/app/services/api/.env:roDockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
ENV NODE_ENV=production
# SECURE_ENV_KEY injected at runtime — never bake into image
CMD ["node", "-r", "@multisystemsuite/secure-env/register", "dist/index.js"]See examples/docker/.
Kubernetes / ECS / EKS
Inject SECURE_ENV_KEY from a Kubernetes Secret or AWS Secrets Manager — never bake the key into the image.
Kubernetes:
apiVersion: v1
kind: Secret
metadata:
name: secure-env-key
type: Opaque
stringData:
SECURE_ENV_KEY: "<your-hex-key>"
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: api
env:
- name: SECURE_ENV_KEY
valueFrom:
secretKeyRef:
name: secure-env-key
key: SECURE_ENV_KEY
- name: NODE_ENV
value: production
command: ["node", "-r", "@multisystemsuite/secure-env/register", "dist/index.js"]ECS / EKS: store SECURE_ENV_KEY in AWS Secrets Manager and inject via task definition secrets block.
Application startup:
import { loadServiceEnvSync } from '@multisystemsuite/secure-env';
loadServiceEnvSync();
await import('./main.js');AWS Integration
Key Resolution Priority
SECURE_ENV_KEYenvironment variablesecure-env.keyfile- AWS Secrets Manager
- AWS KMS
AWS Secrets Manager
{
"provider": "aws-secret-manager",
"providerConfig": {
"secretId": "myorg/secure-env-key",
"region": "ap-south-1"
}
}npm install @aws-sdk/client-secrets-managerSet IAM permissions for secretsmanager:GetSecretValue.
AWS KMS
{
"provider": "aws-kms",
"providerConfig": {
"keyId": "arn:aws:kms:ap-south-1:123456789012:key/abc-123",
"region": "ap-south-1"
}
}Set SECURE_ENV_ENCRYPTED_KEY with the KMS-encrypted master key blob.
npm install @aws-sdk/client-kmsOptional Cloud Providers
Also supported (install optional SDK packages):
| Provider | Config provider value |
|----------|-------------------------|
| AWS SSM Parameter Store | aws-ssm |
| Azure Key Vault | azure-keyvault |
| HashiCorp Vault | vault |
CI/CD Integration
Run validation in CI to catch unencrypted secrets before merge.
GitHub Actions
name: secure-env
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx secure-env validate --strict
env:
SECURE_ENV_KEY: ${{ secrets.SECURE_ENV_KEY }}Template: templates/github-actions/secure-env.yml
GitLab CI
secure-env-validate:
stage: test
script:
- npm ci
- npx secure-env validate --strict
variables:
SECURE_ENV_KEY: $SECURE_ENV_KEYJenkins
stage('Validate Secrets') {
steps {
withCredentials([string(credentialsId: 'secure-env-key', variable: 'SECURE_ENV_KEY')]) {
sh 'npx secure-env validate --strict'
}
}
}AWS CodeBuild
phases:
build:
commands:
- npm ci
- npx secure-env validate --strict
env:
secrets-manager:
SECURE_ENV_KEY: arn:aws:secretsmanager:ap-south-1:123456789:secret:secure-env-keyAWS CodePipeline
Add a CodeBuild step with the same validate --strict command and inject SECURE_ENV_KEY from Secrets Manager.
Bitbucket Pipelines
pipelines:
default:
- step:
name: Validate secrets
script:
- npm ci
- npx secure-env validate --strict
env:
SECURE_ENV_KEY: $SECURE_ENV_KEYAzure DevOps
- script: npx secure-env validate --strict
displayName: Validate encrypted env files
env:
SECURE_ENV_KEY: $(SECURE_ENV_KEY)Templates ship in templates/ (GitHub Actions, GitLab CI, Jenkins).
Configuration
.secure-env.json (generated by init):
{
"version": 1,
"algorithm": "aes-256-gcm",
"provider": "local",
"autoEncrypt": true,
"autoValidate": true,
"gitHooks": true,
"scanMode": "repository",
"runtimeMode": "service",
"keyFile": "secure-env.key",
"envVarName": "SECURE_ENV_KEY",
"rotationDays": 90,
"auditLog": true,
"strictMode": true
}| Field | Description |
|-------|-------------|
| provider | local, aws-secret-manager, aws-kms |
| autoEncrypt | Encrypt on commit via hooks |
| autoValidate | Validate on commit/push |
| gitHooks | Husky hooks enabled |
| scanMode | repository = scan entire repo |
| runtimeMode | service = load only current service |
| envVarName | Production key env var (default SECURE_ENV_KEY) |
| rotationDays | Days before rotation is recommended |
| auditLog | Write .secure-env-audit.log |
Key Management
Local Development
secure-env.key # Generated by init — never commitProduction
export SECURE_ENV_KEY=$(cat secure-env.key)Inject via Docker, Kubernetes Secret, AWS Secrets Manager, or CI secret store.
Audit Logs
When auditLog: true, events are appended to .secure-env-audit.log:
- Encryption / decryption events
- Validation events
- Key rotation events
- Commit blocks
- Push blocks
Each line is JSON:
{"timestamp":"2026-05-30T12:00:00.000Z","action":"encrypt","success":true,"message":"Encrypted 3 vars","filePath":"/app/.env"}Key Rotation
npx secure-env rotate
npx secure-env rotate --dry-run- Generates a new encryption key
- Re-encrypts all secrets with the new key
- Preserves previous key version for backward compatibility
- Updates
keyVersionin config
Validation
npx secure-env validate
npx secure-env validate --strictChecks:
- Plaintext secrets
- Encryption integrity (auth tags, tamper detection)
- Missing keys
- Corrupted payloads
- Invalid configuration
Strict mode is used by the pre-push hook.
Plaintext Protection
When Git hooks are installed:
| Blocked | How |
|---------|-----|
| Plaintext commit | Pre-commit encrypts before commit completes |
| Plaintext push | Pre-push --strict validation blocks push |
| Invalid encryption | Malformed ENC(...) fails validation |
| Missing key | Cannot encrypt/decrypt without valid key |
| Tampered secrets | GCM auth tag + HMAC integrity check on decrypt |
| Frontend server secrets | VITE_DB_PASSWORD etc. blocked in apps/ paths |
Supported Git hosts: GitHub, GitLab, Bitbucket, Azure DevOps, AWS CodeCommit.
Generated Files
| File | Purpose |
|------|---------|
| .secure-env.json | Configuration |
| secure-env.key | Local encryption key (never commit) |
| .secure-env-audit.log | JSON audit trail |
| .secure-env-manifest.json | Encryption manifest (file tracking) |
| .secure-env-backups/ | Snapshots for rollback |
| .husky/pre-commit | Auto-encrypt hook |
| .husky/pre-push | Auto-validate hook |
Advanced Features
Available beyond core V1 (optional):
npx secure-env report # Security score (0–100)
npx secure-env report --compliance # SOC2, HIPAA, GDPR, PCI-DSS checks
npx secure-env rollback --list # List backup snapshots
npx secure-env impact --file path/.env # Monorepo impact analysis
npx secure-env lockdown --reason "..." # Emergency lockdown
npx secure-env vscode # VS Code settingsProgrammatic APIs: computeSecurityScore(), generateComplianceReport(), createBackup(), analyzeImpact(), createAuditBridge() (OpenTelemetry, Datadog, Splunk, CloudWatch, ELK).
Programmatic API
Full exports from @multisystemsuite/secure-env:
// Runtime
import {
loadServiceEnv,
loadServiceEnvSync,
loadAllSecureEnv,
loadSecureEnv,
decryptProcessEnvSync,
hasEncryptedProcessEnv,
} from '@multisystemsuite/secure-env';
// Encryption
import {
encryptRepository,
decryptRepository,
rotateKeys,
encryptEnvValue,
decryptEnvValue,
} from '@multisystemsuite/secure-env';
// Scanning & validation
import {
scanRepository,
scanEnvFiles,
validateRepository,
findPlaintextViolations,
} from '@multisystemsuite/secure-env';
// Config & keys
import {
loadConfig,
saveConfig,
resolveMasterKey,
resolveMasterKeySync,
KeyManager,
} from '@multisystemsuite/secure-env';
// Git hooks
import {
installGitHooks,
runPreCommitHook,
runPrePushHook,
} from '@multisystemsuite/secure-env';
// Utilities
import { findRepoRoot, maskValue, keyFingerprint, AuditLogger } from '@multisystemsuite/secure-env';Framework subpath imports:
import { secureEnvVitePlugin } from '@multisystemsuite/secure-env/vite';
import { loadExpressEnv } from '@multisystemsuite/secure-env/express';
import { injectReactEnv } from '@multisystemsuite/secure-env/react';Troubleshooting
npx secure-env doctor
npx secure-env doctor --fix| Problem | Solution |
|---------|----------|
| Config not found | Run npx secure-env init |
| Cannot resolve key | Set SECURE_ENV_KEY or ensure secure-env.key exists |
| Plaintext on push | Run git commit again or npm run secure:encrypt |
| Hooks not running | Run npx secure-env hooks install |
| Zod sees ENC(...) | Use loadServiceEnvSync() before validation, or -r register |
| PORT is NaN | Decryption did not run before env validation |
| Vite shows undefined for VITE_* | Add secureEnvVitePlugin() to vite.config.ts |
| CRA build missing env | Run injectReactEnv() in prebuild script |
Project Structure
secure-env/
├── src/
│ ├── cli/ # init, encrypt, decrypt, scan, validate, rotate, report, doctor, hooks
│ ├── crypto/ # aes-gcm, pbkdf2, enc-format, key-manager
│ ├── scanners/ # env-scanner, repo-scanner, monorepo-detector
│ ├── loaders/ # loadServiceEnv, loadServiceEnvSync, vite/express/react helpers
│ ├── hooks/ # Husky pre-commit / pre-push
│ ├── providers/ # SECURE_ENV_KEY → file → AWS Secrets Manager → KMS
│ ├── validators/ # integrity, plaintext detection
│ ├── setup/ # zero-config init
│ ├── types/
│ ├── utils/
│ ├── register.ts # Node -r preload hook
│ ├── vite.ts # @multisystemsuite/secure-env/vite
│ ├── express.ts # @multisystemsuite/secure-env/express
│ ├── react.ts # @multisystemsuite/secure-env/react
│ └── index.ts
├── tests/
├── docs/
├── examples/ # express, vite, react, docker, nodejs
├── templates/ # GitHub Actions, GitLab CI, Jenkins
├── bin/
├── package.json
├── tsconfig.json
├── tsup.config.ts
└── README.mdRoadmap
Planned for future versions (not in V1):
- Compliance reporting (SOC2, HIPAA, GDPR)
- Security score dashboards
- VS Code extension
- Multi-team key governance
- OpenTelemetry / Datadog audit export
- Emergency lockdown mode
V1 focuses on one job: keep secrets out of Git.
Success Criteria
After installation, a developer should use Git normally with zero manual encryption steps:
npm install @multisystemsuite/secure-env
npx secure-env init
git add .
git commit -m "update"
git pushWhat happens automatically:
| Step | Action |
|------|--------|
| git commit | Scan → encrypt all .env files → stage → validate |
| git push | Strict validation → block if plaintext or tampered |
| App startup | loadServiceEnvSync() or -r register decrypts at runtime |
| Docker/K8s | SECURE_ENV_KEY injected → secrets decrypt in container |
| CI/CD | validate --strict catches unencrypted secrets before merge |
No extra manual steps required after init.
Development
npm install
npm run build
npm test
npm run lint
npm run publish:public # patch bump + publishLicense
MIT © MultiSystemSuite
