🔐 Envy
Git for your .env files — Enterprise-grade secret management with Zero-Knowledge End-to-End Encryption, profile inheritance, schema validation, and a built-in web dashboard.
Installation • Quick Start • Features • Commands • Architecture • Contributing
📋 Table of Contents
- Why Envy?
- Features Overview
- Tech Stack
- Installation
- Quick Start
- Command Reference
- Zero-Knowledge E2EE Architecture
- Anti-Phishing Protection
- Profile Inheritance
- Schema Validation & Type-Safety
- Log Masking
- Envy Blame
- Pre-commit Hook Integration
- Local Web Dashboard
- Use Cases
- Security Best Practices
- File Structure
- FAQ
- Contributing
- License
💡 Why Envy?
Every development team has the same problem: managing secrets is painful. .env files are plaintext, easy to leak, and impossible to share securely. Existing tools either require a third-party SaaS provider that can read your secrets, or they're so complex they need a dedicated DevOps engineer to set up.
Envy is different. It's a CLI-first tool that works like Git — you initialize it in your project directory, encrypt your secrets locally, and sync them with your team through Envy Cloud. The critical difference is that Envy Cloud never sees your secrets. Every piece of sensitive data is encrypted on your machine before it ever leaves, using the same cryptographic primitives used by Signal and 1Password.
Envy replaces:
- Plaintext
.envfiles ❌ - Shared password vaults with copy-paste workflows ❌
- Third-party secret managers that require you to trust their servers ❌
With:
- AES-256-GCM encrypted local storage ✅
- Zero-Knowledge End-to-End Encryption for cloud sync ✅
- A single CLI command (
envy run) that injects secrets into memory without ever touching disk ✅
✨ Features Overview
| Feature | Description |
|---|---|
| 🔐 AES-256-GCM Encryption | All secrets are encrypted at rest using authenticated encryption (AEAD) |
| 🏗️ Zero-Knowledge E2EE | Cloud sync where the server mathematically cannot read your secrets |
| 🎣 Anti-Phishing (WebAuthn + SRP) | Passkey login via TouchID/Windows Hello/Microsoft Authenticator. SRP fallback ensures passwords never leave your machine. |
| 📁 Profile Management | Multiple environments (dev, staging, prod) with one-click switching |
| 🔗 Profile Inheritance | staging can inherit from prod — only store overrides |
| 🛡️ Schema Validation | Enforce types, patterns, and per-profile rules on all secrets |
| 🎭 Log Masking | envy run intercepts stdout/stderr and masks secret values with ******** |
| 📜 Envy Blame | Git-blame-style audit trail showing who changed what, when |
| 🪝 Pre-commit Hooks | Warns developers when they forget to push new secrets to cloud |
| 🖥️ Web Dashboard | Beautiful local dark-mode UI for managing 100+ variables visually |
| ⏰ Secret Rotation | Expiration dates, staleness detection, and health checks |
| 🔄 Drift Detection | Compare profiles to find missing or divergent keys |
| ☁️ Cloud Sync | Push, pull, and clone secrets across your team |
🛠️ Tech Stack
Envy is a full-stack application spanning a Python CLI, a Node.js API, a React web dashboard, and a self-contained local UI — all unified by a Zero-Knowledge cryptographic core.
CLI (Python)
| Component | Technology | Purpose |
|---|---|---|
| Framework | Typer + Rich | Command-line interface with beautiful terminal output |
| Encryption | cryptography (AES-256-GCM, X25519) | Local secret encryption and asymmetric key exchange |
| Key Derivation | argon2-cffi (Argon2id) | Derives encryption keys from the Master Password |
| Anti-Phishing | SRP-6a (pure Python, RFC 5054) | Zero-knowledge password proof for headless login |
| Browser Auth | OAuth PKCE (built-in http.server) |
Opens browser for Passkey login, captures token via localhost callback |
| HTTP | requests | API communication with Envy Cloud |
| Keyring | keyring | Stores master key in OS keychain (Windows Credential Manager, macOS Keychain) |
| Local UI | http.server (built-in) | Self-contained web dashboard with zero dependencies |
| Build | hatchling | PEP 517 compliant Python package builder |
| CI/CD | GitHub Actions (OIDC Trusted Publishing) | Automated PyPI releases |
Backend (Node.js)
| Component | Technology | Purpose |
|---|---|---|
| Framework | Express.js 5 | REST API server |
| Database | MongoDB + Mongoose | User accounts, projects, encrypted secrets, activity logs |
| Auth (Passkeys) | @simplewebauthn/server | WebAuthn registration and authentication |
| Auth (SRP) | secure-remote-password | Server-side SRP-6a challenge-response |
| Auth (Tokens) | jsonwebtoken | JWT session tokens (7-day expiry) |
| Validation | express-validator | Request body validation |
Frontend (React)
| Component | Technology | Purpose |
|---|---|---|
| Framework | React + Vite | Single-page application |
| Passkeys | @simplewebauthn/browser | WebAuthn registration/login from the browser |
| E2EE | libsodium-wrappers + Web Crypto API | Client-side X25519 key exchange and AES-256-GCM decryption |
| Styling | CSS | Custom design system with dark mode |
Cryptographic Primitives
| Layer | Algorithm | Standard | Why |
|---|---|---|---|
| Symmetric Encryption | AES-256-GCM | NIST SP 800-38D | AEAD cipher — encrypts and authenticates in one step. Used by TLS 1.3. |
| Asymmetric Key Exchange | X25519 (Curve25519) | RFC 7748 | Modern elliptic-curve Diffie-Hellman. Used by Signal, WireGuard, and TLS 1.3. |
| Key Derivation | Argon2id | RFC 9106 | Memory-hard KDF resistant to GPU/ASIC brute-force attacks. Winner of the Password Hashing Competition. |
| Anti-Phishing (Browser) | WebAuthn / FIDO2 | W3C WebAuthn L2 | Cryptographic authentication tied to the domain name. Impossible to phish. |
| Anti-Phishing (Headless) | SRP-6a | RFC 5054 | Zero-knowledge password proof. The password never leaves the client, even over a compromised network. |
| Random Numbers | os.urandom / CSPRNG | NIST SP 800-90A | Cryptographically secure random number generation for keys, nonces, and salts. |
Installation
# Install from PyPI
pip install envy-secrets
PyPI: https://pypi.org/project/envy-secrets/
Requirements: Python 3.10+
Development Installation
# Clone the repository
git clone https://github.com/KRISHNA-JAIN15/ENVY.git
cd ENVY
# Create and activate virtual environment
python -m venv venv
.\venv\Scripts\Activate # Windows
source venv/bin/activate # Linux/macOS
# Install in development mode with dev dependencies
pip install -e ".[dev]"
Quick Start
# 1. Initialize Envy in your project
envy init
# 2. Add some secrets
envy set DATABASE_URL=postgres://localhost/mydb
envy set API_KEY=sk-1234567890 --expires 30d
envy set PORT=3000 --profile prod
# 3. View your secrets
envy view # Active profile (masked)
envy view --profile prod --show # Show actual values
# 4. Run your app with secrets injected into memory (BEST PRACTICE!)
envy run dev -- npm start
envy run prod -- python app.py
# 5. Open the visual dashboard
envy ui
# 6. Sync with your team via Envy Cloud
envy cloud login
envy cloud push
📖 Command Reference
Core Commands
| Command | Description |
|---|---|
envy init |
Initialize Envy in the current directory. Creates .envy/ with AES-256-GCM encryption keys and default profiles (dev, staging, prod). Automatically updates .gitignore. |
envy set KEY=VALUE |
Encrypt and store a secret. Supports --profile, --expires, and --desc flags. Validates against schema rules if envy.schema.json exists. |
envy get KEY |
Retrieve a secret value. Use --show to reveal the plaintext (masked by default). |
envy delete KEY |
Delete a secret from a profile. Requires --force or interactive confirmation. |
envy view |
Display all secrets in a table with Key, Value (masked), Source (own/inherited), and Status (expired/stale). Use --show to reveal values, --json for JSON output. |
envy run <profile> -- <cmd> |
Gold standard for security. Injects decrypted secrets into the subprocess environment. Secrets live only in memory — never written to disk. Automatically masks secret values leaked in stdout/stderr. |
envy export |
Generate a plaintext .env file. ⚠️ Less secure than envy run. |
envy import <file> |
Import variables from an existing .env file. Use --merge to add to existing secrets. |
envy capture |
Capture environment variables from the current shell session. Filters out system variables like PATH, HOME, etc. |
envy diff <source> <target> |
Compare two profiles to find missing, extra, or different keys. Prevents "works on my machine" errors. |
envy check |
Health check — find expired, expiring-soon, and stale secrets. Returns exit code 1 if issues are found (great for CI). |
envy blame <KEY> |
Show the full change history for a specific key from Envy Cloud. Displays user, action, environment, source (CLI/web), and timestamp. |
envy status |
Show a summary of the project: active profile, total profiles, schema rules, and encryption status. |
envy version |
Print the current Envy version. |
envy shell |
Print shell export commands. Usage: eval $(envy shell) |
envy ui |
Launch a local web dashboard at http://localhost:8888. |
Profile Commands
| Command | Description |
|---|---|
envy profile list |
List all profiles with secret counts and inheritance info. |
envy profile create <name> |
Create a new profile. Use --extends <parent> for inheritance. |
envy profile delete <name> |
Delete a profile and all its secrets. |
envy profile switch <name> |
Switch the active profile. |
envy profile copy <src> <dst> |
Clone all secrets from one profile to another. |
Schema Validation
| Command | Description |
|---|---|
envy schema show |
Display the current envy.schema.json rules. |
envy schema init |
Auto-generate a schema from your existing secrets. |
envy schema validate |
Validate all secrets in the active profile against the schema. |
Git Hooks
| Command | Description |
|---|---|
envy hooks install |
Install a Git pre-commit hook that warns when secrets are modified but not pushed to cloud. |
envy hooks uninstall |
Remove the Envy pre-commit hook. |
Cloud & Team Commands
| Command | Description |
|---|---|
envy cloud login |
Authenticate with Envy Cloud. |
envy cloud logout |
Clear saved credentials. |
envy cloud status |
Show the currently logged-in user. |
envy cloud clone <slug> |
Clone a project's secrets from the cloud. Auto-initializes Envy if needed. |
envy cloud push |
Push all local profiles to the cloud. Use --profile <name> to push a single profile. |
envy cloud remote |
Show, add, or remove the remote project origin. |
Web Dashboard
| Command | Description |
|---|---|
envy ui |
Launch on default port 8888 and auto-open browser. |
envy ui --port 3000 |
Use a custom port. |
envy ui --no-open |
Start the server without opening the browser. |
🔐 Zero-Knowledge E2EE Architecture
Envy v2 implements a complete Zero-Knowledge End-to-End Encryption system. The server never sees your secrets or your private key. Here is how every layer works:
1. User Account Creation (Key Derivation)
When a user signs up (envy cloud register):
- The CLI asks for a Master Password.
- The CLI stretches the password into a 256-bit Account Key using Argon2id — the winner of the Password Hashing Competition and the current gold standard for key derivation.
- The CLI generates an X25519 asymmetric keypair (a Public Key and a Private Key).
- The CLI encrypts the Private Key using the Account Key with AES-256-GCM.
- What is sent to the server: The plaintext Public Key, the encrypted Private Key, and the key salt. The Master Password and Account Key never leave your computer.
2. Project Initialization (envy init)
- The CLI generates a random 256-bit Project Master Key (symmetric, AES-256-GCM).
- All local
.envvariables are encrypted using this Project Master Key. - The key is stored locally in
.envy/master.keyand added to.gitignore.
3. Pushing to the Cloud (envy cloud push)
Instead of decrypting secrets before sending them:
- The CLI sends the secrets still encrypted with the Project Master Key.
- To allow the cloud to store the Project Master Key safely, the CLI fetches the user's Public Key from the server.
- The CLI encrypts the Project Master Key using the user's Public Key (X25519 sealed box).
- What is sent to the server: The encrypted secrets blob + the encrypted Project Master Key. The server holds your data, but it is mathematically impossible for the server to read it.
4. Team Sharing (Adding a Teammate)
How do you securely share secrets if the server can't read them?
- Admin runs
envy team add teammate@email.com. - The CLI fetches the teammate's Public Key from the server.
- The CLI takes the local Project Master Key and encrypts a copy of it using the teammate's Public Key.
- The CLI pushes this new wrapped key to the server.
- When the teammate runs
envy cloud clone, they download the encrypted secrets and their specific encrypted copy of the Project Master Key. They decrypt the Project Master Key using their own Private Key, then decrypt the secrets.
Cryptographic Primitives
| Layer | Algorithm | Why |
|---|---|---|
| Symmetric Encryption | AES-256-GCM | AEAD cipher — encrypts and authenticates in one step. Faster and more secure than CBC mode. |
| Asymmetric Encryption | X25519 (Curve25519) | Modern elliptic-curve key exchange. Faster and smaller than RSA. Used by Signal, WireGuard, and TLS 1.3. |
| Key Derivation | Argon2id | Memory-hard KDF resistant to GPU/ASIC attacks. Winner of the Password Hashing Competition. Falls back to PBKDF2-SHA256 (600k iterations) if argon2-cffi is unavailable. |
Note: The React web frontend mirrors the CLI's cryptographic capabilities using the Web Crypto API (
AES-256-GCM,PBKDF2) andlibsodium-wrappers(X25519). Keys are held in ephemeral memory refs and are never persisted to localStorage or cookies.
🎣 Anti-Phishing Protection
Envy implements 100% phishing-proof authentication using two complementary protocols. No matter how a user logs in, their credentials are mathematically protected from interception.
WebAuthn (Passkeys) — Primary Login
When you run envy cloud login or log in on the web dashboard, Envy uses WebAuthn / FIDO2 Passkeys. Passkeys are cryptographic credentials tied to the exact domain name (envy.com). If a user is tricked into visiting a fake site (envvy.com), the browser physically refuses to authenticate — the attack is impossible at the protocol level.
Supported Authenticators: Apple TouchID, Windows Hello, Microsoft Authenticator, Google Password Manager, 1Password, YubiKey, and any FIDO2-compliant device.
CLI Flow (OAuth PKCE):
- You run
envy cloud login. - The CLI spins up a temporary
localhostserver and opens your browser. - You authenticate on the trusted domain via Passkey (biometric scan, QR code, etc.).
- The browser redirects back to the CLI with the session token.
- The CLI captures the token and you're logged in — no password was typed.
envy cloud login # Opens browser → Passkey authentication
SRP-6a (Secure Remote Password) — Headless Fallback
For environments where a browser cannot be opened (SSH servers, CI/CD pipelines, Docker containers), Envy falls back to SRP-6a — a zero-knowledge proof protocol from RFC 5054.
How it stops phishing: Instead of sending your password to the server, the CLI uses your password to solve a mathematical challenge. Even if you accidentally connect to a malicious server, the server learns absolutely nothing about your password. The CLI also verifies the server's proof (M2) to confirm the server is authentic.
envy cloud login --headless # SRP challenge-response (no browser needed)
The 2-Step Handshake:
- Step 1 (Challenge): CLI sends email + ephemeral value
A. Server responds with salt + ephemeral valueB. - Step 2 (Proof): CLI computes proof
M1using the password locally. Server verifiesM1and responds with its own proofM2. CLI verifiesM2to ensure the server is real.
At no point does the password leave the client. The server stores only a mathematical verifier (computed during registration), which cannot be reversed to recover the password.
Vault Decryption (Always Local)
Whether you log in via Passkey or SRP, the server only handles authentication (proving who you are). The actual decryption of your secrets always requires your Master Password locally — the server never has access to it. This is the same security model used by 1Password and Bitwarden.
Implementation Details
CLI Integration
envy cloud register: Computes the SRP salt and verifier locally (your password is never sent). It generates an X25519 E2EE keypair, encrypts the private key using an Argon2id-derived key, and sends only the verifier and the encrypted key material to the server.envy cloud login: Defaults to the OAuth PKCE browser flow for Passkey authentication. The--headlessflag triggers the 2-step SRP challenge-response handshake.
Frontend WebAuthn & SRP Integration
- SRP Client (
srp.js): A JavaScript SRP-6a client managesSRPSessionandgenerateVerifierto ensure zero-knowledge authentication in the browser. - API endpoints (
api.js): Replaced traditional login withsrpChallengeandsrpVerifyendpoints, and added endpoints for WebAuthn authentication. - Auth Context (
AuthContext.jsx): Theregister()function computes the SRP verifier locally. Thelogin()function performs the 2-step SRP handshake. NewloginWithPasskey()andregisterPasskey()functions handle WebAuthn. - Auth UI:
Login.jsxfeatures a two-tab UI: Passkey (default, phishing-proof) and Master Password (SRP, zero-knowledge).Signup.jsxuses SRP registration and clearly indicates that the "password never leaves your device."
🔗 Profile Inheritance
If you have 50 variables in prod and 49 of them are the same in staging, you shouldn't have to duplicate them all. With profile inheritance, you store only the overrides.
How It Works
# Create a staging profile that inherits everything from prod
envy profile create staging --extends prod
# Override just the one key that's different
envy set DATABASE_URL=postgres://staging-db --profile staging
Now staging automatically inherits all 50 keys from prod, and only the DATABASE_URL override is stored in the staging profile. The secrets.json stays small and manageable.
Viewing Inherited Secrets
envy view --profile staging
The table shows a Source column:
own— the key is defined directly in this profile← prod— the key is inherited from the parent profile
Circular Reference Protection
Envy walks the inheritance chain with cycle detection. If you accidentally create a circular dependency (A extends B, B extends A), it will stop and use only the keys it has already resolved.
🛡️ Schema Validation & Type-Safety
Plain .env files are just dumb strings. Envy lets you define strict rules for your secrets so that mistakes are caught before they reach production.
Setting Up a Schema
Create an envy.schema.json file in your project root:
{
"variables": {
"PORT": {
"type": "integer",
"required": true
},
"DATABASE_URL": {
"type": "url",
"required": true
},
"STRIPE_KEY": {
"type": "string",
"profiles": {
"dev": { "pattern": "^sk_test_" },
"prod": { "pattern": "^sk_live_" }
}
},
"LOG_LEVEL": {
"type": "string",
"enum": ["debug", "info", "warn", "error"]
},
"APP_NAME": {
"type": "string",
"minLength": 3,
"maxLength": 50
}
}
}
Supported Validation Rules
| Rule | Description | Example |
|---|---|---|
type |
Enforces a data type | "integer", "number", "boolean", "url", "email", "string" |
required |
Key must exist in the profile | true / false |
pattern |
Regex pattern the value must match | "^sk_live_" |
enum |
Value must be one of a set | ["debug", "info", "warn"] |
minLength |
Minimum string length | 3 |
maxLength |
Maximum string length | 128 |
profiles |
Per-profile overrides of any rule above | See the STRIPE_KEY example above |
What Happens When Validation Fails
$ envy set STRIPE_KEY=sk_test_123 --profile prod
Schema Error: Value for STRIPE_KEY in profile 'prod' must match pattern: ^sk_live_
The CLI blocks the operation and does not save the secret.
CLI Commands
envy schema show # Display the current schema rules
envy schema init # Auto-generate a schema from existing secrets
envy schema validate # Validate all secrets in the active profile
🎭 Log Masking
When you run envy run prod -- npm start, Envy doesn't just inject the secrets — it actively protects them from being leaked in logs.
How It Works
- The subprocess is launched with
stdoutandstderrpiped through Envy. - Two daemon threads read the output line-by-line in real time.
- Every line is scanned for any secret value (≥ 4 characters long).
- Matches are replaced with
********before being printed to your terminal.
Example
# If your app accidentally prints: "Connecting to postgres://admin:s3cret@db:5432"
# You see: "Connecting to ********"
Controlling Log Masking
envy run prod -- npm start # Masking ON (default)
envy run prod --no-mask -- npm start # Masking OFF
📜 Envy Blame
Just like git blame, Envy Blame shows you exactly who changed a specific secret, when they changed it, and from which source (CLI or web dashboard).
Usage
envy blame DATABASE_URL
Output
┌──────────────────────────────────────────────────────────────┐
│ 📜 Blame: DATABASE_URL │
├────────┬──────────┬─────────┬──────┬────────┬───────────────┤
│ Commit │ User │ Action │ Env │ Source │ When │
├────────┼──────────┼─────────┼──────┼────────┼───────────────┤
│ a3f2c1 │ Krishna │ updated │ prod │ cli │ 2 hours ago │
│ 8b1d4e │ Krishna │ created │ prod │ web │ 3 days ago │
└────────┴──────────┴─────────┴──────┴────────┴───────────────┘
This works by querying the Envy Cloud activity log (activities.js model) for all events related to that specific key. It requires a remote to be configured (envy cloud remote add <slug>).
🪝 Pre-commit Hook Integration
A common failure mode: a developer adds a new package (like Stripe), creates a STRIPE_KEY in their local Envy, writes the code, and pushes — but forgets to run envy cloud push. The CI build breaks for everyone.
Installation
envy hooks install
This creates a script in .git/hooks/pre-commit. Every time a developer runs git commit:
- The hook checks if
.envy/secrets.jsonhas been modified in the staged files. - If it has, the hook warns the developer and asks them to push their secrets to the cloud before committing.
- The commit proceeds, but the developer gets a clear, visible prompt.
Uninstallation
envy hooks uninstall
This cleanly removes only the Envy portion of the pre-commit hook, leaving any other hooks intact.
🖥️ Local Web Dashboard (envy ui)
Managing 100+ environment variables in a terminal can be tedious. The envy ui command launches a beautiful, full-screen dark-mode dashboard on localhost where you can manage everything visually.
How It's Built
The dashboard is completely self-contained inside the Python package. It uses Python's built-in http.server module — zero external web framework dependencies (no Flask, no FastAPI, no npm). The entire HTML, CSS, and JavaScript is embedded as a single inline template in web_ui.py.
Launching the Dashboard
envy ui # Launch on port 8888, auto-open browser
envy ui --port 3000 # Use a custom port
envy ui --no-open # Start without opening browser
Dashboard Features
| Feature | Description |
|---|---|
| Profile Sidebar | Lists all profiles with secret counts and inheritance indicators. Click to switch. |
| Secrets Table | View all keys in a sortable table. Click any value to toggle reveal/hide. |
| Search | Instant client-side filtering as you type. |
| Add / Edit Secrets | Modal dialog with key, value, and description fields. Schema validation runs on save. |
| Delete Secrets | One-click delete with confirmation prompt. |
| Create Profiles | Create new profiles with optional --extends inheritance. |
| Visual Diff | Side-by-side comparison of any two profiles. Missing keys are highlighted red, extra keys green, changed keys yellow. |
| Dark Mode | Premium design with Inter + JetBrains Mono fonts and glassmorphism accents. |
Security
The server binds exclusively to 127.0.0.1 (localhost). It is not accessible from other machines on the network. All decryption happens server-side in the Python process — the browser receives already-decrypted values over the local loopback interface.
💡 Use Cases
Local Development
# Developer A sets up the project
envy init
envy set DATABASE_URL=postgres://localhost/dev
envy set API_KEY=dev-key-123
envy run dev -- npm start
# Developer B clones and gets secrets
git clone repo && cd repo
envy cloud login
envy cloud clone myproject --env development
envy run dev -- npm start
Multiple Environments with Inheritance
# Set up production with all variables
envy set DATABASE_URL=postgres://prod-db --profile prod
envy set REDIS_URL=redis://prod-cache --profile prod
envy set API_KEY=live-key-prod --profile prod
# Staging inherits everything, only override what's different
envy profile create staging --extends prod
envy set DATABASE_URL=postgres://staging-db --profile staging
# Run in either environment
envy run prod -- python app.py
envy run staging -- python app.py # Gets prod's REDIS_URL and API_KEY automatically
CI/CD Pipeline
# In your CI/CD pipeline (GitHub Actions, GitLab CI, etc.)
pip install envy-secrets
envy cloud login --email $ENVY_EMAIL --password $ENVY_PASSWORD
envy cloud clone myproject --env production
envy run prod -- npm run build
Secret Rotation with Schema Enforcement
# Set up schema rules
envy schema init
# Set secrets with expiration
envy set API_KEY=old-key --expires 30d
# Check for expiring secrets (great for CI health checks)
envy check # Returns exit code 1 if issues found
# Rotate the secret
envy set API_KEY=new-key --expires 30d
🔒 Security Best Practices
- Never commit
.envy/master.key— It's automatically added to.gitignoreduringenvy init. - Use
envy runinstead ofenvy export— Secrets stay in process memory and are never written to a plaintext file on disk. - Enable log masking — It's on by default with
envy run. Any secret value that leaks into stdout or stderr is replaced with********. - Set expiration dates —
envy set KEY=value --expires 30densures you rotate secrets regularly. - Run
envy checkin CI — It returns a non-zero exit code if any secrets are expired or stale. - Install pre-commit hooks —
envy hooks installwarns developers when they forget to push new secrets. - Use schema validation — Define
envy.schema.jsonto prevent staging keys from accidentally being used in production.
File Structure
your-project/
├── .envy/
│ ├── master.key # 🔑 AES-256-GCM encryption key (NEVER COMMIT!)
│ └── secrets.json # 🔒 Encrypted secrets database (safe to commit)
├── envy.schema.json # 📋 Optional schema validation rules (commit this)
├── .gitignore # Auto-updated by envy init
└── ...
❓ FAQ
How is this different from dotenv?
dotenv loads plaintext .env files. Envy encrypts secrets at rest with AES-256-GCM, supports multiple profiles, enforces schema validation, syncs via Zero-Knowledge E2EE, masks log output, and provides a visual web dashboard. It's an entire secret management platform, not just a file loader.
Can I use this with my existing .env files?
Yes! Import your existing .env file and Envy will encrypt every variable:
envy import .env
What happens if I lose my master key?
Without .envy/master.key, your local secrets cannot be decrypted. Always back up this file securely. If you use Envy Cloud, your secrets are also stored (encrypted) on the server and can be re-cloned by any team member.
Is it safe to commit .envy/secrets.json?
Yes. The secrets.json file contains only AES-256-GCM encrypted ciphertext. Without the master key, it is computationally infeasible to decrypt.
What encryption does Envy use?
Envy v2 uses AES-256-GCM (symmetric, AEAD), X25519 (asymmetric key exchange, Curve25519), and Argon2id (key derivation). Fernet (AES-128-CBC) was fully removed in v2.0.
Can I use this in production?
Absolutely. Use envy run prod -- your-command to inject secrets directly into your process without writing them to disk. The log masking feature ensures secrets don't leak into stdout/stderr.
Does the web dashboard expose secrets to the network?
No. The envy ui server binds exclusively to 127.0.0.1 (localhost). It is not accessible from any other machine.
Is this compatible with Microsoft Authenticator / YubiKey / TouchID?
Yes, Envy uses standard WebAuthn for hardware-backed keys. It works out-of-the-box with Apple Touch ID, Windows Hello, YubiKeys, and authenticator apps like 1Password and Microsoft Authenticator.
Why make a project "Public" if it only has environment variables?
This is a great question, because exposing actual secrets (like Database URLs or API keys) publicly is incredibly dangerous! However, having a "Public" visibility option for an env manager serves a few very powerful, specific use cases:
- Open Source Templates (
.env.examplereplacement): If you build an open-source project on GitHub, you can create a public Envy project that contains all the keys (and maybe safe default values) but keeps the real secrets blank. Contributors can just runenvy pull <project-id>to instantly generate their local.envfile with the correct schema, instead of copy-pasting from a.env.examplefile. - Public Configuration: Sometimes apps need to share non-sensitive configuration globally (e.g.,
PUBLIC_API_URL, feature flags, or theme settings). A public project allows client-side apps or community members to fetch this configuration without needing authentication. - Forking Configurations: Just like you fork a repo on GitHub, developers could "Fork" a public Envy project to instantly get the base configuration for a popular framework (like a Next.js starter kit) copied into their own private workspace.
🤝 Contributing
We welcome contributions! Here's how to get started:
Setting Up
git clone https://github.com/KRISHNA-JAIN15/ENVY.git
cd ENVY
python -m venv venv
source venv/bin/activate # Linux/macOS
.\venv\Scripts\Activate # Windows
pip install -e ".[dev]"
Running Tests
pytest
Code Style
black .
ruff check .
Contribution Guidelines
- Fork the repository and create a feature branch.
- Make your changes with clear, descriptive commit messages.
- Add tests for new features.
- Ensure all tests pass with
pytest. - Format your code with
blackandruff. - Submit a pull request with a clear description of what you changed and why.
Report Issues
Found a bug or have a feature request? Open an issue on GitHub.
📄 License
MIT License — see the LICENSE file for details.
Made with ❤️ by Krishna Jain
⭐ Star us on GitHub • 🐦 Follow updates
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file envy_secrets-2.0.3.tar.gz.
File metadata
- Download URL: envy_secrets-2.0.3.tar.gz
- Upload date:
- Size: 61.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6173af7ef17dfedff9ed300f487cad9638446afeda8059ee936e5488801cc42
|
|
| MD5 |
f7939a8f97abda09850b6ac43ccb3402
|
|
| BLAKE2b-256 |
438aae424be72262927018b809ffa4023978909fe737c6d904dc3a9450c084cc
|
Provenance
The following attestation bundles were made for envy_secrets-2.0.3.tar.gz:
Publisher:
publish.yml on KRISHNA-JAIN15/ENVY
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
envy_secrets-2.0.3.tar.gz -
Subject digest:
e6173af7ef17dfedff9ed300f487cad9638446afeda8059ee936e5488801cc42 - Sigstore transparency entry: 2218992767
- Sigstore integration time:
-
Permalink:
KRISHNA-JAIN15/ENVY@773ed7df9a66dfcc25cce819c27fdf972901bc41 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/KRISHNA-JAIN15
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@773ed7df9a66dfcc25cce819c27fdf972901bc41 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file envy_secrets-2.0.3-py3-none-any.whl.
File metadata
- Download URL: envy_secrets-2.0.3-py3-none-any.whl
- Upload date:
- Size: 54.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae2e0bef9ac95385c1b76ab0fe024fe387d30e8ce79d05245a6a29cd4dfad999
|
|
| MD5 |
f45cd37c81156e228ccc6d559f17f13a
|
|
| BLAKE2b-256 |
58823197d365b7f9f8af56e9780b73ce98407ed53a4e1a2ae52092b93e9bc4d7
|
Provenance
The following attestation bundles were made for envy_secrets-2.0.3-py3-none-any.whl:
Publisher:
publish.yml on KRISHNA-JAIN15/ENVY
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
envy_secrets-2.0.3-py3-none-any.whl -
Subject digest:
ae2e0bef9ac95385c1b76ab0fe024fe387d30e8ce79d05245a6a29cd4dfad999 - Sigstore transparency entry: 2218993325
- Sigstore integration time:
-
Permalink:
KRISHNA-JAIN15/ENVY@773ed7df9a66dfcc25cce819c27fdf972901bc41 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/KRISHNA-JAIN15
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@773ed7df9a66dfcc25cce819c27fdf972901bc41 -
Trigger Event:
workflow_dispatch
-
Statement type: