Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/actions/scan-secrets/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: "Scan secrets"
description: "Scan secrets"
runs:
using: "composite"
steps:
- name: "Scan secrets"
shell: bash
run: |
# Please do not change this `check=whole-history` setting, as new patterns may be added or history may be rewritten.
check=whole-history ./scripts/githooks/scan-secrets.sh
3 changes: 3 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SEE: https://github.com/gitleaks/gitleaks/blob/master/README.md#gitleaksignore

cd9c0efec38c5d63053dd865e5d4e207c0760d91:docs/guides/Perform_static_analysis.md:generic-api-key:37
19 changes: 19 additions & 0 deletions scripts/config/gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SEE: https://github.com/gitleaks/gitleaks/#configuration

[extend]
useDefault = true # SEE: https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml

[[rules]]
description = "IPv4"
id = "ipv4"
regex = '''[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'''

[rules.allowlist]
regexTarget = "match"
regexes = [
# Exclude the private network IPv4 addresses as well as the DNS servers for Google and OpenDNS
'''(127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3}|0\.0\.0\.0|255\.255\.255\.255|8\.8\.8\.8|8\.8\.4\.4|208\.67\.222\.222|208\.67\.220\.220)''',
]

[allowlist]
paths = ['''.terraform.lock.hcl''', '''poetry.lock''', '''yarn.lock''']
40 changes: 40 additions & 0 deletions scripts/config/pre-commit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
repos:
- repo: local
hooks:
- id: scan-secrets
name: Scan secrets
entry: ./scripts/githooks/scan-secrets.sh
args: ["check=staged-changes"]
language: script
pass_filenames: false
- repo: local
hooks:
- id: check-file-format
name: Check file format
entry: ./scripts/githooks/check-file-format.sh
args: ["check=staged-changes"]
language: script
pass_filenames: false
- repo: local
hooks:
- id: check-markdown-format
name: Check Markdown format
entry: ./scripts/githooks/check-markdown-format.sh
args: ["check=staged-changes"]
language: script
pass_filenames: false
- repo: local
hooks:
- id: check-english-usage
name: Check English usage
entry: ./scripts/githooks/check-english-usage.sh
args: ["check=staged-changes"]
language: script
pass_filenames: false
- repo: local
hooks:
- id: lint-terraform
name: Lint Terraform
entry: ./scripts/githooks/check-terraform-format.sh
language: script
pass_filenames: false
111 changes: 111 additions & 0 deletions scripts/githooks/scan-secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/bin/bash

# WARNING: Please, DO NOT edit this file! It is maintained in the Repository Template (https://github.com/nhs-england-tools/repository-template). Raise a PR instead.

set -euo pipefail

# Pre-commit git hook to scan for secrets hard-coded in the codebase. This is a
# gitleaks command wrapper. It will run gitleaks natively if it is installed,
# otherwise it will run it in a Docker container.
#
# Usage:
# $ [options] ./scan-secrets.sh
#
# Options:
# check={whole-history,last-commit,staged-changes} # Type of the check to run, default is 'staged-changes'
# FORCE_USE_DOCKER=true # If set to true the command is run in a Docker container, default is 'false'
# VERBOSE=true # Show all the executed commands, default is 'false'
#
# Exit codes:
# 0 - No leaks present
# 1 - Leaks or error encountered
# 126 - Unknown flag

# ==============================================================================

function main() {

cd "$(git rev-parse --show-toplevel)"

if command -v gitleaks > /dev/null 2>&1 && ! is-arg-true "${FORCE_USE_DOCKER:-false}"; then
dir="$PWD"
cmd="$(get-cmd-to-run)" run-gitleaks-natively
else
dir="/workdir"
cmd="$(get-cmd-to-run)" run-gitleaks-in-docker
fi
}

# Get Gitleaks command to execute and configuration.
# Arguments (provided as environment variables):
# dir=[project's top-level directory]
function get-cmd-to-run() {

check=${check:-staged-changes}
case $check in
"whole-history")
cmd="detect --source $dir --verbose --redact"
;;
"last-commit")
cmd="detect --source $dir --verbose --redact --log-opts -1"
;;
"staged-changes")
cmd="protect --source $dir --verbose --staged"
;;
esac
# Include base line file if it exists
if [ -f "$dir/scripts/config/.gitleaks-baseline.json" ]; then
cmd="$cmd --baseline-path $dir/scripts/config/.gitleaks-baseline.json"
fi
# Include the config file
cmd="$cmd --config $dir/scripts/config/gitleaks.toml"

echo "$cmd"
}

# Run Gitleaks natively.
# Arguments (provided as environment variables):
# cmd=[command to run]
function run-gitleaks-natively() {

# shellcheck disable=SC2086
gitleaks $cmd
}

# Run Gitleaks in a Docker container.
# Arguments (provided as environment variables):
# cmd=[command to run]
# dir=[directory to mount as a volume]
function run-gitleaks-in-docker() {

# shellcheck disable=SC1091
source ./scripts/docker/docker.lib.sh

# shellcheck disable=SC2155
local image=$(name=ghcr.io/gitleaks/gitleaks docker-get-image-version-and-pull)
# shellcheck disable=SC2086
docker run --rm --platform linux/amd64 \
--volume "$PWD:$dir" \
--workdir $dir \
"$image" \
$cmd
}

# ==============================================================================

function is-arg-true() {

if [[ "$1" =~ ^(true|yes|y|on|1|TRUE|YES|Y|ON)$ ]]; then
return 0
else
return 1
fi
}

# ==============================================================================

is-arg-true "${VERBOSE:-false}" && set -x

main "$@"

exit 0