Secret Scanning in Azure DevOps with GitLeaks

As you might know, it is important to keep any private keys, passwords and/or other secrets away from your source control. Having secrets in source control poses many risks, the most important one being: you have no idea how or where those secrets will be stored once someone pulls your repository. If your repository is private, then you might argue that it is reasonably safe, but even then secrets will be stored in plain text on the pc of every person that works with the repository. Not a very secure way of working.

To prevent secrets from accidentally being added to source control, you can use a secret scanning tool. Preferably, have everyone working with the repository setup a pre-commit hook that checks if any potential secrets are staged. Unfortunately, you cannot always control the machines of the people checking in code. As an extra safety measure, you can also add some secret scanning to your Azure DevOps pipelines. The excellent tool GitLeaks provides a docker container to easily be able to run it. If you’re using Azure services, consider extending your GitLeaks configuration with the rules provided by Jesse Houwing.

First, create a .gitleaks.toml file in the root of your repository. Add any extra rules, like the ones mentioned above, and possibly add some allowlist rules to make sure you do not get any false positives. With this in place, you can do a local run to check if there are any secrets already in your repository. From your repository, run the following docker command:

docker run -v .:/path zricethezav/gitleaks:latest detect --source="/path" --verbose --redact -f "json"

Any secrets will be shown in the console output. Use this output to add any false positives to your allowlist in the .gitleaks.toml file.

The next step is to add it to a pipeline. The docker command to use will be very similar, only this time you only want to scan the commits of a pull request (before it is merged to main). To do this, you can add an argument --log-opts to the docker run command. --log-opts is the argument that GitLeaks will pas to a git log command, so the code to check is very configurable. In our case, we will do every commit on the current branch that is not on main by passing origin/main..HEAD.

In a pipeline, you would get the following yaml:

jobs:
- job: secrets
  displayName: scan for secrets
  pool:
    vmImage: ubuntu-22.04
  
  steps:
  - checkout: self

  - task: DockerInstaller@0
    inputs:
      dockerVersion: '17.09.0-ce'

  - script: docker run -v $(Build.SourcesDirectory):/path zricethezav/gitleaks:latest detect --source="/path" --log-opts="origin/main..HEAD" --verbose --redact -f "json"

If any secrets are found, it will automatically fail your pipeline. If your branch policies are setup correctly, you have now made it significantly harder to accidentally put any secrets into the repository.