evnx CLI
A comprehensive CLI tool for managing .env files — validation, secret scanning, format conversion, and migration to cloud secret managers.
📚 Documentation | 🌐 Website
Why evnx?
I built this after accidentally pushing AWS credentials to GitHub in a test file during an Airflow refactor (20 DAGs, 300+ Scrapy spiders). The key was revoked immediately, other services went down, and I had to explain the incident to my development head. That conversation was more painful than any billing alert.
Three years later, I'm still paranoid about secrets management. This tool is the safety net I wish I'd had.
✨ Features
All features are production-ready and working in v0.1.0!
Core Commands (Always Available)
- ✅
init- Interactive project setup with templates for Python, Node.js, Rust, Go, PHP - ✅
validate- Comprehensive validation (checks for placeholders, weak secrets, misconfigurations) - ✅
scan- Secret detection using pattern matching and entropy analysis - ✅
diff- Compare.envand.env.example, show missing/extra variables - ✅
convert- Transform to 14+ formats (JSON, YAML, Docker, Kubernetes, AWS, GCP, Azure, GitHub Actions, and more) - ✅
sync- Keep.envand.env.examplein sync (bidirectional)
Extended Commands (With Features)
- ✅
migrate- Direct migration to secret managers (GitHub Actions, AWS Secrets Manager, Doppler, Infisical) - ✅
doctor- Diagnose common setup issues - ✅
template- Generate config files from templates with variable substitution - ✅
backup- Create AES-256-GCM encrypted backups - ✅
restore- Restore from encrypted backups
Build with all features:
# or
🚀 Quick Start
Installation
macOS / Linux
|
From source
# Install with core features only
# Install with all features
Verify
Basic Usage
# 1. Initialize a new project
# 2. Validate your configuration
# 3. Scan for accidentally committed secrets
# 4. Compare files
# 5. Convert to different formats
# 6. Keep files in sync
📖 Documentation
- Getting Started Guide - Complete walkthrough with examples
- Use Cases - Real-world scenarios
- CI/CD Integration - GitLab, GitHub Actions, Jenkins
- Architecture - System design and internals
- Contributing - How to contribute
🎯 Command Overview
evnx init
Interactive project setup - Generates .env.example with sensible defaults.
Supported stacks: Python, Node.js, Rust, Go, PHP
Supported services: PostgreSQL, Redis, MongoDB, MySQL, RabbitMQ, Elasticsearch, AWS S3, Stripe, SendGrid, OpenAI, and more
evnx validate
Comprehensive validation - Catches misconfigurations before deployment.
Detects:
- ❌ Missing required variables
- ❌ Placeholder values (
YOUR_KEY_HERE,CHANGE_ME) - ❌ Boolean string trap (
DEBUG="False"is truthy!) - ❌ Weak
SECRET_KEY(too short, common patterns) - ❌
localhostin production - ❌ Suspicious port numbers
evnx scan
Secret detection - Find accidentally committed credentials.
Detects 8+ secret types:
- AWS Access Keys (
AKIA...) - Stripe API Keys (live & test)
- GitHub Personal Access Tokens
- OpenAI API Keys
- Anthropic API Keys
- Private Keys (RSA, EC, OpenSSH)
- High-entropy strings (potential secrets)
- Generic API keys
SARIF output integrates with GitHub Security tab!
evnx diff
File comparison - See what's different between environments.
evnx convert
Format conversion - Transform to 14+ output formats.
Advanced options:
Real-world example - Deploy to AWS:
| \
evnx sync
Bidirectional sync - Keep .env and .env.example aligned.
# Forward: .env → .env.example (document what you have)
# Reverse: .env.example → .env (generate from template)
Use cases:
- Generate
.envfrom.env.examplein CI/CD - Update
.env.examplewhen adding new variables - Maintain documentation
evnx migrate (Requires --features migrate)
Cloud migration - Move secrets directly to secret managers.
# GitHub Actions Secrets
# AWS Secrets Manager
# Doppler
Features:
- ✅ Conflict detection (skip or overwrite)
- ✅ Dry-run mode
- ✅ Progress tracking
- ✅ Encrypted uploads (GitHub uses libsodium)
evnx doctor
Health check - Diagnose common issues.
Checks:
- ✅
.envexists and has secure permissions - ✅
.envis in.gitignore - ✅
.env.exampleexists and is tracked by Git - ✅ Project structure detection (Python, Node.js, Rust, Docker)
evnx template
Template generation - Dynamic config file creation.
Supports filters:
# config.template.yml
database:
host:
port:
ssl:
name:
evnx backup/restore (Requires --features backup)
Encrypted backups - AES-256-GCM encryption with Argon2 key derivation.
# Create backup
# Restore
Security:
- AES-256-GCM encryption
- Argon2 password hashing
- No secrets in plaintext
🔧 CI/CD Integration
GitHub Actions
name: Validate Environment
on:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install evnx
run: |
curl -sSL https://raw.githubusercontent.com/urwithajit9/evnx/main/install.sh | bash
- name: Validate configuration
run: evnx validate --strict --format github-actions
- name: Scan for secrets
run: evnx scan --format sarif > scan-results.sarif
- name: Upload SARIF to GitHub Security
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: scan-results.sarif
GitLab CI
validate-env:
stage: validate
image: alpine:latest
before_script:
- apk add --no-cache curl bash
- curl -sSL https://install.dotenv.space | bash
script:
- evnx validate --strict --format json
- evnx scan --format sarif > scan.sarif
artifacts:
reports:
sast: scan.sarif
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: dotenv-validate
name: Validate .env files
entry: evnx validate --strict
language: system
pass_filenames: false
- id: dotenv-scan
name: Scan for secrets
entry: evnx scan --exit-zero
language: system
pass_filenames: false
⚙️ Configuration
Store preferences in .evnx.toml:
[]
= ".env"
= ".env.example"
= false
[]
= true
= false
= "pretty"
[]
= true
= ["*.example", "*.sample", "*.template"]
= "pretty"
[]
= "json"
= false
[]
= "github-actions"
= "kubernetes"
= "terraform"
🏗️ Development
# Clone repository
# Build (core features only)
# Build with all features
# Run tests
# Run with features
# Lint and format
Feature Flags
# Cargo.toml features
[]
= []
= ["reqwest", "base64", "indicatif"]
= ["aes-gcm", "argon2", "rand"]
= ["migrate", "backup"]
Why feature flags?
- Smaller binary size for basic usage
- Optional dependencies (reqwest, crypto libraries)
- Faster compilation during development
🤝 Contributing
Contributions welcome! See CONTRIBUTING.md.
Areas where help is appreciated:
- Additional format converters
- Secret pattern improvements
- Windows support
- Documentation improvements
- Integration examples
- Translation (i18n)
📜 License
MIT License - see LICENSE
🙏 Credits
Built by Ajit Kumar after learning the hard way about secrets management.
Inspired by:
- Countless developers who've accidentally committed secrets
- The pain of production incidents caused by misconfiguration
- The desire for better developer tooling
Related Projects:
- python-dotenv - Python implementation
- dotenvy - Rust dotenv parser
- direnv - Environment switcher
- git-secrets - AWS secret scanning
🆘 Support
⭐ Show Your Support
If this tool saved you from a secrets incident or made your life easier, please:
- ⭐ Star the repository
- 🐦 Tweet about it
- 📝 Write a blog post
- 💬 Tell your teammates
Your support helps improve the tool for everyone!
Made with 🦀 Rust and ❤️ by developers who've been there