Skip to main content

Pre-receive

Prelude#

A pre-receive hook allows you to reject commits from being pushed to a git repository if they do not validate every check. Please refer to our learning center for more information.

Our pre-receive hook is performed through ggshield. ggshield is a wrapper around GitGuardian API for secrets detection that requires an API key to work.

Since pre-receive hooks are configured to run programmatically on the VCS instance, we recommend the use of a dedicated service account to authenticate ggshield calls. To create a service account, sign in to your GitGuardian workspace and go to the API section.

You can find ggshield's pre-receive hook samples in the doc/pre-receive.sample and doc/pre-receive-docker.sample.

Preview#

pre-receive preview

Gitlab Enterprise Edition and Bitbucket Server#

Install ggshield git pre-receive hook#

The sample script can be found in pre-receive.sample.

  1. This pre-receive hook requires the host machine to have python>=3.8 and pip installed

  2. Install ggshield from pip: pip install ggshield

  3. Move pre-receive.sample to .git/hooks/pre-receive or to your provider's git hook directory

  4. Mark the script executable with chmod +x .git/hooks/pre-receive

  5. Define the GITGUARDIAN_API_KEY environment variable. Either in a machine wide configuration file or in the .git/hooks/pre-receive file, as instructed in the sample file.

How do I add ignored matches and use a custom config in this pre-receive hook?

  • Create a gitguardian.yaml somewhere in the system. An example config file is available here.

  • Replace in the pre-receive hook

    ggshield secret scan pre-receive

    with:

    ggshield -c <INSERT path to gitguardian.yaml> scan pre-receive

Install ggshield git pre-receive hook with docker#

For the pre-receive hook to work, the directory where the repositories are stored must also be mounted on the container.

The sample script can be found in pre-receive-docker.sample

  1. This pre-receive hook requires the host machine to have docker installed.
  2. Move pre-receive-docker.sample to .git/hooks/pre-receive
  3. Do not forget to chmod +x .git/hooks/pre-receive
  4. either set an environment variable machine wide GITGUARDIAN_API_KEY or set it in the .git/hooks/pre-receive as instructed in the sample file.

GitHub Enterprise#

Installing a git pre-receive hook on GitHub Enterprise requires 2 components:

  • a script executed for each push event,
  • an environment to execute the script in.

For more information: visit GitHub Enterprise documentation about pre-receive hook

The pre-receive environment#

A pre-receive hook environment is a Linux chroot. It can be generated either from an existing chroot or from a Docker image. We recommend using the ggshield Docker image to create it.

ggshield running in a chroot, you need to provide the API key to this context. The pre-receive script has to be in a repository hosted in the Github Enterprise instance. Instead of setting its value in the script, the best practice is to store the value in a file within the environment.

To generate the pre-receive environment:

mkdir /tmp/ggshieldcd /tmp/ggshielddocker create --name ggshield-environment gitguardian/ggshield:latest /bin/truedocker export ggshield-environment -o ggshield-env-exporttar xf ggshield-env-exportrm etc/localtimecp usr/share/zoneinfo/Etc/UTC etc/localtimeecho <your_gitguardian_api_key> > app/api_keyrm ggshield-env-exporttar -czvf ggshield-environment.tar.gz .

You can then upload this file to the GitHub Enterprise Server and add it using the following command:

ghe-hook-env-create ggshield-environment ~/ggshield-environment.tar.gz

Or you can upload this file to a server and pass its URL to the GitHub Enterprise web user interface to add it.

Script#

You need to add the following script to a repository hosted in the GitHub Enterprise server:

#!/bin/bash
# If you don't use the Saas product, you need to setup your onprem public api url:# export GITGUARDIAN_API_URL=<your onprem public api url>export GITGUARDIAN_API_KEY=$(cat /app/api_key)/app/.venv/bin/ggshield secret scan pre-receive

This script file should have execute permission. Since the script name appears in the pre-receive hook result, we recommend to name it pre-receive.sh.

Create the pre-receive hook#

You are now able to follow GitHub Enterprise documentation to create the pre-receive hook.

Troubleshooting#

If you encounter the following error when pushing code:

$ git push origin main
Enumerating objects: 3, done.Counting objects: 100% (3/3), done.Writing objects: 100% (3/3), 231 bytes | 231.00 KiB/s, done.Total 3 (delta 0), reused 0 (delta 0), pack-reused 0remote: pre-receive.sh: failed with exit status 1remote: cp: '/etc/localtime' and '/tmp/hooks-overlay-1fFe7b/etc/localtime' are the same file
To https://my-ghe-instance.com/my-repository.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://my-ghe-instance.com/my-repository.git'

It is because the environment you provide contains a /etc/localtime pointing to the same file as the GitHub Enterprise Server. It is why we replace the /etc/localtime symlink with a copy of the file it originally targets.