CodeWithYou

Using husky and git-secrets to prevent committing sensitive information to a git repository.

Published on
Authors
Using husky and git-secrets to prevent committing passwords and other sensitive information to a git repository.

This blog post will show you how to use husky and git-secrets to prevent committing passwords and other sensitive information to a git repository. This is a good idea because it reduces the risk of your API key and secret being exposed to your code.

What is husky?

Husky is a very popular (6 million downloads a week) npm package that allows custom scripts to be ran against your repository. Husky works with any project that uses a package. json file. Husky supports all Git hooks..

What is git-secrets?

git-secrets is a tool maintained by AWS Lab that allows you prevent committing passwords and other sensitive information to a git repository.

Advertisement

How to use husky and git-secrets?

Prerequisites: You must have git-secrets installed on your local PC. Install git-secrets with the following command:

brew install git-secrets

Check more information about git-secrets here

  1. Init husky with the following command:
npx husky-init && npm install       # npm
npx husky-init && yarn              # Yarn 1
yarn dlx husky-init --yarn2 && yarn # Yarn 2+
pnpm dlx husky-init && pnpm install # pnpm

It will setup husky, modify package.json and create a sample pre-commit hook that you can edit. By default, it will run npm test when you commit.

Look at the ./.husky/pre-commit hook file and it looks like this:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
  1. To prevent committing passwords and other sensitive information to a git repository, we need config husky with 3 following hooks:

    • pre-commit: Used to check if any of the files changed in the commit use prohibited patterns.
    • commit-msg: Used to determine if a commit message contains a prohibited patterns.
    • prepare-commit-msg: Used to determine if a merge commit will introduce a history that contains a prohibited pattern at any point. Please note that this hook is only invoked for non fast-forward merges.
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
npx husky add .husky/prepare-commit-msg 'npx --no -- commitlint --edit "$1"'

After that, you can see the following files:

  • .husky/commit-msg
  • .husky/prepare-commit-msg
  • .husky/pre-commit

Update the .husky/commit-msg with the following content:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Section for git-secrets
if ! command -v git-secrets &> /dev/null
then
    echo "git-secrets is not installed. Please run 'brew install git-secrets' or visit https://github.com/awslabs/git-secrets#installing-git-secrets"
    exit 1
fi

# Initialise git-secrets configuration
git-secrets --register-aws > /dev/null

echo "Running git-secrets..."
# Scans the commit message.
git-secrets --commit_msg_hook -- "$@"

Update the .husky/pre-commit with the following content:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Section for git-secrets
if ! command -v git-secrets &> /dev/null
then
    echo "git-secrets is not installed. Please run 'brew install git-secrets' or visit https://github.com/awslabs/git-secrets#installing-git-secrets"
    exit 1
fi

# Initialise git-secrets configuration
git-secrets --register-aws > /dev/null

echo "Running git-secrets..."
# Scans all files that are about to be committed.
git-secrets --pre_commit_hook -- "$@"

And finally, update the .husky/prepare-commit-msg with the following content:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"


# Section for git-secrets
if ! command -v git-secrets &> /dev/null
then
    echo "git-secrets is not installed. Please run 'brew install git-secrets' or visit https://github.com/awslabs/git-secrets#installing-git-secrets"
    exit 1
fi

# Initialise git-secrets configuration
git-secrets --register-aws > /dev/null

echo "Running git-secrets..."
# Determines if merging in a commit will introduce tainted history.
git-secrets --prepare_commit_msg_hook -- "$@"

You can see full example of the .husky/commit-msg, .husky/pre-commit and .husky/prepare-commit-msg files in the GitHub repository

How do git-secrets work?

Basically, git-secrets is a tool that scans the commit message and all files that are about to be committed. If the commit message or any of the files contain a prohibited pattern, git-secrets will prevent the commit.

  • AWS Access Key IDs via (A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]16
  • AWS Secret Access Key assignments via ":" or "=" surrounded by optional quotes
  • AWS account ID assignments via ":" or "=" surrounded by optional quotes
  • Allowed patterns for example AWS keys (AKIAIOSFODNN7EXAMPLE and wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)
  • Known credentials from ~/.aws/credentials

Test your code with husky and git-secrets

Let try add some sensitive information to git repository(.env) and commit it. You will see the following output and your commit will be blocked:

Possible mitigations:
- Mark false positives as allowed using: git config --add secrets.allowed ...
- Mark false positives as allowed by adding regular expressions to .gitallowed at repository's root directory
- List your configured patterns: git config --get-all secrets.patterns
- List your configured allowed patterns: git config --get-all secrets.allowed
- List your configured allowed patterns in .gitallowed at repository's root directory
- Use --no-verify if this is a one-time false positive
husky - pre-commit hook exited with code 1 (error)
[2022-08-23T03:11:01.932Z] > git config --get-all user.name [5ms]
[2022-08-23T03:11:01.936Z] > git config --get-all user.email [4ms]
[2022-08-23T03:11:03.018Z] > git ls-files --stage -- /Users/binhbui/Documents/my/blog-tutorials/.env [10ms]
[2022-08-23T03:11:03.028Z] > git cat-file -s c8ce8bd9956efefb64f7bbc60f07011eff44b164 [9ms]
[2022-08-23T03:11:03.044Z] > git show --textconv :.env [7ms]

Conclusion

  • You can see the full example of the .husky/commit-msg, .husky/pre-commit and .husky/prepare-commit-msg files in the GitHub repository
  • Storing and managing secrets like API keys and other credentials can be challenging, always make sure you think about the implications of storing sensitive information in source code. You can read more about this in the Security section
Advertisement