Securing Secrets in Git with git-crypt: Encrypt Sensitive Files Without a Vault

Git tutorial - IT technology blog
Git tutorial - IT technology blog

A True Story: When Your .env File Catches a GitHub Bot’s Eye

A few years ago, a friend of mine accidentally committed a .env file containing all production database credentials to a public repository. In less than 2 minutes, the system logged tens of thousands of brute-force requests from automated bots. The result? The whole team had to stay up until 3 AM to rotate all API keys and clean up the database. According to a GitGuardian report, over 12.8 million secrets were exposed on GitHub in 2023 – don’t let yourself be the next victim.

Usually, we use .gitignore to “hide” sensitive files. However, when working in a team, sending configuration files via Slack, Telegram, or Google Drive creates a mess and security risks. git-crypt was created to solve exactly this: keep secrets right inside Git but in an encrypted format.

Comparing git-crypt with Other Solutions

Before jumping into the configuration, let’s take a quick look at where git-crypt stands compared to its competitors:

  • AWS Secrets Manager / HashiCorp Vault: Excellent for large enterprises. However, they come with costs ranging from dozens to hundreds of USD per month and take at least a few days to set up a complex key-fetching system.
  • Environment Variables on CI/CD: Only solves the deployment phase. Developers still have to manage .env files manually on their local machines.
  • git-crypt: Free, sets up in 5 minutes. Files on your machine are clear-text, but when you git push, Git automatically encrypts them into binary. This is the “sweet spot” choice for small to medium projects.

Why Do Developers Love git-crypt?

The best thing about git-crypt is its incredibly smooth workflow. You just git add and git commit as usual without changing your habits. For those without access, they only see a bunch of gibberish when opening the files on GitHub.

However, keep in mind: git-crypt does not support flexible permission revocation. If a member leaves the team, you will have to generate a new key and re-encrypt everything. If your team has high turnover, consider centralized management solutions like Doppler or Vault.

Detailed Guide to Implementing git-crypt

I will guide you through two ways: using a Symmetric Key (sharing a single key file) and GPG (managing by individual identity).

1. Quick Installation

For macOS, Homebrew is the easiest choice:

brew install git-crypt

If using Ubuntu or Debian:

sudo apt install git-crypt

2. Configuring Protected Files

First, initialize git-crypt in your project directory:

git-crypt init

Now, specify the files you want to encrypt via the .gitattributes file. For example, I want to protect the .env file and all certificates in the certs/ folder:

# .gitattributes file
.env filter=git-crypt diff=git-crypt
certs/*.pem filter=git-crypt diff=git-crypt
config/secrets.yml filter=git-crypt diff=git-crypt

Pro Tip: You must declare files in .gitattributes before you git add them. If you accidentally committed a file in clear-text previously, Git history will still retain the old traces. In that case, you must use tools like BFG Repo-Cleaner to wipe the old commit history.

3. Method 1: Using a Symmetric Key (Best for Small Teams)

This method generates a secret key file. You just need to send this file to your colleagues via secure channels like Bitwarden Send or 1Password.

To export the key, run the command:

git-crypt export-key ~/my-project.key

When a colleague clones the project, they just need to run the following command to decrypt all files:

git-crypt unlock /path/to/my-project.key

4. Method 2: Using GPG (More Professional and Secure)

With GPG, you don’t need to share a common key file. Each person uses their personal key, and you grant permissions to specific emails.

First, add yourself to the authorized list:

git-crypt add-gpg-user [email protected]

When there is a new member, they just need to send their GPG Public Key to you. You import that key and add them:

gpg --import colleague-public-key.asc
git-crypt add-gpg-user [email protected]

The system will automatically create a commit in the .git-crypt/ directory. Just push this commit, and you’re done. Your colleague only needs to type git-crypt unlock, and the computer will automatically find the matching key to unlock it.

Verifying the Results

To ensure no sensitive files were missed, run the command:

git-crypt status

The screen will display a list of files with an encrypted status. If an important file still shows not encrypted, check your .gitattributes file immediately.

Practical Tips to Avoid “Getting Burned”

After using git-crypt for a long time, I’ve gathered a few lessons learned:

  • Never encrypt .gitignore: Git needs to read this file in clear-text to know what to ignore.
  • Handling the Staging Area: If you modify .gitattributes but Git doesn’t update the encryption status, try git rm --cached <file> and then add it again.
  • Backup Your Key: If you lose the Symmetric Key, your data becomes permanent gibberish. Store it safely in a password manager.
  • CI/CD Integration: For GitHub Actions, store the key content in GitHub Secrets, then write it to a temporary file during the pipeline execution to run git-crypt unlock.

Git-crypt is an excellent balance between convenience and security. It keeps your repository ready-to-run while ensuring that malicious actors cannot read your most sensitive information.

Share: