genvx
v1.0.1
Published
A simple CLI tool to save and load `.env*` files across projects using a private git repository.
Readme
genvx
A simple CLI tool to save and load .env* files across projects using a private git repository.
Features
- 🔐 Encrypted by default - AES-256-GCM encryption with project-specific keys
- 🔒 Branch isolation - Each project gets its own hashed branch (no cross-project exposure)
- ⬆️⬇️ Explicit transfer - Push or pull
.env*files - ☁️ Private gitstore - Store env files in a private git repository
- 🧹 Clean - Temporary
.genvxfolder is auto-cleaned after operations
Why?
- Share env files across your machines easily
- Backup sensitive env files securely in a private repo
- Encrypted at rest - Files stored with AES-256-GCM encryption
- Minimal clone - Only downloads your project's env files, not everyone's
- Obscure branches - Branch names are SHA256 hashes, hiding which project they belong to
Installation
# Install globally via npm
npm i -g genvx
# Or via bun
bun install -g genvx
# Now you can use genvx anywhere
genvx --helpDevelopment Setup
# Clone the repo
git clone https://github.com/snomiao/genvx.git
cd genvx
# Install dependencies
bun install
# Link globally for system-wide access
bun linkConfiguration
Quick start: genvx setup
The fastest way to configure genvx is the interactive setup command:
genvx setupIt walks you through:
- Where to save - global (
~/.genvx/.env.local), the current project (./.env.local), or a custom directory - Gitstore URL - your private repo (an empty repo is fine; genvx initializes it on first push)
- Encryption key - auto-generates a strong key, or accepts your own
The config file is written with 600 permissions. Non-interactive use:
genvx setup --gitstore=https://github.com/me/envs.git --dir=~/.config/genvx -yIf you save to a custom directory, set GENVX_CONFIG_DIR=<dir> so genvx loads it.
Manual configuration
Required: Encryption Key
Set your encryption key (required for push/pull):
# Via environment variable
export GENVX_KEY="your-secret-encryption-key"
# Or in ~/.genvx/.env.local
echo "GENVX_KEY=your-secret-encryption-key" >> ~/.genvx/.env.localGenerate a strong key:
openssl rand -base64 32Required: Gitstore URL
Set your gitstore (private repo) URL via one of these methods (priority order):
- CLI flag:
--gitstore=<url>(highest priority) - Environment variable:
export GENVX_STORE=<url> - Project
.env.local:GENVX_STORE=<url>(in current directory) - Global config:
~/.genvx/.env.localwithGENVX_STORE=<url>(lowest priority)
Global Configuration
For convenience, set defaults globally:
mkdir -p ~/.genvx
cat >> ~/.genvx/.env.local << 'EOF'
GENVX_STORE=https://github.com/youruser/envs.git
GENVX_KEY=your-secret-encryption-key
EOFUsage
Save env files to gitstore
# Push all .env* files to gitstore (encrypted)
genvx push
# Or use short alias
genvx p
# Push without confirmation prompt
genvx push -yLoad env files from gitstore
# Pull all .env* files from gitstore (decrypts automatically)
genvx pull
# Or use load alias
genvx load
# Pull without confirmation prompt
genvx pull -yPreview changes (dry run)
# Show what would be pushed/pulled
genvx diffShow branch name
# Show the hashed branch name for this project
genvx branch
# Output: env/27b8a763f3dc97f1Disable encryption (not recommended)
# Push without encryption
genvx push --no-encrypt
# Pull without decryption
genvx pull --no-encryptPush and pull are one-way operations. Deletes are not propagated automatically.
How it works
Encryption
- Algorithm: AES-256-GCM (authenticated encryption)
- Key derivation: scrypt with project ID as salt
- Per-project keys: Each project derives a unique key from your master key
- File format:
{iv}:{authTag}:{ciphertext}(hex encoded)
Branch-per-Project Architecture
Each project gets its own isolated branch in your gitstore:
gitstore-repo/
├── branch: env/27b8a763f3dc97f1 → project1's .env.enc files
├── branch: env/9f2c4a8b1e3d7650 → project2's .env.enc files
└── branch: env/a1b2c3d4e5f67890 → project3's .env.enc files- Branch names are SHA256 hashes of
{host}/{owner}/{repo} - Each branch is an orphan branch (no shared history)
- Cloning only fetches the single branch you need
- Files stored as
.env*.enc(encrypted)
Workflow
- Clone Branch:
git clone --single-branch --depth 1 -b env/<hash>(minimal data) - Encrypt/Decrypt: Files encrypted on push, decrypted on pull
- Transfer Files: Copies
.env*.encfiles to/from branch root - Commit/Push: Commits and pushes changes to the branch
- Cleanup: Removes temporary
.genvxdirectory
Security Layers
| Layer | Protection | |-------|------------| | Private repo | Access control | | Branch hashing | Obscures project identity | | AES-256-GCM encryption | Data at rest protection | | Per-project key derivation | Isolation between projects |
Examples
# Configure via environment variables
export [email protected]:yourusername/my-env-store.git
export GENVX_KEY="$(openssl rand -base64 32)"
# Push your env files (encrypted)
genvx push
# On another machine, pull them (decrypted)
genvx pull
# Check which branch this project uses
genvx branch
# Use CLI flag to override gitstore
genvx [email protected]:company/envs.git pushSecurity Notes
- 🔐 Encryption on by default - All files encrypted with AES-256-GCM
- 🔒 Branch isolation - You only see your own project's secrets
- 🔒 Hashed branches - Branch names don't reveal project identity
- ⚠️ Use a private repository for your gitstore
- ⚠️ Keep your GENVX_KEY secret - Anyone with the key can decrypt
- ⚠️ Never commit
.env*files to your project repos
Commands
| Command | Aliases | Description |
|---------|---------|-------------|
| setup | init | Interactively configure gitstore URL and encryption key |
| push | p, save | Push local .env* files to gitstore (encrypted) |
| pull | load | Pull .env* files from gitstore (decrypted) |
| diff | d | Show pending changes (dry run) |
| branch | b | Show hashed branch name for this project |
Options
| Option | Alias | Description |
|--------|-------|-------------|
| --gitstore | -g | Git repository URL for env storage |
| --dir | - | Directory to save config (setup only) |
| --yes | -y | Skip confirmation prompts |
| --no-encrypt | - | Disable encryption (not recommended) |
| --help | -h | Show help |
| --version | -v | Show version |
Development
Built with:
License
MIT
