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
18 changes: 18 additions & 0 deletions .github/actions/trivy-iac/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: "Trivy IaC Scan"
description: "Scan Terraform IaC using Trivy"
runs:
using: "composite"
steps:
- name: "Trivy Terraform IaC Scan"
shell: bash
run: |
components_exit_code=0
modules_exit_code=0

./scripts/terraform/trivy-scan.sh --mode iac ./infrastructure/terraform/components || components_exit_code=$?
./scripts/terraform/trivy-scan.sh --mode iac ./infrastructure/terraform/modules || modules_exit_code=$?

if [ $components_exit_code -ne 0 ] || [ $modules_exit_code -ne 0 ]; then
echo "Trivy misconfigurations detected."
exit 1
fi
16 changes: 16 additions & 0 deletions .github/actions/trivy-package/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: "Trivy Package Scan"
description: "Scan project packages using Trivy"
runs:
using: "composite"
steps:
- name: "Trivy Package Scan"
shell: bash
run: |
exit_code=0

./scripts/terraform/trivy-scan.sh --mode package . || exit_code=$?

if [ $exit_code -ne 0 ]; then
echo "Trivy has detected package vulnerablilites. Please refer to https://nhsd-confluence.digital.nhs.uk/spaces/RIS/pages/1257636917/PLAT-KOP-012+-+Trivy+Pipeline+Vulnerability+Scanning+Exemption"
exit 1
fi
17 changes: 0 additions & 17 deletions .github/actions/trivy/action.yaml

This file was deleted.

194 changes: 194 additions & 0 deletions scripts/terraform/trivy-scan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#!/usr/bin/env bash

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

set -euo pipefail

function usage() {
cat <<'EOF'
Usage: ./scripts/terraform/trivy-scan.sh --mode <iac|package> [directory]

Options:
--mode, -m Scan type to run. Accepts "iac" or "package" (required).
--help, -h Show this message.
[directory] Directory to scan. Defaults to the repository root.

Environment variables:
FORCE_USE_DOCKER=true Force execution through Docker even if Trivy is installed locally.
VERBOSE=true Enable bash -x tracing.
EOF
}

function main() {
cd "$(git rev-parse --show-toplevel)"

local scan_mode=""
local dir_to_scan="."

while [[ $# -gt 0 ]]; do
case "$1" in
--mode|-m)
if [[ $# -lt 2 ]]; then
echo "Error: --mode requires an argument." >&2
usage
exit 1
fi
scan_mode="$2"
shift 2
;;
--help|-h)
usage
exit 0
;;
--)
shift
break
;;
-*)
echo "Unknown option: $1" >&2
usage
exit 1
;;
*)
dir_to_scan="$1"
shift
;;
esac
done

if [[ $# -gt 0 ]]; then
dir_to_scan="$1"
fi

if [[ -z "$scan_mode" ]]; then
echo "Error: --mode must be provided (iac|package)." >&2
usage
exit 1
fi

case "$scan_mode" in
iac|package)
;;
*)
echo "Error: unknown mode '$scan_mode'. Expected 'iac' or 'package'." >&2
usage
exit 1
;;
esac

if command -v trivy > /dev/null 2>&1 && ! is-arg-true "${FORCE_USE_DOCKER:-false}"; then
run-trivy-natively "$scan_mode" "$dir_to_scan"
else
run-trivy-in-docker "$scan_mode" "$dir_to_scan"
fi
}

function run-trivy-natively() {
local scan_mode="$1"
local dir_to_scan="$2"

echo "Trivy found locally, running natively"
echo "Running Trivy ($scan_mode) on directory: $dir_to_scan"

if execute-trivy-command "$scan_mode" "$dir_to_scan"; then
check-trivy-status 0
else
local status=$?
check-trivy-status "$status"
fi
}

function run-trivy-in-docker() {
# shellcheck disable=SC1091
source ./scripts/docker/docker.lib.sh

local scan_mode="$1"
local dir_to_scan="$2"

# shellcheck disable=SC2155
local image=$(name=aquasec/trivy docker-get-image-version-and-pull)

echo "Trivy not found locally, running in Docker Container"
echo "Running Trivy ($scan_mode) on directory: $dir_to_scan"

if execute-trivy-in-docker "$image" "$scan_mode" "$dir_to_scan"; then
check-trivy-status 0
else
local status=$?
check-trivy-status "$status"
fi
}

function execute-trivy-command() {
local scan_mode="$1"
local dir_to_scan="$2"

if [[ "$scan_mode" == "iac" ]]; then
trivy config \
--config scripts/config/trivy.yaml \
--tf-exclude-downloaded-modules \
"$dir_to_scan"
else
trivy \
--config scripts/config/trivy.yaml \
fs "$dir_to_scan" \
--scanners vuln \
--severity HIGH,CRITICAL \
--include-dev-deps
fi
}

function execute-trivy-in-docker() {
local image="$1"
local scan_mode="$2"
local dir_to_scan="$3"

if [[ "$scan_mode" == "iac" ]]; then
docker run --rm --platform linux/amd64 \
--volume "$PWD":/workdir \
--workdir /workdir \
"$image" \
config \
--config scripts/config/trivy.yaml \
--tf-exclude-downloaded-modules \
"$dir_to_scan"
else
docker run --rm --platform linux/amd64 \
--volume "$PWD":/workdir \
--workdir /workdir \
"$image" \
--config scripts/config/trivy.yaml \
fs "$dir_to_scan" \
--scanners vuln \
--severity HIGH,CRITICAL \
--include-dev-deps
fi
}

function check-trivy-status() {
local status="$1"

if [[ "$status" -eq 0 ]]; then
echo "Trivy completed successfully."
return 0
fi

echo "Trivy found issues."
exit "$status"
}

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
96 changes: 0 additions & 96 deletions scripts/terraform/trivy.sh

This file was deleted.

Loading