From 8b483e77846e288a0443b9e54a048d10c741abef Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 15:04:31 +0000 Subject: [PATCH 01/21] verify installs --- .github/workflows/build_all_images.yml | 21 +-- Makefile | 17 +- src/base/.devcontainer/Dockerfile | 6 +- src/base/.devcontainer/Dockerfile.tflint | 24 +++ src/base/.devcontainer/Dockerfile.zizmor | 24 +++ src/base/.devcontainer/devcontainer.json | 2 + .../scripts/install_aws_sam_cli.sh | 161 ++++++++++++++++++ .../scripts/install_github_release.sh | 54 ++++++ .../.devcontainer/scripts/root_install.sh | 15 +- .../scripts/requirements-user.txt | 1 - .../.devcontainer/scripts/vscode_install.sh | 3 - .../scripts/requirements-user.txt | 2 - .../.devcontainer/scripts/vscode_install.sh | 3 - .../scripts/requirements-user.txt | 2 - .../.devcontainer/scripts/vscode_install.sh | 3 - .../scripts/requirements-user.txt | 2 - .../.devcontainer/scripts/vscode_install.sh | 3 - .../.devcontainer/Dockerfile.tflint | 13 -- .../.devcontainer/scripts/install_tflint.sh | 48 ------ 19 files changed, 294 insertions(+), 110 deletions(-) create mode 100644 src/base/.devcontainer/Dockerfile.tflint create mode 100644 src/base/.devcontainer/Dockerfile.zizmor create mode 100755 src/base/.devcontainer/scripts/install_aws_sam_cli.sh create mode 100755 src/base/.devcontainer/scripts/install_github_release.sh delete mode 100644 src/languages/node_24_python_3_10/.devcontainer/scripts/requirements-user.txt delete mode 100644 src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt delete mode 100644 src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt delete mode 100644 src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt delete mode 100644 src/projects/eps-storage-terraform/.devcontainer/Dockerfile.tflint delete mode 100755 src/projects/eps-storage-terraform/.devcontainer/scripts/install_tflint.sh diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index 98484a0c..fb7fa3b4 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -37,9 +37,9 @@ jobs: build_tool_images: # build common tool images with a lower scoped github token - # as it uses a 3rd party docker image with github cli installed to verify attestation of tflint binary - # and we dont want to make a high scoped token available to that image - # token needs attestation read so it can verify attestation of tflint binary + # as it uses a 3rd party docker image with github cli installed to verify attestation of binaries downloaded from github + # and we don't want to make a high scoped token available to that image + # token needs attestation read so it can verify attestation of binaries name: Build tool images for on ${{ matrix.arch }} runs-on: '${{ matrix.runner }}' strategy: @@ -59,23 +59,14 @@ jobs: with: fetch-depth: 0 persist-credentials: false - - name: build_grype + - name: build_tools run: | - make build-grype + make build-tools docker save "local_grype:latest" -o grype_image.tar - - name: build_syft - run: | - make build-syft docker save "local_syft:latest" -o syft_image.tar - - name: build_grant - run: | - make build-grant docker save "local_grant:latest" -o grant_image.tar - - - name: build_tflint - run: | - make build-tflint docker save "local_tflint:latest" -o tflint_image.tar + docker save "local_zizmor:latest" -o zizmor_image.tar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Makefile b/Makefile index 140fdba4..92995189 100644 --- a/Makefile +++ b/Makefile @@ -91,11 +91,24 @@ build-tflint: else \ docker buildx build \ --secret id=GH_TOKEN,env=GITHUB_TOKEN \ - -f src/projects/eps-storage-terraform/.devcontainer/Dockerfile.tflint \ + -f src/base/.devcontainer/Dockerfile.tflint \ --tag local_tflint:latest \ - src/projects/eps-storage-terraform/.devcontainer/; \ + src/base/.devcontainer/; \ fi +build-zizmor: + @if docker image inspect local_zizmor:latest >/dev/null 2>&1; then \ + echo "Image local_zizmor:latest already exists. Skipping build."; \ + else \ + docker buildx build \ + --secret id=GH_TOKEN,env=GITHUB_TOKEN \ + -f src/base/.devcontainer/Dockerfile.zizmor \ + --tag local_zizmor:latest \ + src/base/.devcontainer/; \ + fi + +build-tools: build-syft build-grype build-grant build-tflint build-zizmor + build-image: build-syft build-grype build-grant build-tflint guard-CONTAINER_NAME guard-BASE_VERSION_TAG guard-BASE_FOLDER guard-IMAGE_TAG workspace_folder="$${CONTAINER_NAME}"; \ case "$${CONTAINER_NAME}" in \ diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index fe46e449..d6277458 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -1,20 +1,24 @@ FROM local_syft:latest AS syft-build FROM local_grype:latest AS grype-build FROM local_grant:latest AS grant-build +FROM local_zizmor:latest AS zizmor-build FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04 ARG SCRIPTS_DIR=/usr/local/share/eps ARG CONTAINER_NAME ARG IMAGE_TAG ARG TARGETARCH +ARG SAM_VERSION="v1.158.0" ENV SCRIPTS_DIR=${SCRIPTS_DIR} ENV CONTAINER_NAME=${CONTAINER_NAME} ENV TARGETARCH=${TARGETARCH} +ENV SAM_VERSION=${SAM_VERSION} COPY .tool-versions.asdf ${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf COPY --chmod=755 scripts/lifecycle/*.sh ${SCRIPTS_DIR}/ COPY --chmod=755 scripts/root_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/root_install.sh +COPY --chmod=755 scripts/install_aws_sam_cli.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh COPY --chmod=755 Mk ${SCRIPTS_DIR}/Mk WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} @@ -23,7 +27,7 @@ RUN ./root_install.sh COPY --from=syft-build /syft /usr/local/bin/syft COPY --from=grype-build /grype /usr/local/bin/grype COPY --from=grant-build /grant /usr/local/bin/grant - +COPY --from=zizmor-build /zizmor /usr/local/bin/zizmor COPY --chmod=755 scripts/vscode_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/vscode_install.sh USER vscode COPY --chown=vscode:vscode .tool-versions.asdf /home/vscode/.tool-versions.asdf diff --git a/src/base/.devcontainer/Dockerfile.tflint b/src/base/.devcontainer/Dockerfile.tflint new file mode 100644 index 00000000..2273aa33 --- /dev/null +++ b/src/base/.devcontainer/Dockerfile.tflint @@ -0,0 +1,24 @@ +FROM serversideup/github-cli:2.89.0 AS build +ARG TARGETARCH +ARG TFLINT_VERSION="v0.61.0" +COPY --chmod=755 scripts/install_github_release.sh /tmp/install_github_release.sh +RUN --mount=type=secret,id=GH_TOKEN,env=GH_TOKEN \ + case "${TARGETARCH}" in \ + x86_64|amd64) DOWNLOAD_BINARY=tflint_linux_amd64.zip ;; \ + aarch64|arm64) DOWNLOAD_BINARY=tflint_linux_arm64.zip ;; \ + *) echo "Unsupported TARGETARCH: ${TARGETARCH}" && exit 1 ;; \ + esac \ + && INSTALL_DIR=/tmp/tflint/ \ + ARCH="${TARGETARCH}" \ + VERSION="${TFLINT_VERSION}" \ + GITHUB_REPO="terraform-linters/tflint" \ + TOOL="tflint" \ + DOWNLOAD_BINARY="${DOWNLOAD_BINARY}" \ + VERIFY_BINARY_ATTESTATION="false" \ + VERIFY_CHECKSUM="true" \ + COMPRESSION="zip" \ + /tmp/install_github_release.sh + +FROM scratch +COPY --from=build /tmp/tflint/tflint /tflint +ENTRYPOINT ["/tflint"] diff --git a/src/base/.devcontainer/Dockerfile.zizmor b/src/base/.devcontainer/Dockerfile.zizmor new file mode 100644 index 00000000..bc504b3f --- /dev/null +++ b/src/base/.devcontainer/Dockerfile.zizmor @@ -0,0 +1,24 @@ +FROM serversideup/github-cli:2.89.0 AS build +ARG TARGETARCH +ARG ZIZMOR_VERSION="v1.24.1" +COPY --chmod=755 scripts/install_github_release.sh /tmp/install_github_release.sh +RUN --mount=type=secret,id=GH_TOKEN,env=GH_TOKEN \ + case "${TARGETARCH}" in \ + x86_64|amd64) DOWNLOAD_BINARY=zizmor-x86_64-unknown-linux-gnu.tar.gz ;; \ + aarch64|arm64) DOWNLOAD_BINARY=zizmor-aarch64-unknown-linux-gnu.tar.gz ;; \ + *) echo "Unsupported TARGETARCH: ${TARGETARCH}" && exit 1 ;; \ + esac \ + && INSTALL_DIR=/tmp/zizmor/ \ + ARCH="${TARGETARCH}" \ + VERSION="${ZIZMOR_VERSION}" \ + GITHUB_REPO="zizmorcore/zizmor" \ + TOOL="zizmor" \ + DOWNLOAD_BINARY="${DOWNLOAD_BINARY}" \ + VERIFY_BINARY_ATTESTATION="true" \ + VERIFY_CHECKSUM="false" \ + COMPRESSION="tar.gz" \ + /tmp/install_github_release.sh + +FROM scratch +COPY --from=build /tmp/zizmor/zizmor /zizmor +ENTRYPOINT ["/zizmor"] diff --git a/src/base/.devcontainer/devcontainer.json b/src/base/.devcontainer/devcontainer.json index 9b8e753c..a27fa6ee 100644 --- a/src/base/.devcontainer/devcontainer.json +++ b/src/base/.devcontainer/devcontainer.json @@ -21,7 +21,9 @@ "moby": "true", "installDockerBuildx": "true" }, + // fine to use github-cli feature here as it verifies the installation "ghcr.io/devcontainers/features/github-cli:1": {}, + // fine to use aws-cli feature here as it verifies the installation "ghcr.io/devcontainers/features/aws-cli:1": { "version": "latest" } diff --git a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh new file mode 100755 index 00000000..7fd7d2c4 --- /dev/null +++ b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +set -e + +VERSION=${VERSION:-"latest"} +VERBOSE=${VERBOSE:-"true"} + +PRIMARY_PUBLIC_KEY="-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.22 (GNU/Linux) + +mQINBGRuSzMBEADsqiwOy78w7F4+sshaMFRIwRGNRm94p5Qey2KMZBxekFtoryVD +D9jEOnvupx4tvhfBHz5EcUHCEOdl4MTqdBy6vVAshozgxVb9RE8JpECn5lw7XC69 +4Y7Gy1TKKQMEWtDXElkGxIFdUWvWjSnPlzfnoXwQYGeE93CUS3h5dImP22Yk1Ct6 +eGGhlcbg1X4L8EpFMj7GvcsU8f7ziVI/PyC1Xwy39Q8/I67ip5eU5ddxO/xHqrbL +YC7+8pJPbRMej2twT2LrcpWWYAbprMtRoa6WfE0/thoo3xhHpIMHdPfAA86ZNGIN +kRLjGUg7jnPTRW4Oin3pCc8nT4Tfc1QERkHm641gTC/jUvpmQsM6h/FUVP2i5iE/ +JHpJcMuL2Mg6zDo3x+3gTCf+Wqz3rZzxB+wQT3yryZs6efcQy7nROiRxYBxCSXX0 +2cNYzsYLb/bYaW8yqWIHD5IqKhw269gp2E5Khs60zgS3CorMb5/xHgXjUCVgcu8a +a8ncdf9fjl3WS5p0ohetPbO2ZjWv+MaqrZOmUIgKbA4RpWZ/fU97P5BW9ylwmIDB +sWy0cMxg8MlvSdLytPieogaM0qMg3u5qXRGBr6Wmevkty0qgnmpGGc5zPiUbtOE8 +CnFFqyxBpj5IOnG0KZGVihvn+iRxrv6GO7WWO92+Dc6m94U0EEiBR7QiOwARAQAB +tDRBV1MgU0FNIENMSSBQcmltYXJ5IDxhd3Mtc2FtLWNsaS1wcmltYXJ5QGFtYXpv +bi5jb20+iQI/BBMBCQApBQJkbkszAhsvBQkHhM4ABwsJCAcDAgEGFQgCCQoLBBYC +AwECHgECF4AACgkQQv1fenOtiFqTuhAAzi5+ju5UVOWqHKevOJSO08T4QB8HcqAE +SVO3mY6/j29knkcL8ubZP/DbpV7QpHPI2PB5qSXsiDTP3IYPbeY78zHSDjljaIK3 +njJLMScFeGPyfPpwMsuY4nzrRIgAtXShPA8N/k4ZJcafnpNqKj7QnPxiC1KaIQWm +pOtvb8msUF3/s0UTa5Ys/lNRhVC0eGg32ogXGdojZA2kHZWdm9udLo4CDrDcrQT7 +NtDcJASapXSQL63XfAS3snEc4e1941YxcjfYZ33rel8K9juyDZfi1slWR/L3AviI +QFIaqSHzyOtP1oinUkoVwL8ThevKD3Ag9CZflZLzNCV7yqlF8RlhEZ4zcE/3s9El +WzCFsozb5HfE1AZonmrDh3SyOEIBMcS6vG5dWnvJrAuSYv2rX38++K5Pr/MIAfOX +DOI1rtA+XDsHNv9lSwSy0lt+iClawZANO9IXCiN1rOYcVQlwzDFwCNWDgkwdOqS0 +gOA2f8NF9lE5nBbeEuYquoOl1Vy8+ICbgOFs9LoWZlnVh7/RyY6ssowiU9vGUnHI +L8f9jqRspIz/Fm3JD86ntZxLVGkeZUz62FqErdohYfkFIVcv7GONTEyrz5HLlnpv +FJ0MR0HjrMrZrnOVZnwBKhpbLocTsH+3t5It4ReYEX0f1DIOL/KRwPvjMvBVkXY5 +hblRVDQoOWc= +=d9oG +-----END PGP PUBLIC KEY BLOCK-----" + +SIGNER_PUBLIC_KEY="-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.22 (GNU/Linux) + +mQINBGgrxIgBEADGCTudveeeVbWpZDGX9Ni57mBRMVSJwQJ6F/PC34jw0DozxTtd +H+ZPsXLvLwerN/DVXbK8E1qNZ5RGptak8j7MPz+MC3n4txibEJpB61vpjJJM+9cC +7whaMLDT/SbykHYXdrnHqa8KsUJl7rPLJcaRN722NSxvYVMIOA9ffVXV7cfEyZi5 +MbYF2Gc9LNbKaknImIva7EKeeh2/wI6YCqC5yytyfWU5dL6oHXsgTnFL9mhziMxv +WhyzawyJG6EJZsJ3WLlbIKApN6XZSXyCxOvlBrebYZjD5v0nA+TJaQ7is8atjtOI +DGe0AViw7kO8ChTpjA7YG/Uu7n/Fy7qLF/3Nz0b6cBNjemjBazQ3A3KNCpi5hqFM +Uo1WpoVLr5CXQnc0B3fBUnTIoxi0Sk5MKjH9AbYxfgqEX0ZJB9hAlc6LIEy0Yru6 +MMBrIHE86IMl1NfE/DeLnCdPG23+1PttwyOt3+9z5QwmPe3VPpEfCySPcdxHKZSP +rLile8qDznEvlPDvQ0qkBxdMtVa2yct5VJkdqy6UrN2xa0dpspHjRUjHh/EY/xMt +fwMUjOKohaZ/1pjotCcksAsZWUxCNcFvLYxuxeytVk4F09Es1hj4ihhLUI+43/ic +3DHSEiext7Q8/UccNArkhSCT7UOvvL7QTuP+pjYTyiC8Vx6g/Y5Ht5+qywARAQAB +tDBBV1MgU0FNIENMSSBUZWFtIDxhd3Mtc2FtLWNsaS1zaWduZXJAYW1hem9uLmNv +bT6JAj8EEwEJACkFAmgrxIgCGy8FCQPCZwAHCwkIBwMCAQYVCAIJCgsEFgIDAQIe +AQIXgAAKCRBAlKuxvt/atJo6EAC/5C8uJs76W5f5V5XNAMzwBFiZuYpop3DRReCo +P68ZZylokAC9ShRZnIOujpDJtlNS7T/G00BzmcpspkYYE531ALaXcHWmb9XV0Ajg +J8iboAVBLY0C7mhL/cbJ3v9QlpXXjyTuhexkJCV8rdHVX/0H8WqTZplEaRuZ7p8q +PMxddg4ClwstYuH3O/dmNdlGqfb4Fqy8MnV1yGSXRs5Jf+sDlN2UO4mbpyk/mr1c +f/jFxmx86IkCWJVvdXWCVTe2AFy3NHCdLtdnEvFhokCOQd9wibUWX0j9vq4cVRZT +qamnpAQaOlH3lXOwrjqo8b1AIPoRWSfMtCYvh6kA8MAJv4cAznzXILSLtOE0mzaU +qp5qoy37wNIjeztX6c/q4wss05qTlJhnNu4s3nh5VHultooaYpmDxp+ala5TWeuM +KZDI4KdAGF4z0Raif+N53ndOYIiXkY0goUbsPCnVrCwoK9PjjyoJncq7c14wNl5O +IQUZEjyYAQDGZqs5XSfY4zW2cCXatrfozKF7R1kSU14DfJwPUyksoNAQEQezfXyq +kr0gfIWK1r2nMdqS7WgSx/ypS5kdyrHuPZdaYfEVtuezpoT2lQQxOSZqqlp5hI4R +nqmPte53WXJhbC0tgTIJWn+Uy/d5Q/aSIfD6o8gNLS1BDs1j1ku0XKu1sFCHUcZG +aerdsIkCHAQQAQkABgUCaCvFeAAKCRBC/V96c62IWt3/D/9gOLzWtz62lqJRCsri +wcA/yz88ayKb/GUv3FCT5Nd9JZt8y1tW+AE3SPTdcpfZmt5UN2sRzljO61mpKJzp +eBvYQ9og/34ZrRQqeg8bz02u34LKYl1gD0xY0bWtB7TGIxIZZYqZECoPR0Dp6ZzB +abzkRSsJkEk0vbZzJhfWFYs98qfp/G0suFSBE79O8Am33DB2jQ/Sollh1VmNE6Sv +EOgR6+2yEkS2D0+msJMa/V82v9gBTPnxSlNV1d8Dduvt9rbM3LoxiNXUgx/s52yY +U6H3bwUcQ3UY6uRe1UWo5QnMFcDwfg43+q5rmjB4xQyX/BaQyF5K0hZyG+42/pH1 +EMwl8qN617FTxo3hvQUi/cBahlhQ8EVYsGnHDVxLCisbq5iZvp7+XtmMy1Q417gT +EQRo8feJh31elGWlccVR2pZgIm1PQ69dzzseHnnKkGhifik0bDGo5/IH2EgI1KFn +SG399RMU/qRzOPLVP3i+zSJmhMqG8cnZaUwE5V4P21vQSclhhd2Hv/C4SVKNqA2i ++oZbHj2vAkuzTTL075AoANebEjPGqwsKZi5mWUE5Pa931JeiXxWZlEB7rkgQ1PAB +fsDBhYLt4MxCWAhifLMA6uQ4BhXu2RuXOqNfSbqa8jVF6DB6cD8eAHGpPKfJOl30 +LtZnq+n4SfeNbZjD2FQWZR4CrA== +=lHfs +-----END PGP PUBLIC KEY BLOCK-----" + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +apt_get_update() +{ + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi +} + +export DEBIAN_FRONTEND=noninteractive + +check_packages curl ca-certificates gpg dirmngr unzip bash-completion less + +verify_aws_sam_cli_gpg_signature() { + local filePath=$1 + local sigFilePath=$2 + tmp_dir="$(mktemp -d)" + trap 'rm -rf "${tmp_dir}"' EXIT + local awsGpgKeyring="${tmp_dir}/aws-sam-cli-public-key.gpg" + + echo "${PRIMARY_PUBLIC_KEY}" | gpg --dearmor > "${awsGpgKeyring}" + echo "${SIGNER_PUBLIC_KEY}" | gpg --dearmor >> "${awsGpgKeyring}" + + gpg --batch --quiet --no-default-keyring --keyring "${awsGpgKeyring}" --verify "${sigFilePath}" "${filePath}" + local status=$? + + return ${status} +} + +install() { + tmp_dir="$(mktemp -d)" + trap 'rm -rf "${tmp_dir}"' EXIT + + local scriptZipFile="${tmp_dir}/aws-sam-cli.zip" + local scriptSigFile="${tmp_dir}/aws-sam-cli.sig" + + architecture=$(dpkg --print-architecture) + case "${architecture}" in + amd64) architectureStr=x86_64 ;; + arm64) architectureStr=arm64 ;; + *) + echo "AWS SAM CLI does not support machine architecture '$architecture'. Please use an x86-64 or ARM64 machine." + exit 1 + esac + local scriptUrl=https://github.com/aws/aws-sam-cli/releases/download/${VERSION}/aws-sam-cli-linux-${architectureStr}.zip + echo "Downloading AWS SAM CLI from ${scriptUrl}..." + curl -fsSL "${scriptUrl}" -o "${scriptZipFile}" + curl -fsSL "${scriptUrl}.sig" -o "${scriptSigFile}" + + verify_aws_sam_cli_gpg_signature "$scriptZipFile" "$scriptSigFile" + if (( $? > 0 )); then + echo "Could not verify GPG signature of AWS CLI install script. Make sure you provided a valid version." + exit 1 + fi + echo "GPG signature of AWS SAM CLI install script verified successfully. Installing..." + unzip -q "${scriptZipFile}" -d "${tmp_dir}/aws-sam-cli" + "${tmp_dir}/aws-sam-cli/install" + + echo "AWS SAM CLI installed successfully." +} + +echo "(*) Installing AWS SAM CLI..." + +install + +# Clean up +rm -rf /var/lib/apt/lists/* + +echo "Done!" diff --git a/src/base/.devcontainer/scripts/install_github_release.sh b/src/base/.devcontainer/scripts/install_github_release.sh new file mode 100755 index 00000000..8873a65a --- /dev/null +++ b/src/base/.devcontainer/scripts/install_github_release.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +set -euo pipefail +export DEBIAN_FRONTEND=noninteractive + +DEFAULT_INSTALL_DIR="/usr/local/bin" +INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" + +if ! command -v curl >/dev/null 2>&1 || ! command -v unzip >/dev/null 2>&1; then + apt-get update + apt-get install -y --no-install-recommends curl unzip ca-certificates +fi + +if ! command -v gh >/dev/null 2>&1; then + echo "GitHub CLI (gh) is required for attestation verification but was not found" + exit 1 +fi + +if [ "${VERIFY_BINARY_ATTESTATION}" != "true" ] && [ "${VERIFY_CHECKSUM}" != "true" ]; then + echo "VERIFY_BINARY_ATTESTATION or VERIFY_CHECKSUM must be set to true" + exit 1 +fi + +BINARY_URL="https://github.com/${GITHUB_REPO}/releases/download/${VERSION}/${DOWNLOAD_BINARY}" +BINARY_ASSET_NAME="${DOWNLOAD_BINARY}" +CHECKSUMS_URL="https://github.com/${GITHUB_REPO}/releases/download/${VERSION}/checksums.txt" +tmp_dir="$(mktemp -d)" +trap 'rm -rf "${tmp_dir}"' EXIT + +curl -fsSL "${BINARY_URL}" -o "${tmp_dir}/${BINARY_ASSET_NAME}" +if [ "${VERIFY_BINARY_ATTESTATION}" == "true" ]; then + gh attestation verify "${tmp_dir}/${BINARY_ASSET_NAME}" -R "${GITHUB_REPO}" +fi + +if [ "${VERIFY_CHECKSUM}" == "true" ]; then + curl -fsSL "${CHECKSUMS_URL}" -o "${tmp_dir}/checksums.txt" + gh attestation verify "${tmp_dir}/checksums.txt" -R "${GITHUB_REPO}" + ( + cd "${tmp_dir}" + sha256sum --ignore-missing -c checksums.txt + ) +fi + +if [ "${COMPRESSION}" == "zip" ]; then + unzip -q "${tmp_dir}/${BINARY_ASSET_NAME}" -d "${tmp_dir}" +elif [ "${COMPRESSION}" == "tar.gz" ]; then + tar -xzf "${tmp_dir}/${BINARY_ASSET_NAME}" -C "${tmp_dir}" +else + echo "Unsupported compression format: ${COMPRESSION}" + exit 1 +fi + +mkdir -p "$INSTALL_DIR" +install -m 0755 "$tmp_dir/$TOOL" "${INSTALL_DIR}/${TOOL}" diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index 386f3981..5750a961 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -e + export DEBIAN_FRONTEND=noninteractive # Add amd64 architecture if on arm64 @@ -31,18 +32,8 @@ apt-get -y install --no-install-recommends htop vim curl git build-essential \ libreadline-dev wget llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev liblzma-dev netcat-traditional libyaml-dev uuid-runtime xxd unzip -# Download correct SAM CLI for arch -echo "Installing aws-sam cli" -if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" = "aarch64" ]; then - wget -O /tmp/aws-sam-cli.zip --no-verbose "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-arm64.zip" - else - wget -O /tmp/aws-sam-cli.zip --no-verbose "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip" - fi - unzip -q /tmp/aws-sam-cli.zip -d /tmp/aws-sam-cli - /tmp/aws-sam-cli/install - rm /tmp/aws-sam-cli.zip - rm -rf /tmp/aws-sam-cli - +# install AWS SAM CLI +VERSION="${SAM_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh" # Install ASDF echo "Installing asdf" ASDF_VERSION=$(awk '!/^#/ && NF {print $1; exit}' "${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf") diff --git a/src/languages/node_24_python_3_10/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_10/.devcontainer/scripts/requirements-user.txt deleted file mode 100644 index 37e7b2fe..00000000 --- a/src/languages/node_24_python_3_10/.devcontainer/scripts/requirements-user.txt +++ /dev/null @@ -1 +0,0 @@ -zizmor==1.23.1 diff --git a/src/languages/node_24_python_3_10/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_10/.devcontainer/scripts/vscode_install.sh index a82f26f5..f13cedf2 100755 --- a/src/languages/node_24_python_3_10/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_10/.devcontainer/scripts/vscode_install.sh @@ -1,11 +1,8 @@ #!/usr/bin/env bash set -e -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install - -pip install --user -r "${SCRIPT_DIR}/requirements-user.txt" diff --git a/src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt deleted file mode 100644 index ac968564..00000000 --- a/src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt +++ /dev/null @@ -1,2 +0,0 @@ -zizmor==1.23.1 -cfn-lint==1.47.1 diff --git a/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh index a82f26f5..f13cedf2 100755 --- a/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh @@ -1,11 +1,8 @@ #!/usr/bin/env bash set -e -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install - -pip install --user -r "${SCRIPT_DIR}/requirements-user.txt" diff --git a/src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt deleted file mode 100644 index ac968564..00000000 --- a/src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt +++ /dev/null @@ -1,2 +0,0 @@ -zizmor==1.23.1 -cfn-lint==1.47.1 diff --git a/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh index a82f26f5..f13cedf2 100755 --- a/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh @@ -1,11 +1,8 @@ #!/usr/bin/env bash set -e -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install - -pip install --user -r "${SCRIPT_DIR}/requirements-user.txt" diff --git a/src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt deleted file mode 100644 index ac968564..00000000 --- a/src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt +++ /dev/null @@ -1,2 +0,0 @@ -zizmor==1.23.1 -cfn-lint==1.47.1 diff --git a/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh index a82f26f5..f13cedf2 100755 --- a/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh @@ -1,11 +1,8 @@ #!/usr/bin/env bash set -e -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install - -pip install --user -r "${SCRIPT_DIR}/requirements-user.txt" diff --git a/src/projects/eps-storage-terraform/.devcontainer/Dockerfile.tflint b/src/projects/eps-storage-terraform/.devcontainer/Dockerfile.tflint deleted file mode 100644 index d6a1e223..00000000 --- a/src/projects/eps-storage-terraform/.devcontainer/Dockerfile.tflint +++ /dev/null @@ -1,13 +0,0 @@ -FROM serversideup/github-cli:2.89.0 AS build -ARG TARGETARCH -ARG TFLINT_VERSION="v0.61.0" -COPY --chmod=755 scripts/install_tflint.sh /tmp/install_tflint.sh -RUN --mount=type=secret,id=GH_TOKEN,env=GH_TOKEN \ - INSTALL_DIR=/tmp/tflint/ \ - ARCH="${TARGETARCH}" \ - VERSION="${TFLINT_VERSION}" \ - /tmp/install_tflint.sh - -FROM scratch -COPY --from=build /tmp/tflint/tflint /tflint -ENTRYPOINT ["/tflint"] diff --git a/src/projects/eps-storage-terraform/.devcontainer/scripts/install_tflint.sh b/src/projects/eps-storage-terraform/.devcontainer/scripts/install_tflint.sh deleted file mode 100755 index 1f62116e..00000000 --- a/src/projects/eps-storage-terraform/.devcontainer/scripts/install_tflint.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -export DEBIAN_FRONTEND=noninteractive - -DEFAULT_INSTALL_DIR="/usr/local/bin" -INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" - -case "${TARGETARCH:-}" in - amd64|arm64) - TFLINT_ARCH="${TARGETARCH}" - ;; - *) - echo "Unsupported or missing TARGETARCH: '${TARGETARCH:-}'" - echo "Expected one of: amd64, arm64" - exit 1 - ;; -esac - -if ! command -v curl >/dev/null 2>&1 || ! command -v unzip >/dev/null 2>&1; then - apt-get update - apt-get install -y --no-install-recommends curl unzip ca-certificates -fi - -if ! command -v gh >/dev/null 2>&1; then - echo "GitHub CLI (gh) is required for attestation verification but was not found" - exit 1 -fi - -TFLINT_URL="https://github.com/terraform-linters/tflint/releases/download/${TFLINT_VERSION}/tflint_linux_${TFLINT_ARCH}.zip" -TFLINT_ASSET_NAME="tflint_linux_${TFLINT_ARCH}.zip" -CHECKSUMS_URL="https://github.com/terraform-linters/tflint/releases/download/${TFLINT_VERSION}/checksums.txt" -tmp_dir="$(mktemp -d)" -trap 'rm -rf "${tmp_dir}"' EXIT - -curl -fsSL "${CHECKSUMS_URL}" -o "${tmp_dir}/checksums.txt" -gh attestation verify "${tmp_dir}/checksums.txt" -R terraform-linters/tflint - -curl -fsSL "${TFLINT_URL}" -o "${tmp_dir}/${TFLINT_ASSET_NAME}" -( - cd "${tmp_dir}" - sha256sum --ignore-missing -c checksums.txt -) - -unzip -q "${tmp_dir}/${TFLINT_ASSET_NAME}" -d "${tmp_dir}" - -mkdir -p "$INSTALL_DIR" -install -m 0755 "$tmp_dir/tflint" "${INSTALL_DIR}/tflint" From 59c6589eeba73e958103bbf66039fe4a465b76a3 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 18:16:21 +0000 Subject: [PATCH 02/21] verify asdfa --- src/base/.devcontainer/.tool-versions.asdf | 2 - src/base/.devcontainer/Dockerfile | 5 +- .../.devcontainer/scripts/install_asdf.sh | 56 +++++++++++++++++++ .../.devcontainer/scripts/root_install.sh | 12 +--- 4 files changed, 60 insertions(+), 15 deletions(-) delete mode 100644 src/base/.devcontainer/.tool-versions.asdf create mode 100755 src/base/.devcontainer/scripts/install_asdf.sh diff --git a/src/base/.devcontainer/.tool-versions.asdf b/src/base/.devcontainer/.tool-versions.asdf deleted file mode 100644 index 9ee20c51..00000000 --- a/src/base/.devcontainer/.tool-versions.asdf +++ /dev/null @@ -1,2 +0,0 @@ -# define the .asdf-version to use here -0.18.1 diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index d6277458..827959b6 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -9,16 +9,18 @@ ARG CONTAINER_NAME ARG IMAGE_TAG ARG TARGETARCH ARG SAM_VERSION="v1.158.0" +ARG ASDF_VERSION="v0.18.1" ENV SCRIPTS_DIR=${SCRIPTS_DIR} ENV CONTAINER_NAME=${CONTAINER_NAME} ENV TARGETARCH=${TARGETARCH} ENV SAM_VERSION=${SAM_VERSION} +ENV ASDF_VERSION=${ASDF_VERSION} -COPY .tool-versions.asdf ${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf COPY --chmod=755 scripts/lifecycle/*.sh ${SCRIPTS_DIR}/ COPY --chmod=755 scripts/root_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/root_install.sh COPY --chmod=755 scripts/install_aws_sam_cli.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh +COPY --chmod=755 scripts/install_asdf.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_asdf.sh COPY --chmod=755 Mk ${SCRIPTS_DIR}/Mk WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} @@ -30,7 +32,6 @@ COPY --from=grant-build /grant /usr/local/bin/grant COPY --from=zizmor-build /zizmor /usr/local/bin/zizmor COPY --chmod=755 scripts/vscode_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/vscode_install.sh USER vscode -COPY --chown=vscode:vscode .tool-versions.asdf /home/vscode/.tool-versions.asdf COPY --chown=vscode:vscode .tool-versions /home/vscode/.tool-versions COPY --chown=vscode:vscode .grant.yaml /home/vscode/.grant.yaml diff --git a/src/base/.devcontainer/scripts/install_asdf.sh b/src/base/.devcontainer/scripts/install_asdf.sh new file mode 100755 index 00000000..b3c180ef --- /dev/null +++ b/src/base/.devcontainer/scripts/install_asdf.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +VERSION=${VERSION:-"v0.18.1"} +# Expected SHA256 checksums taken from https://github.com/asdf-vm/asdf/releases/tag/v0.18.1 +# When we change asdf versions, these must be changed +sha256sum_expected_arm="sha256:1850faf576cab7acb321e99dd98d3fe0d4665e1331086ad9ed991aeec1dc9d36" +sha256sum_expected_amd64="sha256:56141dc99eab75c140dcdd85cf73f3b82fed2485a8dccd4f11a4dc5cbcb6ea5c" + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi +} + +check_packages curl ca-certificates tar sha256sum + +install() { + tmp_dir="$(mktemp -d)" + trap 'rm -rf "${tmp_dir}"' EXIT + + download_file="${tmp_dir}/asdf.tar.gz" + + if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then + download_url="https://github.com/asdf-vm/asdf/releases/download/${VERSION}/asdf-${VERSION}-linux-arm64.tar.gz" + sha256sum_expected="${sha256sum_expected_arm}" + else + download_url="https://github.com/asdf-vm/asdf/releases/download/${VERSION}/asdf-${VERSION}-linux-amd64.tar.gz" + sha256sum_expected="${sha256sum_expected_amd64}" + fi + curl -fsSL "${download_url}" -o "${download_file}" + + download_file_sha256sum=$(sha256sum "${download_file}" | awk '{print $1}') + if [ "${download_file_sha256sum}" != "${sha256sum_expected#sha256:}" ]; then + echo "SHA256 checksum mismatch for downloaded asdf archive" + echo "Expected: ${sha256sum_expected}" + echo "Actual: sha256:${download_file_sha256sum}" + exit 1 + fi + + tar -xzf "${download_file}" -C "${tmp_dir}" + mkdir -p /usr/bin + mv "${tmp_dir}/asdf" /usr/bin/asdf + chmod +x /usr/bin/asdf +} +echo "(*) Installing asdf..." + +install + +echo "Done!" diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index 5750a961..d0663269 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -36,17 +36,7 @@ apt-get -y install --no-install-recommends htop vim curl git build-essential \ VERSION="${SAM_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh" # Install ASDF echo "Installing asdf" -ASDF_VERSION=$(awk '!/^#/ && NF {print $1; exit}' "${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf") -if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then - wget -O /tmp/asdf.tar.gz --no-verbose "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-arm64.tar.gz" -else - wget -O /tmp/asdf.tar.gz --no-verbose "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-amd64.tar.gz" -fi -tar -xzf /tmp/asdf.tar.gz -C /tmp -mkdir -p /usr/bin -mv /tmp/asdf /usr/bin/asdf -chmod +x /usr/bin/asdf -rm -rf /tmp/asdf.tar.gz +VERSION="${ASDF_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_asdf.sh" # install gitsecrets git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets From e92681d0b42055e33f6d2d40a03615eb085eeb85 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 18:27:59 +0000 Subject: [PATCH 03/21] add gitleaks --- src/base/.devcontainer/Dockerfile | 4 +- .../.devcontainer/scripts/install_gitleaks.sh | 57 +++++++++++++++++++ .../.devcontainer/scripts/root_install.sh | 3 + 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100755 src/base/.devcontainer/scripts/install_gitleaks.sh diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index 827959b6..dd61623e 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -10,17 +10,19 @@ ARG IMAGE_TAG ARG TARGETARCH ARG SAM_VERSION="v1.158.0" ARG ASDF_VERSION="v0.18.1" +ARG GITLEAKS_VERSION="8.30.1" ENV SCRIPTS_DIR=${SCRIPTS_DIR} ENV CONTAINER_NAME=${CONTAINER_NAME} ENV TARGETARCH=${TARGETARCH} ENV SAM_VERSION=${SAM_VERSION} ENV ASDF_VERSION=${ASDF_VERSION} - +ENV GITLEAKS_VERSION=${GITLEAKS_VERSION} COPY --chmod=755 scripts/lifecycle/*.sh ${SCRIPTS_DIR}/ COPY --chmod=755 scripts/root_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/root_install.sh COPY --chmod=755 scripts/install_aws_sam_cli.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh COPY --chmod=755 scripts/install_asdf.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_asdf.sh +COPY --chmod=755 scripts/install_gitleaks.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_gitleaks.sh COPY --chmod=755 Mk ${SCRIPTS_DIR}/Mk WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} diff --git a/src/base/.devcontainer/scripts/install_gitleaks.sh b/src/base/.devcontainer/scripts/install_gitleaks.sh new file mode 100755 index 00000000..f21b6cd1 --- /dev/null +++ b/src/base/.devcontainer/scripts/install_gitleaks.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +VERSION=${VERSION:-"8.30.1"} +# Expected SHA256 checksums taken from https://github.com/gitleaks/gitleaks/releases/tag/v8.30.1 +# When we change gitleaks versions, these must be changed +sha256sum_expected_arm="sha256:e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080" +sha256sum_expected_amd64="sha256:551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb" + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi +} + +check_packages curl ca-certificates tar sha256sum + +install() { + tmp_dir="$(mktemp -d)" + trap 'rm -rf "${tmp_dir}"' EXIT + + download_file="${tmp_dir}/gitleaks.tar.gz" + + if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then + download_url="https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_arm64.tar.gz" + sha256sum_expected="${sha256sum_expected_arm}" + else + download_url="https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" + sha256sum_expected="${sha256sum_expected_amd64}" + fi + echo "Downloading gitleaks from ${download_url}..." + curl -fsSL "${download_url}" -o "${download_file}" + + download_file_sha256sum=$(sha256sum "${download_file}" | awk '{print $1}') + if [ "${download_file_sha256sum}" != "${sha256sum_expected#sha256:}" ]; then + echo "SHA256 checksum mismatch for downloaded gitleaks archive" + echo "Expected: ${sha256sum_expected}" + echo "Actual: sha256:${download_file_sha256sum}" + exit 1 + fi + + tar -xzf "${download_file}" -C "${tmp_dir}" + mkdir -p /usr/bin + mv "${tmp_dir}/gitleaks" /usr/bin/gitleaks + chmod +x /usr/bin/gitleaks +} +echo "(*) Installing gitleaks..." + +install + +echo "Done!" diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index d0663269..d63229bc 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -37,6 +37,9 @@ VERSION="${SAM_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.s # Install ASDF echo "Installing asdf" VERSION="${ASDF_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_asdf.sh" +# install gitleaks +echo "Installing gitleaks" +VERSION="${GITLEAKS_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_gitleaks.sh" # install gitsecrets git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets From ab1dfd5a92b4ad1433bb76ae778ef579f8d849b5 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 18:43:28 +0000 Subject: [PATCH 04/21] phony --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 92995189..10dd0cb1 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ guard-%: .PHONY: install install-python install-node install-hooks build-base-image build-node-24-image build-node-24-python-3-10-image build-node-24-python-3-12-image build-node-24-python-3-13-image build-node-24-python-3-14-image \ build-eps-storage-terraform-image build-eps-data-extract-image build-fhir-facade-image build-node-24-python-3-14-golang-1-24-image build-node-24-python-3-14-java-24-image \ build-regression-tests-image build-all build-image build-githubactions-image scan-image scan-image-json shell-image lint test lint-githubactions lint-githubaction-scripts clean \ - build-syft build-grype build-grant build-tflint + build-syft build-grype build-grant build-tflint build-tools build-zizmor install: install-python install-node install-hooks install-python: From 076d4e059434de5a56dea7e6e38541c22ffd6e0f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 18:49:58 +0000 Subject: [PATCH 05/21] update secret-scan target --- src/base/.devcontainer/Mk/check.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/base/.devcontainer/Mk/check.mk b/src/base/.devcontainer/Mk/check.mk index 2bf0a03f..e0fde3ab 100644 --- a/src/base/.devcontainer/Mk/check.mk +++ b/src/base/.devcontainer/Mk/check.mk @@ -84,7 +84,11 @@ actionlint: actionlint secret-scan: - git-secrets --scan-history . + @if [ -f .gitignore ]; then \ + git-secrets --scan-history .; \ + else \ + gitleaks -v git; \ + fi guard-%: @ if [ "${${*}}" = "" ]; then \ From ee2515c14ea6751d77397af8f49262dc13c560af Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 18:51:49 +0000 Subject: [PATCH 06/21] fix --- src/base/.devcontainer/Mk/check.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/.devcontainer/Mk/check.mk b/src/base/.devcontainer/Mk/check.mk index e0fde3ab..73a7b0da 100644 --- a/src/base/.devcontainer/Mk/check.mk +++ b/src/base/.devcontainer/Mk/check.mk @@ -84,7 +84,7 @@ actionlint: actionlint secret-scan: - @if [ -f .gitignore ]; then \ + @if [ -f .gitallowed ]; then \ git-secrets --scan-history .; \ else \ gitleaks -v git; \ From d678d60c21ee9c39a478930068b8ccb987abe14a Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 19:18:33 +0000 Subject: [PATCH 07/21] fix scripts --- src/base/.devcontainer/Dockerfile | 3 + .../.devcontainer/scripts/install_asdf.sh | 4 +- .../scripts/install_aws_sam_cli.sh | 12 +--- .../scripts/install_cfn_guard.sh | 55 +++++++++++++++++++ .../scripts/install_github_release.sh | 2 +- .../.devcontainer/scripts/install_gitleaks.sh | 4 +- .../.devcontainer/scripts/root_install.sh | 3 +- .../.devcontainer/scripts/vscode_install.sh | 5 +- 8 files changed, 68 insertions(+), 20 deletions(-) create mode 100755 src/base/.devcontainer/scripts/install_cfn_guard.sh diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index dd61623e..7650b81d 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -11,6 +11,7 @@ ARG TARGETARCH ARG SAM_VERSION="v1.158.0" ARG ASDF_VERSION="v0.18.1" ARG GITLEAKS_VERSION="8.30.1" +ARG CFN_GUARD_VERSION="3.2.0" ENV SCRIPTS_DIR=${SCRIPTS_DIR} ENV CONTAINER_NAME=${CONTAINER_NAME} @@ -18,11 +19,13 @@ ENV TARGETARCH=${TARGETARCH} ENV SAM_VERSION=${SAM_VERSION} ENV ASDF_VERSION=${ASDF_VERSION} ENV GITLEAKS_VERSION=${GITLEAKS_VERSION} +ENV CFN_GUARD_VERSION=${CFN_GUARD_VERSION} COPY --chmod=755 scripts/lifecycle/*.sh ${SCRIPTS_DIR}/ COPY --chmod=755 scripts/root_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/root_install.sh COPY --chmod=755 scripts/install_aws_sam_cli.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh COPY --chmod=755 scripts/install_asdf.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_asdf.sh COPY --chmod=755 scripts/install_gitleaks.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_gitleaks.sh +COPY --chmod=755 scripts/install_cfn_guard.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/install_cfn_guard.sh COPY --chmod=755 Mk ${SCRIPTS_DIR}/Mk WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} diff --git a/src/base/.devcontainer/scripts/install_asdf.sh b/src/base/.devcontainer/scripts/install_asdf.sh index b3c180ef..abad77fd 100755 --- a/src/base/.devcontainer/scripts/install_asdf.sh +++ b/src/base/.devcontainer/scripts/install_asdf.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail VERSION=${VERSION:-"v0.18.1"} # Expected SHA256 checksums taken from https://github.com/asdf-vm/asdf/releases/tag/v0.18.1 @@ -14,12 +15,11 @@ fi # Checks if packages are installed and installs them if not check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update apt-get -y install --no-install-recommends "$@" fi } -check_packages curl ca-certificates tar sha256sum +check_packages curl ca-certificates tar install() { tmp_dir="$(mktemp -d)" diff --git a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh index 7fd7d2c4..00741b70 100755 --- a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh +++ b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash - -set -e +set -euo pipefail VERSION=${VERSION:-"latest"} VERBOSE=${VERBOSE:-"true"} @@ -83,18 +82,9 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -apt_get_update() -{ - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - apt-get update -y - fi -} - # Checks if packages are installed and installs them if not check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update apt-get -y install --no-install-recommends "$@" fi } diff --git a/src/base/.devcontainer/scripts/install_cfn_guard.sh b/src/base/.devcontainer/scripts/install_cfn_guard.sh new file mode 100755 index 00000000..82510e77 --- /dev/null +++ b/src/base/.devcontainer/scripts/install_cfn_guard.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -euo pipefail + +VERSION=${VERSION:-"3.2.0"} +# Expected SHA256 checksums taken from https://github.com/aws-cloudformation/cloudformation-guard/releases/tag/3.2.0 +# When we change gitleaks versions, these must be changed +sha256sum_expected_arm="sha256:d562e14831794a4859782f5609186970373e8e0a049fbded2c01612d2dcdb087" +sha256sum_expected_amd64="sha256:9f8c4d9f15f7dd54a37ea70a5237ba00aba682fb1e6521a744d12259961dfc13" + + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + sudo apt-get -y install --no-install-recommends "$@" + fi +} + +check_packages curl ca-certificates tar + +install() { + tmp_dir="$(mktemp -d)" + trap 'rm -rf "${tmp_dir}"' EXIT + + download_file="${tmp_dir}/gitleaks.tar.gz" + + if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then + download_url="https://github.com/aws-cloudformation/cloudformation-guard/releases/download/${VERSION}/cfn-guard-v3-aarch64-ubuntu-latest.tar.gz" + arch_type="aarch64" + sha256sum_expected="${sha256sum_expected_arm}" + else + download_url="https://github.com/aws-cloudformation/cloudformation-guard/releases/download/${VERSION}/cfn-guard-v3-x86_64-ubuntu-latest.tar.gz" + arch_type="x86_64" + sha256sum_expected="${sha256sum_expected_amd64}" + fi + echo "Downloading cfn-guard from ${download_url}..." + curl -fsSL "${download_url}" -o "${download_file}" + + download_file_sha256sum=$(sha256sum "${download_file}" | awk '{print $1}') + if [ "${download_file_sha256sum}" != "${sha256sum_expected#sha256:}" ]; then + echo "SHA256 checksum mismatch for downloaded cfn-guard archive" + echo "Expected: ${sha256sum_expected}" + echo "Actual: sha256:${download_file_sha256sum}" + exit 1 + fi + + tar -xzf "${download_file}" -C "${tmp_dir}" + mkdir -p ~/.guard/bin + mv "${tmp_dir}/cfn-guard-v3-${arch_type}-ubuntu-latest/cfn-guard" ~/.guard/bin/cfn-guard + chmod +x ~/.guard/bin/cfn-guard +} +echo "(*) Installing cfn-guard..." + +install + +echo "Done!" diff --git a/src/base/.devcontainer/scripts/install_github_release.sh b/src/base/.devcontainer/scripts/install_github_release.sh index 8873a65a..daa51034 100755 --- a/src/base/.devcontainer/scripts/install_github_release.sh +++ b/src/base/.devcontainer/scripts/install_github_release.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash - set -euo pipefail + export DEBIAN_FRONTEND=noninteractive DEFAULT_INSTALL_DIR="/usr/local/bin" diff --git a/src/base/.devcontainer/scripts/install_gitleaks.sh b/src/base/.devcontainer/scripts/install_gitleaks.sh index f21b6cd1..2d00a6fa 100755 --- a/src/base/.devcontainer/scripts/install_gitleaks.sh +++ b/src/base/.devcontainer/scripts/install_gitleaks.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail VERSION=${VERSION:-"8.30.1"} # Expected SHA256 checksums taken from https://github.com/gitleaks/gitleaks/releases/tag/v8.30.1 @@ -14,12 +15,11 @@ fi # Checks if packages are installed and installs them if not check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update apt-get -y install --no-install-recommends "$@" fi } -check_packages curl ca-certificates tar sha256sum +check_packages curl ca-certificates tar install() { tmp_dir="$(mktemp -d)" diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index d63229bc..11da747e 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -e +set -euo pipefail export DEBIAN_FRONTEND=noninteractive @@ -42,6 +42,7 @@ echo "Installing gitleaks" VERSION="${GITLEAKS_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_gitleaks.sh" # install gitsecrets +# this should be removed once we have migrated all repos to gitleaks git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets cd /tmp/git-secrets make install diff --git a/src/base/.devcontainer/scripts/vscode_install.sh b/src/base/.devcontainer/scripts/vscode_install.sh index e14f35ac..49c07c7f 100755 --- a/src/base/.devcontainer/scripts/vscode_install.sh +++ b/src/base/.devcontainer/scripts/vscode_install.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash - -set -e +set -euo pipefail # shellcheck disable=SC2129 # shellcheck disable=SC2016 @@ -21,7 +20,7 @@ asdf plugin add terraform https://github.com/asdf-community/asdf-hashicorp.git asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git # install cfn-guard -curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh +VERSION="${CFN_GUARD_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_cfn_guard.sh" # install base asdf versions of common tools cd /home/vscode From 74c6d02b9c8f651fe7f8c2d329761b8ef6a5b07d Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 20:20:18 +0000 Subject: [PATCH 08/21] tidy --- .github/workflows/build_all_images.yml | 1 + src/base/.devcontainer/scripts/root_install.sh | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index fb7fa3b4..a56ce74c 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -79,6 +79,7 @@ jobs: syft_image.tar grant_image.tar tflint_image.tar + zizmor_image.tar package_base_docker_image: uses: ./.github/workflows/build_multi_arch_image.yml permissions: diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index 11da747e..43eeddd0 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -35,10 +35,8 @@ apt-get -y install --no-install-recommends htop vim curl git build-essential \ # install AWS SAM CLI VERSION="${SAM_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_aws_sam_cli.sh" # Install ASDF -echo "Installing asdf" VERSION="${ASDF_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_asdf.sh" # install gitleaks -echo "Installing gitleaks" VERSION="${GITLEAKS_VERSION}" "${SCRIPTS_DIR}/${CONTAINER_NAME}/install_gitleaks.sh" # install gitsecrets @@ -53,10 +51,13 @@ chmod 755 /usr/share/secrets-scanner curl -L https://raw.githubusercontent.com/NHSDigital/software-engineering-quality-framework/main/tools/nhsd-git-secrets/nhsd-rules-deny.txt -o /usr/share/secrets-scanner/nhsd-rules-deny.txt # get cfn-guard ruleset -wget -O /tmp/ruleset.zip https://github.com/aws-cloudformation/aws-guard-rules-registry/releases/download/1.0.2/ruleset-build-v1.0.2.zip >/dev/null 2>&1 +tmp_dir="$(mktemp -d)" +trap 'rm -rf "${tmp_dir}"' EXIT +download_file="${tmp_dir}/ruleset.zip" +curl -fsSL "https://github.com/aws-cloudformation/aws-guard-rules-registry/releases/download/1.0.2/ruleset-build-v1.0.2.zip" -o "${download_file}" + mkdir -p "${SCRIPTS_DIR}/cfnguard_rulesets" -unzip /tmp/ruleset.zip -d "${SCRIPTS_DIR}/cfnguard_rulesets" >/dev/null 2>&1 -rm /tmp/ruleset.zip +unzip "${download_file}" -d "${SCRIPTS_DIR}/cfnguard_rulesets" # clean up apt-get clean From e985d4de44e20b5a9a6da076db1b125cb2d623ae Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 20:22:49 +0000 Subject: [PATCH 09/21] fix --- Makefile | 2 +- src/base/.devcontainer/Dockerfile.zizmor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 10dd0cb1..f46a6199 100644 --- a/Makefile +++ b/Makefile @@ -109,7 +109,7 @@ build-zizmor: build-tools: build-syft build-grype build-grant build-tflint build-zizmor -build-image: build-syft build-grype build-grant build-tflint guard-CONTAINER_NAME guard-BASE_VERSION_TAG guard-BASE_FOLDER guard-IMAGE_TAG +build-image: build-tools guard-CONTAINER_NAME guard-BASE_VERSION_TAG guard-BASE_FOLDER guard-IMAGE_TAG workspace_folder="$${CONTAINER_NAME}"; \ case "$${CONTAINER_NAME}" in \ eps_*) workspace_folder="$$(printf '%s' "$${CONTAINER_NAME}" | tr '_' '-')" ;; \ diff --git a/src/base/.devcontainer/Dockerfile.zizmor b/src/base/.devcontainer/Dockerfile.zizmor index bc504b3f..de563c90 100644 --- a/src/base/.devcontainer/Dockerfile.zizmor +++ b/src/base/.devcontainer/Dockerfile.zizmor @@ -12,7 +12,7 @@ RUN --mount=type=secret,id=GH_TOKEN,env=GH_TOKEN \ ARCH="${TARGETARCH}" \ VERSION="${ZIZMOR_VERSION}" \ GITHUB_REPO="zizmorcore/zizmor" \ - TOOL="zizmor" \ + TOOL="zizmor" \ DOWNLOAD_BINARY="${DOWNLOAD_BINARY}" \ VERIFY_BINARY_ATTESTATION="true" \ VERIFY_CHECKSUM="false" \ From d80dcb3445e1d54f2688e33229902d4c8aa8aeec Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 20:23:16 +0000 Subject: [PATCH 10/21] fix --- src/base/.devcontainer/Dockerfile.tflint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/.devcontainer/Dockerfile.tflint b/src/base/.devcontainer/Dockerfile.tflint index 2273aa33..4e61f773 100644 --- a/src/base/.devcontainer/Dockerfile.tflint +++ b/src/base/.devcontainer/Dockerfile.tflint @@ -12,7 +12,7 @@ RUN --mount=type=secret,id=GH_TOKEN,env=GH_TOKEN \ ARCH="${TARGETARCH}" \ VERSION="${TFLINT_VERSION}" \ GITHUB_REPO="terraform-linters/tflint" \ - TOOL="tflint" \ + TOOL="tflint" \ DOWNLOAD_BINARY="${DOWNLOAD_BINARY}" \ VERIFY_BINARY_ATTESTATION="false" \ VERIFY_CHECKSUM="true" \ From c4dc1ab300cd408bae1972f4ca2164232a10b8bb Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 15 Apr 2026 20:24:24 +0000 Subject: [PATCH 11/21] fix --- src/base/.devcontainer/scripts/install_aws_sam_cli.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh index 00741b70..9c5f7e64 100755 --- a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh +++ b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh @@ -129,9 +129,8 @@ install() { curl -fsSL "${scriptUrl}" -o "${scriptZipFile}" curl -fsSL "${scriptUrl}.sig" -o "${scriptSigFile}" - verify_aws_sam_cli_gpg_signature "$scriptZipFile" "$scriptSigFile" - if (( $? > 0 )); then - echo "Could not verify GPG signature of AWS CLI install script. Make sure you provided a valid version." + if ! verify_aws_sam_cli_gpg_signature "$scriptZipFile" "$scriptSigFile"; then + echo "Could not verify GPG signature of AWS SAM CLI install script. Make sure you provided a valid version." exit 1 fi echo "GPG signature of AWS SAM CLI install script verified successfully. Installing..." From d92d2158c1f4800c2188a99fedfe4b2dd9b09822 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 06:39:17 +0000 Subject: [PATCH 12/21] fix --- .grype.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.grype.yaml b/.grype.yaml index 8a3d028f..ddee89b8 100644 --- a/.grype.yaml +++ b/.grype.yaml @@ -35,6 +35,9 @@ ignore: - vulnerability: CVE-2026-32283 - vulnerability: CVE-2026-32281 - vulnerability: CVE-2026-33810 + - vulnerability: CVE-2026-6100 + - vulnerability: CVE-2026-4786 + - vulnerability: CVE-2026-4786 # node_24 vulnerabilities - vulnerability: GHSA-c2c7-rcm5-vvqj - vulnerability: GHSA-7r86-cg39-jmmj From 40211f090d5b3d5ada15c10ce3f15ef059c83049 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 06:41:25 +0000 Subject: [PATCH 13/21] fix --- src/base/.devcontainer/scripts/install_cfn_guard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/.devcontainer/scripts/install_cfn_guard.sh b/src/base/.devcontainer/scripts/install_cfn_guard.sh index 82510e77..eab7cce9 100755 --- a/src/base/.devcontainer/scripts/install_cfn_guard.sh +++ b/src/base/.devcontainer/scripts/install_cfn_guard.sh @@ -3,7 +3,7 @@ set -euo pipefail VERSION=${VERSION:-"3.2.0"} # Expected SHA256 checksums taken from https://github.com/aws-cloudformation/cloudformation-guard/releases/tag/3.2.0 -# When we change gitleaks versions, these must be changed +# When we change cfn-guard versions, these must be changed sha256sum_expected_arm="sha256:d562e14831794a4859782f5609186970373e8e0a049fbded2c01612d2dcdb087" sha256sum_expected_amd64="sha256:9f8c4d9f15f7dd54a37ea70a5237ba00aba682fb1e6521a744d12259961dfc13" From bb77bf160fabe29243aec66c42a979c01b62dd65 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 06:41:53 +0000 Subject: [PATCH 14/21] fix --- src/base/.devcontainer/scripts/install_cfn_guard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/.devcontainer/scripts/install_cfn_guard.sh b/src/base/.devcontainer/scripts/install_cfn_guard.sh index eab7cce9..221f85f1 100755 --- a/src/base/.devcontainer/scripts/install_cfn_guard.sh +++ b/src/base/.devcontainer/scripts/install_cfn_guard.sh @@ -21,7 +21,7 @@ install() { tmp_dir="$(mktemp -d)" trap 'rm -rf "${tmp_dir}"' EXIT - download_file="${tmp_dir}/gitleaks.tar.gz" + download_file="${tmp_dir}/cfn-guard.tar.gz" if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then download_url="https://github.com/aws-cloudformation/cloudformation-guard/releases/download/${VERSION}/cfn-guard-v3-aarch64-ubuntu-latest.tar.gz" From 1c65c833eb108c396eeebcc3f7cd0335e8afa8f2 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:06:31 +0000 Subject: [PATCH 15/21] fix --- src/base/.devcontainer/scripts/install_aws_sam_cli.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh index 9c5f7e64..f81a85e2 100755 --- a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh +++ b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh @@ -96,8 +96,7 @@ check_packages curl ca-certificates gpg dirmngr unzip bash-completion less verify_aws_sam_cli_gpg_signature() { local filePath=$1 local sigFilePath=$2 - tmp_dir="$(mktemp -d)" - trap 'rm -rf "${tmp_dir}"' EXIT + local tmp_dir=$3 local awsGpgKeyring="${tmp_dir}/aws-sam-cli-public-key.gpg" echo "${PRIMARY_PUBLIC_KEY}" | gpg --dearmor > "${awsGpgKeyring}" @@ -129,7 +128,7 @@ install() { curl -fsSL "${scriptUrl}" -o "${scriptZipFile}" curl -fsSL "${scriptUrl}.sig" -o "${scriptSigFile}" - if ! verify_aws_sam_cli_gpg_signature "$scriptZipFile" "$scriptSigFile"; then + if ! verify_aws_sam_cli_gpg_signature "$scriptZipFile" "$scriptSigFile" "$tmp_dir"; then echo "Could not verify GPG signature of AWS SAM CLI install script. Make sure you provided a valid version." exit 1 fi From 108804c510cbb3b79de16b896e0504b17eecd53d Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:08:40 +0000 Subject: [PATCH 16/21] more fix --- .../scripts/install_github_release.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/base/.devcontainer/scripts/install_github_release.sh b/src/base/.devcontainer/scripts/install_github_release.sh index daa51034..fd8d9a94 100755 --- a/src/base/.devcontainer/scripts/install_github_release.sh +++ b/src/base/.devcontainer/scripts/install_github_release.sh @@ -16,6 +16,23 @@ if ! command -v gh >/dev/null 2>&1; then exit 1 fi +required_vars=( + "GITHUB_REPO" + "VERSION" + "DOWNLOAD_BINARY" + "TOOL" + "COMPRESSION" + "VERIFY_BINARY_ATTESTATION" + "VERIFY_CHECKSUM" +) + +for var_name in "${required_vars[@]}"; do + if [ -z "${!var_name:-}" ]; then + echo "${var_name} must be defined" + exit 1 + fi +done + if [ "${VERIFY_BINARY_ATTESTATION}" != "true" ] && [ "${VERIFY_CHECKSUM}" != "true" ]; then echo "VERIFY_BINARY_ATTESTATION or VERIFY_CHECKSUM must be set to true" exit 1 From 4e2b61cb434f3d567e6cf2e9c87e54e1717608c9 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:10:51 +0000 Subject: [PATCH 17/21] fix --- src/base/.devcontainer/scripts/install_aws_sam_cli.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh index f81a85e2..47b3a053 100755 --- a/src/base/.devcontainer/scripts/install_aws_sam_cli.sh +++ b/src/base/.devcontainer/scripts/install_aws_sam_cli.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -VERSION=${VERSION:-"latest"} -VERBOSE=${VERBOSE:-"true"} +if [ "${VERSION}" = "latest" ]; then + VERSION="$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/aws/aws-sam-cli/releases/latest | awk -F/ '{print $NF}')" +fi PRIMARY_PUBLIC_KEY="-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2.0.22 (GNU/Linux) From b6914cf3b0bb105603134389371c2c63b958d96b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:28:10 +0000 Subject: [PATCH 18/21] fix checksum --- src/base/.devcontainer/scripts/install_cfn_guard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/.devcontainer/scripts/install_cfn_guard.sh b/src/base/.devcontainer/scripts/install_cfn_guard.sh index 221f85f1..15288543 100755 --- a/src/base/.devcontainer/scripts/install_cfn_guard.sh +++ b/src/base/.devcontainer/scripts/install_cfn_guard.sh @@ -4,7 +4,7 @@ set -euo pipefail VERSION=${VERSION:-"3.2.0"} # Expected SHA256 checksums taken from https://github.com/aws-cloudformation/cloudformation-guard/releases/tag/3.2.0 # When we change cfn-guard versions, these must be changed -sha256sum_expected_arm="sha256:d562e14831794a4859782f5609186970373e8e0a049fbded2c01612d2dcdb087" +sha256sum_expected_arm="sha256:aa757b599e59425fe3322dc65cfc93d2931c7f818aa1626996f8ad4852eae5ca" sha256sum_expected_amd64="sha256:9f8c4d9f15f7dd54a37ea70a5237ba00aba682fb1e6521a744d12259961dfc13" From 350e1ff3814d2a2fcaf7d3a1f97a43e0531da6ca Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:48:57 +0000 Subject: [PATCH 19/21] fix --- .grype.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.grype.yaml b/.grype.yaml index ddee89b8..df239c56 100644 --- a/.grype.yaml +++ b/.grype.yaml @@ -37,7 +37,6 @@ ignore: - vulnerability: CVE-2026-33810 - vulnerability: CVE-2026-6100 - vulnerability: CVE-2026-4786 - - vulnerability: CVE-2026-4786 # node_24 vulnerabilities - vulnerability: GHSA-c2c7-rcm5-vvqj - vulnerability: GHSA-7r86-cg39-jmmj From 12788432cf853db2418d2b24cae3d298af324d43 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:51:41 +0000 Subject: [PATCH 20/21] fix --- src/base/.devcontainer/scripts/install_github_release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/.devcontainer/scripts/install_github_release.sh b/src/base/.devcontainer/scripts/install_github_release.sh index fd8d9a94..673f36d2 100755 --- a/src/base/.devcontainer/scripts/install_github_release.sh +++ b/src/base/.devcontainer/scripts/install_github_release.sh @@ -6,9 +6,9 @@ export DEBIAN_FRONTEND=noninteractive DEFAULT_INSTALL_DIR="/usr/local/bin" INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" -if ! command -v curl >/dev/null 2>&1 || ! command -v unzip >/dev/null 2>&1; then +if ! command -v curl >/dev/null 2>&1 || ! command -v unzip >/dev/null 2>&1 || ! command -v tar >/dev/null 2>&1; then apt-get update - apt-get install -y --no-install-recommends curl unzip ca-certificates + apt-get install -y --no-install-recommends curl unzip tar ca-certificates fi if ! command -v gh >/dev/null 2>&1; then From 508d94f27296cf0bd42d5142004ee9f07d96b18f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 16 Apr 2026 07:56:51 +0000 Subject: [PATCH 21/21] add back in cfn-lint --- .../.devcontainer/scripts/requirements-user.txt | 1 + .../node_24_python_3_12/.devcontainer/scripts/vscode_install.sh | 2 ++ .../.devcontainer/scripts/requirements-user.txt | 1 + .../node_24_python_3_13/.devcontainer/scripts/vscode_install.sh | 2 ++ .../.devcontainer/scripts/requirements-user.txt | 1 + .../node_24_python_3_14/.devcontainer/scripts/vscode_install.sh | 2 ++ 6 files changed, 9 insertions(+) create mode 100644 src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt create mode 100644 src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt create mode 100644 src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt diff --git a/src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt new file mode 100644 index 00000000..58587fdf --- /dev/null +++ b/src/languages/node_24_python_3_12/.devcontainer/scripts/requirements-user.txt @@ -0,0 +1 @@ +cfn-lint==1.47.1 diff --git a/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh index f13cedf2..14bd8c1d 100755 --- a/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_12/.devcontainer/scripts/vscode_install.sh @@ -6,3 +6,5 @@ asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install + +pip install --user -r "${SCRIPT_DIR}/requirements-user.txt" diff --git a/src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt new file mode 100644 index 00000000..58587fdf --- /dev/null +++ b/src/languages/node_24_python_3_13/.devcontainer/scripts/requirements-user.txt @@ -0,0 +1 @@ +cfn-lint==1.47.1 diff --git a/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh index f13cedf2..14bd8c1d 100755 --- a/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_13/.devcontainer/scripts/vscode_install.sh @@ -6,3 +6,5 @@ asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install + +pip install --user -r "${SCRIPT_DIR}/requirements-user.txt" diff --git a/src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt b/src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt new file mode 100644 index 00000000..58587fdf --- /dev/null +++ b/src/languages/node_24_python_3_14/.devcontainer/scripts/requirements-user.txt @@ -0,0 +1 @@ +cfn-lint==1.47.1 diff --git a/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh index f13cedf2..14bd8c1d 100755 --- a/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh +++ b/src/languages/node_24_python_3_14/.devcontainer/scripts/vscode_install.sh @@ -6,3 +6,5 @@ asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git asdf install python asdf install + +pip install --user -r "${SCRIPT_DIR}/requirements-user.txt"