展示HN:Lockenv – Git的简单加密密钥存储
Show HN: Lockenv – Simple encrypted secrets storage for Git

原始链接: https://github.com/illarion/lockenv

## lockenv: 简单的加密密钥存储 lockenv 是一个 CLI 工具,用于安全地将敏感文件(如 `.env` 文件、配置文件、证书)直接存储在版本控制中。它为小型团队提供了一个比 sops 或 git-crypt 等工具更简单的替代方案。 它的工作原理是使用密码派生密钥将文件加密到一个 `.lockenv` 仓库文件中。用户 `lock` 文件进行加密,`unlock` 文件进行解密,只将 `.lockenv` 文件提交到仓库。 **主要特点:** * **简单设置:** 通过 Homebrew、包管理器或二进制下载轻松安装。 * **密码或密钥环认证:** 使用密码进行加密,可以选择安全地存储在操作系统密钥环中。 * **Git 集成:** 专为版本控制设计,提供清晰的指示来添加/提交 `.lockenv` 文件。 * **冲突解决:** 处理本地文件与仓库版本不同的冲突,可以选择保留本地、使用仓库、编辑或保留两者。 * **CI/CD 支持:** 可以使用环境变量解锁(存在安全隐患)。 **最适合:** 管理简单的 `.env` 和配置文件。不适合非常大的文件(>100MB)或需要细粒度访问控制的场景。请记住,丢失密码意味着失去对密钥的访问! [https://github.com/illarion/lockenv](https://github.com/illarion/lockenv)

## Lockenv:简单的基于Git的密钥存储 Lockenv是一个新工具,旨在简化小型团队和个人项目的加密密钥管理。它由一位开发者创建,这位开发者厌倦了像sops或git-crypt这样复杂的解决方案,它提供了一种直接的方法:一个密码保护的vault文件直接提交到Git仓库。 该工具与操作系统密钥环集成,以避免重复的密码提示,并支持Mac、Linux和(目前未经测试的)Windows。作者强调,这并非旨在取代强大的解决方案,而是为那些通过不太安全的渠道(如Slack)共享密钥的情况提供一个简单的替代方案。 讨论中强调了对密钥管理(团队成员离开时撤销访问权限)、版本控制限制(难以跟踪特定密钥的更改)以及意外提交未加密密钥的风险的担忧。现有的工具,如git-crypt和sops,可以解决其中一些问题,而另一些人则建议使用dotenvx或专门的vault解决方案等替代方案。然而,许多人认为,对于复杂的设置来说是多余的,对于较小的项目来说,更简单的方法很有价值。
相关文章

原文

Simple, CLI-friendly secret storage that lets you safely commit encrypted secrets to version control.

For small teams who want something simpler than sops/git-crypt for .env and infra secrets.

lockenv provides a secure way to store sensitive files (like .env files, configuration files, certificates) in an encrypted .lockenv file that can be safely committed to your repository. Files are encrypted using a password-derived key and can be easily extracted when needed.

Feature lockenv git-crypt sops
Format Single vault file Transparent per-file YAML/JSON native
Auth Password + Keyring GPG keys KMS/PGP
Git integration Manual (lock/unlock) Transparent (git filter) Manual
Setup lockenv init GPG key exchange KMS/key config
Best for Simple .env/config Large teams, many devs Cloud infra, key rotation
brew tap illarion/tap
brew install lockenv

Download the .deb file from the latest release:

sudo dpkg -i lockenv_*_linux_amd64.deb

Download the .rpm file from the latest release:

sudo rpm -i lockenv_*_linux_amd64.rpm

Download pre-built binaries from GitHub Releases.

Available for:

  • Linux (amd64, arm64)
  • macOS (amd64, arm64)
  • Windows (amd64, arm64)
go install github.com/illarion/lockenv@latest

Shell completions are automatically installed when using Homebrew, deb, or rpm packages.

For manual installation (binary download or go install):

# Bash - add to ~/.bashrc
eval "$(lockenv completion bash)"

# Zsh - add to ~/.zshrc
eval "$(lockenv completion zsh)"

# Fish - add to ~/.config/fish/config.fish
lockenv completion fish | source

# PowerShell - add to $PROFILE
lockenv completion powershell | Out-String | Invoke-Expression
# Initialize lockenv in your project
lockenv init

# Lock (encrypt and store) sensitive files
lockenv lock .env config/secrets.json

# Later, unlock (decrypt and restore) files with your password
lockenv unlock

lockenv is designed for version control: ignore your sensitive files, commit only the encrypted .lockenv vault.

Add to your .gitignore:

# Sensitive files - these are stored encrypted in .lockenv
.env
.env.*
*.key
*.pem
secrets/

# Keep the encrypted vault (negation pattern)
!.lockenv

The !.lockenv negation ensures the vault is tracked even if broader patterns (like .*) would exclude it.

Project-Specific Examples

Some software project:

.env
.env.local
.env.production
config/secrets.json
!.lockenv

Terraform project:

*.tfvars
terraform.tfstate
terraform.tfstate.backup
.terraform/
!.lockenv

Creates a .lockenv vault file in the current directory. Prompts for a password that will be used for encryption. The password is not stored anywhere - you must remember it.

$ lockenv init
Enter password:
Confirm password:
initialized: .lockenv

lockenv lock <file> [file...]

Encrypts and stores files in the vault. Supports glob patterns for multiple files.

# Lock a single file
$ lockenv lock .env
Enter password:
locking: .env
encrypted: .env
locked: 1 files into .lockenv

# Lock multiple files with glob pattern
$ lockenv lock "config/*.env"
Enter password:
locking: config/dev.env
locking: config/prod.env
encrypted: config/dev.env
encrypted: config/prod.env
locked: 2 files into .lockenv

Options:

  • -r, --remove - Remove original files after locking
$ lockenv lock .env --remove
Enter password:
locking: .env
encrypted: .env
removed: .env
locked: 1 files into .lockenv

Decrypts and restores files from the vault with smart conflict resolution.

# Unlock all files
$ lockenv unlock
Enter password:
unlocked: .env
unlocked: config/database.yml

unlocked: 2 files

# Unlock specific file
$ lockenv unlock .env
Enter password:
unlocked: .env

unlocked: 1 files

# Unlock files matching pattern
$ lockenv unlock "config/*.env"
Enter password:
unlocked: config/dev.env
unlocked: config/prod.env

unlocked: 2 files

Smart Conflict Resolution: When a file exists locally and differs from the vault version, you have multiple options:

Interactive Mode (default):

  • [l] Keep local version
  • [v] Use vault version (overwrite local)
  • [e] Edit merged (opens in $EDITOR with git-style conflict markers, text files only)
  • [b] Keep both (saves vault version as .from-vault)
  • [x] Skip this file

Non-Interactive Flags:

  • --force - Overwrite all local files with vault version
  • --keep-local - Keep all local versions, skip conflicts
  • --keep-both - Keep both versions for all conflicts (vault saved as .from-vault)
# Interactive mode example
$ lockenv unlock

warning: conflict detected: .env
   Local file exists and differs from vault version
   File type: text

Options:
  [l] Keep local version
  [v] Use vault version (overwrite local)
  [e] Edit merged (opens in $EDITOR)
  [b] Keep both (save vault as .from-vault)
  [x] Skip this file

Your choice: e

opening editor for merge...
# Editor opens with:
# <<<<<<< local
# API_KEY=old_value
# =======
# API_KEY=new_value
# DEBUG=true
# >>>>>>> vault

unlocked: .env

# Keep both versions example
$ lockenv unlock --keep-both
Enter password:
saved: .env.from-vault (vault version)
skipped: .env (kept local version)
saved: config/secrets.json.from-vault (vault version)
skipped: config/secrets.json (kept local version)

lockenv rm <file> [file...]

Removes files from the vault. Supports glob patterns.

$ lockenv rm config/dev.env
Enter password:
removed: config/dev.env from vault

Alias for lockenv status. Shows comprehensive vault status.

Shows comprehensive vault status including statistics, file states, and detailed information. Does not require a password.

$ lockenv status

Vault Status
===========================================

Statistics:
   Files in vault: 3
   Total size:     2.17 KB
   Last locked:    2025-01-15 10:30:45
   Encryption:     AES-256-GCM (PBKDF2 iterations: 210000)
   Version:        1

Summary:
   .  2 unchanged
   *  1 modified

Files:
   * .env (modified)
   . config/dev.env (unchanged)
   * config/prod.env (vault only)

===========================================

Changes the vault password. Requires both the current and new passwords. Re-encrypts all files with the new password.

$ lockenv passwd
Enter current password:
Enter new password:
Confirm new password:
password changed successfully

Shows actual content differences between vault and local files (like git diff).

$ lockenv diff
Enter password:
--- a/.env
+++ b/.env
@@ -1,3 +1,4 @@
 API_KEY=secret123
-DATABASE_URL=localhost:5432
+DATABASE_URL=production:5432
+DEBUG=false
 PORT=3000

Binary file config/logo.png has changed

File not in working directory: config/prod.env

Note: lockenv status shows which files changed, lockenv diff shows what changed.

Compacts the vault database to reclaim unused disk space. Runs automatically after rm and passwd, but can be run manually.

$ lockenv compact
Compacted: 45.2 KB -> 12.1 KB

Manages password storage in the OS keyring.

# Save password to keyring
$ lockenv keyring save
Enter password:
Password saved to keyring

# Check if password is stored
$ lockenv keyring status
Password: stored in keyring

# Remove password from keyring
$ lockenv keyring delete
Password removed from keyring
  1. Initial setup

    # Initialize vault
    lockenv init
    
    # Lock your sensitive files (encrypt and store)
    lockenv lock .env config/database.yml certs/server.key --remove
    
    # Commit the encrypted vault
    git add .lockenv
    git commit -m "Add encrypted secrets"
    git push
  2. After cloning repository (new team member)

    git clone <repo>
    cd <repo>
    
    # Unlock files to restore them
    lockenv unlock
  3. Updating secrets

    # Make changes to your .env file
    echo "NEW_SECRET=value" >> .env
    
    # Check what changed
    lockenv status    # See file is modified
    lockenv diff      # See detailed changes
    
    # Lock the updated files
    lockenv lock .env
    
    # Commit the changes
    git add .lockenv
    git commit -m "Update secrets"
    git push
  4. Managing files

    # Add new secret file
    lockenv lock new-secrets.json
    
    # Remove file from vault
    lockenv rm old-config.yml
    
    # Check vault status
    lockenv status
  • Password Management: lockenv does not store your password. If you lose it, you cannot decrypt your files.
  • Encryption: Uses industry-standard encryption (AES-256-GCM) with PBKDF2 key derivation for all file contents.
  • Metadata Visibility: File paths, sizes, and modification times are visible without authentication via lockenv status. If file paths themselves are sensitive, use generic names like config1.enc.
  • Memory Safety: Sensitive data is cleared from memory after use.
  • Version Control: Only commit the .lockenv file, never commit unencrypted sensitive files.

lockenv protects against:

  • Secrets exposed in git history or repository leaks
  • Unauthorized repository access without the password
  • Dev laptops without the password

lockenv does NOT protect against:

  • Compromised CI runner (sees plaintext after unlock)
  • Attacker who has the password

For CI/CD environments, you can provide the password via environment variable:

export LOCKENV_PASSWORD="your-password"
lockenv unlock

Security warning: Environment variables may be visible to other processes on the system (via /proc/<pid>/environ on Linux or process inspection tools). Use this feature only in isolated CI/CD environments where process inspection by other users is not a concern. For interactive use, prefer the terminal prompt or OS keyring.

lockenv can store your password in the operating system's secure keyring, eliminating password prompts for daily use.

Supported backends:

  • macOS: Keychain
  • Linux: GNOME Keyring, KDE Wallet, or any Secret Service implementation
  • Windows: Windows Credential Manager

After init or unlock, lockenv offers to save your password:

$ lockenv unlock
Enter password:
unlocked: .env

Save password to keyring? [y/N]: y
Password saved to keyring

Once saved, subsequent commands use the keyring automatically:

$ lockenv unlock
unlocked: .env  # No password prompt!
# Save password to keyring (verifies password first)
$ lockenv keyring save
Enter password:
Password saved to keyring

# Check keyring status
$ lockenv keyring status
Password: stored in keyring

# Remove from keyring
$ lockenv keyring delete
Password removed from keyring

If the vault password changes but the keyring has the old password, lockenv automatically detects this and prompts for the correct password:

$ lockenv unlock
Warning: keyring password is incorrect, removing stale entry
Enter password:
unlocked: .env
  • Passwords are stored using your OS's native secure storage
  • Each vault has a unique ID - moving .lockenv files preserves keyring association
  • The keyring is optional - lockenv works without it
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install lockenv
        run: |
          curl -sL https://github.com/illarion/lockenv/releases/latest/download/lockenv_linux_amd64.tar.gz | tar xz
          sudo mv lockenv /usr/local/bin/
      - name: Unlock secrets
        env:
          LOCKENV_PASSWORD: ${{ secrets.LOCKENV_PASSWORD }}
        run: lockenv unlock
deploy:
  before_script:
    - curl -sL https://github.com/illarion/lockenv/releases/latest/download/lockenv_linux_amd64.tar.gz | tar xz
    - mv lockenv /usr/local/bin/
    - lockenv unlock
  variables:
    LOCKENV_PASSWORD: $LOCKENV_PASSWORD
  • File size: Files are loaded entirely into memory for encryption. Not recommended for large binary files (>100MB).
  • Single password: One password for the entire vault. No per-user or per-file access control.

For feature requests or issues, see GitHub Issues.

联系我们 contact @ memedata.com