envi pack
Create an encrypted blob from your stored environment configuration that can be shared with team members.
Usage
envi packDescription
The pack command finds all .env files in your repository, encrypts them, and automatically copies the encrypted blob to your clipboard. This blob can be safely shared with team members through communication channels like Slack, email, or messaging platforms.
Note: Pack works completely independently of capture and global storage. It reads environment files directly from your repository and creates an encrypted blob - no capture needed!
Encryption Methods
pack resolves the encryption key in this order:
envi.config.mamlwithencryption_key(preferred) - Generated byenvi create-keyand committed to the repo. The most reliable option because the key is stable across dependency updates.- Manifest-derived key - Fallback when no
envi.config.mamlis present. The key is an MD5 hash of a manifest file's contents. Supported manifests:package.json(JavaScript/TypeScript),Cargo.toml(Rust),go.mod(Go),pyproject.toml(Python),composer.json(PHP),pubspec.yaml(Dart/Flutter),pom.xml(Java/Maven),settings.gradle.kts(Kotlin),settings.gradle(Java/Gradle). Custom manifests: add viaenvi config manifest_files add <filename>- see Multi-Language Support. - Custom secret prompt - Used when neither of the above is available. Must be at least 8 characters; you'll need to share both the blob AND the secret with the recipient.
When to use envi.config.maml
The manifest fallback is fine for most ad-hoc sharing. Run envi create-key once and commit envi.config.maml if you find that blobs in chat or onboarding docs keep breaking after teammates run pnpm install (or equivalent) — it gives you a key that's stable across dependency updates, at the cost of binding decryption to the (private) source repo.
Why prefer envi.config.maml over manifest-derived keys?
- The manifest hash changes whenever the file changes (e.g.,
pnpm installupdatingpnpm-lock.yamlor any line ofpackage.json), which invalidates older blobs. - A committed
envi.config.mamlsurvives dependency updates indefinitely. - The recipient doesn't need to be on the same dependency state as the sender.
Examples
Projects with envi.config.maml
After running envi create-key once and committing envi.config.maml:
envi packOutput:
✔ Finding repository root...
Repository root: /Users/you/projects/myapp
✔ Searching for env files...
✔ Found 3 file(s) to pack
✔ Reading environment files...
ℹ Using encryption_key from envi.config.maml
✔ Encrypting configuration...
✔ Copying blob to clipboard!
Blob is now on your clipboard!
Share it with colleagues who have the same envi.config.maml committed in their checkout
They can restore it using: envi unpackAnyone with the same checkout (and therefore the same envi.config.maml) can decrypt by running envi unpack.
Projects with Manifest Files
If envi.config.maml is not present, pack falls back to manifest-derived keys (works with JavaScript/TypeScript, Rust, Go, Python, PHP, etc.):
envi packOutput:
✔ Finding repository root...
Repository root: /Users/you/projects/myapp
✔ Searching for env files...
✔ Found 3 file(s) to pack
✔ Reading environment files...
Using package.json for encryption key
⚠ Note: Only team members with the same package.json can decrypt this blob
✔ Encrypting configuration...
✔ Copying blob to clipboard...
✔ Blob copied to clipboard!
Blob is now on your clipboard!
Share it with team members who have the same manifest file
They can restore it using: envi unpackThe blob is now in your clipboard and ready to paste into Slack, email, or any messaging platform. Your team members can simply run envi unpack without any arguments - it will automatically read the blob from their clipboard!
Note: The output will mention the specific manifest file found (package.json, Cargo.toml, go.mod, etc.). The encryption key is derived from that file's contents.
Projects without Supported Manifest Files
For projects without a supported manifest file, you'll be prompted for a secret:
envi packInteractive flow:
✔ Finding repository root...
Repository root: /Users/you/projects/myapp
✔ Searching for env files...
✔ Found 2 file(s) to pack
✔ Reading environment files...
⚠ No supported manifest file found in repository root
This is expected for some project types.
You'll need to provide a secret for encryption.
? Enter an encryption secret: ********
Using custom secret for encryption
✔ Encrypting configuration...
✔ Copying blob to clipboard...
✔ Blob copied to clipboard!
Blob is now on your clipboard!
Share the blob and the secret with your team members
They will be prompted for the secret when running: envi unpackThe blob is automatically copied to your clipboard. Share both the blob (paste from clipboard) and the secret you entered with your team members.
How It Works
- Finds project root - Locates your project root (looks for version control markers:
.git,.jj,.hg,.svn, or prompts for confirmation) - Searches for env files - Finds all
.env,.env.*,.dev.vars, and.dev.vars.*files in your repository - Reads environment files - Parses each file, preserving comments and structure
- Resolves encryption key in priority order:
- If
envi.config.mamlexists in the repo root withencryption_keyset, use it - Otherwise check for supported manifest files (package.json, Cargo.toml, go.mod, pyproject.toml, composer.json, pubspec.yaml, pom.xml, settings.gradle.kts, settings.gradle) and derive an MD5-hash key from the first match
- Otherwise prompt for a custom secret (minimum 8 characters)
- If
- Compresses data - Uses gzip compression to reduce blob size by ~50%
- Encrypts data - Uses AES-256-GCM encryption with authentication on compressed data
- Formats blob - Wraps encrypted data in
__envi_start__and__envi_end__delimiters - Copies to clipboard - Automatically copies the blob to your system clipboard for easy sharing
Clipboard Feature
The blob is automatically copied to your clipboard, making it incredibly easy to share:
- Run
envi pack - Paste (Cmd+V / Ctrl+V) directly into Slack, Teams, email, or any messaging app
- Your team member copies the blob and runs
envi unpack(no arguments needed!) - The blob is automatically read from their clipboard and decrypted
If clipboard operations fail (e.g., in headless environments), the blob is displayed in the terminal instead.
Security Considerations
⚠️ Critical Security Warning
IMPORTANT: Blobs encrypted with manifest files (automatic encryption) are only secure while your codebase remains private.
The Risk
When using manifest-based encryption (package.json, Cargo.toml, go.mod, etc.):
- Anyone with access to your codebase can decrypt your blobs
- An attacker could iterate through git commit history to find the commit that decrypts the blob
- Never post blobs in publicly accessible locations
Safe sharing channels:
- ✅ Private direct messages
- ✅ Password managers (1Password, Bitwarden)
- ✅ Encrypted messaging (Signal, etc.)
Unsafe sharing channels:
- ❌ Public Slack/Discord channels
- ❌ Public GitHub issues or wikis
- ❌ Public documentation
- ❌ Team wikis accessible to contractors
- ❌ Any location that might become public
For truly sensitive data: Use a custom strong secret (minimum 20+ random characters) instead of relying on manifest-based encryption. See the Sharing Environment Configurations guide for detailed security information.
Using Manifest-Based Encryption (Automatic)
Pros:
- No need to share secrets separately
- Works out of the box for teams
- Blob can only be decrypted in the same codebase
- Automatic key consistency across the team
- Supports many languages (JavaScript/TypeScript, Rust, Go, Python, PHP, Dart, Java, etc.)
Cons:
- ⚠️ Insecure if codebase is compromised - See warning above
- Blob becomes unreadable if manifest file changes (even a single character difference)
- Cannot be used as historical reference if manifest is updated
- Only works with supported project types
- MD5 hash means any whitespace or formatting change in manifest breaks decryption
Using Custom Secret Encryption
Pros:
- ✅ Secure even if codebase is compromised (if secret is strong and kept separate)
- Blob remains readable regardless of codebase changes
- Can be stored as historical reference
- Full control over who can decrypt
- Works for any project type
Cons:
- Must share secret separately (through secure channel)
- Secret must be remembered/stored securely
- Requires manual secret management
Recommendation: For production credentials or highly sensitive data, always use a custom strong secret (20+ random characters) regardless of project type.
Related Commands
envi unpack- Decrypt and restore a blobenvi create-key- Generateenvi.config.mamlfor a stable shared key that survives manifest changesenvi capture- Capture environment files to storage
See Also
- Sharing Environment Configurations - Complete guide to sharing configs