Skip to content

Repository files navigation

Secure Large File Management for Git LFS

Bash scripts to encrypt large files with GPG before storing them in Git Large File Storage (LFS), and to decrypt them after checkout.

Table of Contents

Description

These scripts encrypt selected files with GPG (AES-256) so ciphertext (.gpg) can be tracked by Git LFS, and decrypt those files after clone or pull. They never default to walking the whole working tree, never store the passphrase in a shell variable, and never delete source files unless you ask.

Installation

Prerequisites

  • Git LFS
  • GPG
  • GNU shred (coreutils), only if you use --wipe-original

Steps

  1. Clone this repository or copy encrypt_large_files.sh, decrypt_large_files.sh, and secure_lfs_common.sh into the same directory.

  2. Make the scripts executable:

    chmod +x encrypt_large_files.sh decrypt_large_files.sh
  3. In the Git repository that will store the files, track ciphertext with LFS:

    git lfs install
    git lfs track '*.gpg'
    git add .gitattributes

Usage

Run the scripts from inside the Git repository. PATH is required. A bare directory is not recursive; only files larger than 100MB in that directory are encrypted. Pass an explicit file to encrypt it regardless of size.

./encrypt_large_files.sh --help
./decrypt_large_files.sh --help

Preview first:

./encrypt_large_files.sh --dry-run ./artifacts
./encrypt_large_files.sh --dry-run --recursive ./artifacts

Encrypt a single file, or large files in one directory:

./encrypt_large_files.sh secrets/dump.bin
./encrypt_large_files.sh ./artifacts

Encrypt recursively (still skips .git), then decrypt:

./encrypt_large_files.sh --recursive ./artifacts
./decrypt_large_files.sh --recursive ./artifacts

Source files are kept by default. Deletion is opt-in:

./encrypt_large_files.sh --delete-original secrets/dump.bin
./encrypt_large_files.sh --wipe-original secrets/dump.bin

--wipe-original overwrites with shred before unlink. That is not reliable on SSDs or journaled filesystems.

GPG prompts for the passphrase through pinentry (and gpg-agent may cache it for later files in the same run). The scripts never read the password into a Bash variable and never pass it on the command line.

Contributing

Contributions are welcome. Fork the repository, make your changes, and submit a pull request. See CONTRIBUTING.md.

License

MIT. Copyright © 2026 Vassbrekke AS.

Source: https://github.com/Vassbrekke/secure-git-lfs

Contact

contact@vassbrekke.no · vassbrekke.no

Release History

  • 1.1.0 - 2026-08-22
    • Require an explicit PATH; do not recurse from . by default
    • Leave passphrase handling to GPG pinentry
    • Make source deletion opt-in (--delete-original / --wipe-original)
    • Add --dry-run and refuse to encrypt unless the .gpg output is Git LFS-tracked
  • 1.0.0 - 2025-07-08
    • Initial release

Security Note

  • Pass a specific file or directory. Recursion is --recursive only.
  • Confirm the file list with --dry-run before encrypting.
  • Originals are not removed unless you pass --delete-original or --wipe-original.
  • Encryption is refused unless git check-attr reports filter=lfs for the .gpg output path.
  • Do not commit decrypted plaintext. Keep .gpg as the LFS-tracked artifact.
  • Prefer a GPG key pair or a proper secret manager if these files are long-lived secrets rather than a shared symmetric passphrase.

About

Secure Large File Management for Git LFS

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages