From 76cfd2ae66392a4c41badf1e38624244f6faf6a2 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 12:59:48 +0000 Subject: [PATCH 01/19] build common node --- .github/workflows/build_all_images.yml | 26 +- .github/workflows/build_multi_arch_image.yml | 55 +--- Makefile | 9 +- README.md | 22 +- .../node_24/.devcontainer/.tool-versions | 1 + .../node_24/.devcontainer/devcontainer.json | 18 + .../.devcontainer/scripts/root_install.sh | 7 + .../.devcontainer/scripts/vscode_install.sh | 5 + src/base_node/node_24/.trivyignore.yaml | 27 ++ src/base_node/node_24/trivy.yaml | 1 + src/common_node_24/.trivyignore.yaml | 309 ++++++++++++++++++ src/common_node_24/Dockerfile | 44 +++ .../.devcontainer/.tool-versions | 1 - .../.devcontainer/devcontainer.json | 2 +- .../.devcontainer/scripts/vscode_install.sh | 1 - .../.devcontainer/.tool-versions | 1 - .../.devcontainer/devcontainer.json | 2 +- .../.devcontainer/scripts/vscode_install.sh | 1 - .../.devcontainer/.tool-versions | 1 - .../.devcontainer/devcontainer.json | 2 +- .../.devcontainer/scripts/vscode_install.sh | 1 - 21 files changed, 481 insertions(+), 55 deletions(-) create mode 100644 src/base_node/node_24/.devcontainer/.tool-versions create mode 100644 src/base_node/node_24/.devcontainer/devcontainer.json create mode 100755 src/base_node/node_24/.devcontainer/scripts/root_install.sh create mode 100755 src/base_node/node_24/.devcontainer/scripts/vscode_install.sh create mode 100644 src/base_node/node_24/.trivyignore.yaml create mode 100644 src/base_node/node_24/trivy.yaml create mode 100644 src/common_node_24/.trivyignore.yaml create mode 100644 src/common_node_24/Dockerfile diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index 8075f67..38c39ce 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -17,6 +17,7 @@ jobs: discover_folders: runs-on: ubuntu-latest outputs: + base_node_folders: ${{ steps.find-folders.outputs.base_node }} language_folders: ${{ steps.find-folders.outputs.languages }} project_folders: ${{ steps.find-folders.outputs.projects }} steps: @@ -24,10 +25,14 @@ jobs: - id: find-folders run: | + base_node_folders=$(find src/base_node -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') language_folders=$(find src/languages -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') project_folders=$(find src/projects -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') - echo "languages=$language_folders" >> "$GITHUB_OUTPUT" - echo "projects=$project_folders" >> "$GITHUB_OUTPUT" + { + echo "base_node=$base_node_folders" + echo "languages=$language_folders" + echo "projects=$project_folders" + } >> "$GITHUB_OUTPUT" package_base_docker_image: uses: ./.github/workflows/build_multi_arch_image.yml with: @@ -36,9 +41,25 @@ jobs: container_name: base base_folder: "." NO_CACHE: ${{ inputs.NO_CACHE }} + package_base_node_images: + needs: + - package_base_docker_image + - discover_folders + strategy: + fail-fast: false + matrix: + container_name: ${{ fromJson(needs.discover_folders.outputs.base_node_folders) }} + uses: ./.github/workflows/build_multi_arch_image.yml + with: + tag_latest: ${{ inputs.tag_latest }} + docker_tag: ${{ inputs.docker_tag }} + container_name: ${{ matrix.container_name }} + base_folder: "base_node" + NO_CACHE: ${{ inputs.NO_CACHE }} package_language_docker_images: needs: - package_base_docker_image + - package_base_node_images - discover_folders strategy: fail-fast: false @@ -54,7 +75,6 @@ jobs: package_project_docker_images: needs: - package_language_docker_images - - discover_folders strategy: fail-fast: false diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index effc2b7..266b768 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -72,17 +72,6 @@ jobs: run: | echo "Building image..." make build-image - - echo "Creating combined trivy ignore file" - # create combined trivy ignore file for use in trivy scan, combining common and specific ignore files if they exist - combined="src/${BASE_FOLDER}/${CONTAINER_NAME}/.trivyignore_combined.yaml" - common="src/common/.trivyignore.yaml" - specific="src/${BASE_FOLDER}/${CONTAINER_NAME}/.trivyignore.yaml" - echo "vulnerabilities:" > "$combined" - if [ -f "$common" ]; then sed -n '2,$p' "$common" >> "$combined"; fi - if [ -f "$specific" ]; then sed -n '2,$p' "$specific" >> "$combined"; fi - echo "Combined trivy ignore file created at $combined" - env: ARCHITECTURE: '${{ matrix.arch }}' CONTAINER_NAME: '${{ inputs.container_name }}' @@ -92,41 +81,33 @@ jobs: BASE_FOLDER: "${{ inputs.base_folder }}" NO_CACHE: '${{ inputs.NO_CACHE }}' - name: Check docker vulnerabilities - json output - uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 - with: - scan-type: "image" - image-ref: "ghcr.io/nhsdigital/eps-devcontainers/${{ inputs.container_name }}:${{ inputs.docker_tag }}-${{ matrix.arch }}" - severity: "CRITICAL,HIGH" - scanners: "vuln" - vuln-type: "os,library" - format: "json" - output: "scan_results_docker.json" - exit-code: "0" - trivy-config: src/${{ inputs.base_folder }}/${{ inputs.container_name }}/trivy.yaml + run: | + make scan-image-json + env: + CONTAINER_NAME: '${{ inputs.container_name }}' + BASE_FOLDER: "${{ inputs.base_folder }}" + IMAGE_TAG: "${{ inputs.docker_tag }}-${{ matrix.arch }}" + EXIT_CODE: 0 - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f name: Upload scan results with: name: "scan_results_docker_${{ inputs.container_name }}_${{ matrix.arch }}.json" - path: scan_results_docker.json - - name: Check docker vulnerabilities - table output - uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 - with: - scan-type: "image" - image-ref: "ghcr.io/nhsdigital/eps-devcontainers/${{ inputs.container_name }}:${{ inputs.docker_tag }}-${{ matrix.arch }}" - severity: "CRITICAL,HIGH" - scanners: "vuln" - vuln-type: "os,library" - format: "table" - output: "scan_results_docker.txt" - exit-code: "1" - trivy-config: src/${{ inputs.base_folder }}/${{ inputs.container_name }}/trivy.yaml + path: .out/scan_results_docker.json + - name: Check docker vulnerabilities - json output + run: | + make scan-image-json + env: + CONTAINER_NAME: '${{ inputs.container_name }}' + BASE_FOLDER: "${{ inputs.base_folder }}" + IMAGE_TAG: "${{ inputs.docker_tag }}-${{ matrix.arch }}" + EXIT_CODE: "1" - name: Show docker vulnerability output if: always() run: | echo "Scan output for ghcr.io/nhsdigital/eps-devcontainers/base:${DOCKER_TAG}-${ARCHITECTURE}" - if [ -f scan_results_docker.txt ]; then - cat scan_results_docker.txt + if [ -f .out/scan_results_docker.txt ]; then + cat .out/scan_results_docker.txt fi env: ARCHITECTURE: '${{ matrix.arch }}' diff --git a/Makefile b/Makefile index 0920c27..999f69c 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ scan-image: guard-CONTAINER_NAME guard-BASE_FOLDER @combined="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore_combined.yaml"; \ common="src/common/.trivyignore.yaml"; \ specific="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore.yaml"; \ + exit_code="$${EXIT_CODE:-1}"; \ echo "vulnerabilities:" > "$$combined"; \ if [ -f "$$common" ]; then sed -n '2,$$p' "$$common" >> "$$combined"; fi; \ if [ -f "$$specific" ]; then sed -n '2,$$p' "$$specific" >> "$$combined"; fi @@ -51,13 +52,15 @@ scan-image: guard-CONTAINER_NAME guard-BASE_FOLDER --severity HIGH,CRITICAL \ --config src/${BASE_FOLDER}/${CONTAINER_NAME}/trivy.yaml \ --scanners vuln \ - --exit-code 1 \ - --format table "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}" + --exit-code "$$exit_code" \ + --format table \ + --output .out/scan_results_docker.txt "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}" scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER guard-IMAGE_TAG @combined="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore_combined.yaml"; \ common="src/common/.trivyignore.yaml"; \ specific="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore.yaml"; \ + exit_code="$${EXIT_CODE:-1}"; \ echo "vulnerabilities:" > "$$combined"; \ if [ -f "$$common" ]; then sed -n '2,$$p' "$$common" >> "$$combined"; fi; \ if [ -f "$$specific" ]; then sed -n '2,$$p' "$$specific" >> "$$combined"; fi @@ -66,7 +69,7 @@ scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER guard-IMAGE_TAG --severity HIGH,CRITICAL \ --config src/${BASE_FOLDER}/${CONTAINER_NAME}/trivy.yaml \ --scanners vuln \ - --exit-code 1 \ + --exit-code "$$exit_code" \ --format json \ --output .out/scan_results_docker.json "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}" diff --git a/README.md b/README.md index 7fa7a29..e7983f1 100644 --- a/README.md +++ b/README.md @@ -132,16 +132,17 @@ It is important that - the first step copies .tool-versions from /home/vscode to $HOME/.tool-versions # Project structure -We have 4 types of dev container. These are defined under src +We have 5 types of dev container. These are defined under src `base` - this is the base image that all others are based on. -`languages` - this installs specific versions of node and python. +`base_node` - images that install node - most language projects rely on one of these +`languages` - this installs specific versions of python - normally based off a node image `projects` - this is used for projects where more customization is needed than just a base language image. `githubactions` - this just takes an existing image and remaps vscode user to be 1001 so it can be used by github actions. Each image to be built contains a .devcontainer folder that defines how the devcontainer should be built. At a minimum, this should contain a devcontainer.json file. See https://containers.dev/implementors/json_reference/ for options for this -Images under languages should point to a dockerfile under src/common that is based off the base image. This also runs `.devcontainer/scripts/root_install.sh` and `.devcontainer/scripts/vscode_install.sh` as vscode user as part of the build. These files should be in the language specific folder. +Images under languages should point to a dockerfile under src/common or src/common_node_24 that is based off the base or node image. This also runs `.devcontainer/scripts/root_install.sh` and `.devcontainer/scripts/vscode_install.sh` as vscode user as part of the build. These files should be in the language specific folder. We use trivy to scan for vulnerabilities in the built docker images. Known vulnerabilities in the base image are in `src/common/.trivyignore.yaml`. Vulnerabilities in specific images are in `.trivyignore.yaml` file in each images folder. These are combined before running a scan to exclude all known vulnerabilities @@ -180,6 +181,14 @@ CONTAINER_NAME=base \ IMAGE_TAG=local-build \ make build-image ``` +Base node 24 image +``` +CONTAINER_NAME=node_24 \ + BASE_VERSION_TAG=local-build \ + BASE_FOLDER=base_node \ + IMAGE_TAG=local-build \ + make build-image +``` Language images ``` CONTAINER_NAME=node_24_python_3_14 \ @@ -212,6 +221,13 @@ CONTAINER_NAME=base \ IMAGE_TAG=local-build \ make scan-image ``` +Base node 24 image +``` +CONTAINER_NAME=node_24 \ + BASE_FOLDER=languages \ + IMAGE_TAG=local-build \ + make scan-image +``` Language images ``` CONTAINER_NAME=node_24_python_3_12 \ diff --git a/src/base_node/node_24/.devcontainer/.tool-versions b/src/base_node/node_24/.devcontainer/.tool-versions new file mode 100644 index 0000000..1b05724 --- /dev/null +++ b/src/base_node/node_24/.devcontainer/.tool-versions @@ -0,0 +1 @@ +nodejs 24.13.0 diff --git a/src/base_node/node_24/.devcontainer/devcontainer.json b/src/base_node/node_24/.devcontainer/devcontainer.json new file mode 100644 index 0000000..90d861a --- /dev/null +++ b/src/base_node/node_24/.devcontainer/devcontainer.json @@ -0,0 +1,18 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "EPS Devcontainer node_24", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "build": { + "dockerfile": "../../../common/Dockerfile", + "args": { + "CONTAINER_NAME": "eps_devcontainer_${localEnv:CONTAINER_NAME}", + "MULTI_ARCH_TAG": "${localEnv:MULTI_ARCH_TAG}", + "BASE_VERSION_TAG": "${localEnv:BASE_VERSION_TAG}", + "IMAGE_TAG": "${localEnv:IMAGE_TAG}" + }, + "context": "." + }, + "features": {} + } + diff --git a/src/base_node/node_24/.devcontainer/scripts/root_install.sh b/src/base_node/node_24/.devcontainer/scripts/root_install.sh new file mode 100755 index 0000000..52fa2b1 --- /dev/null +++ b/src/base_node/node_24/.devcontainer/scripts/root_install.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -e +export DEBIAN_FRONTEND=noninteractive + +# clean up +apt-get clean +rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/src/base_node/node_24/.devcontainer/scripts/vscode_install.sh b/src/base_node/node_24/.devcontainer/scripts/vscode_install.sh new file mode 100755 index 0000000..ea370f1 --- /dev/null +++ b/src/base_node/node_24/.devcontainer/scripts/vscode_install.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e + +asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git +asdf install diff --git a/src/base_node/node_24/.trivyignore.yaml b/src/base_node/node_24/.trivyignore.yaml new file mode 100644 index 0000000..a8010cf --- /dev/null +++ b/src/base_node/node_24/.trivyignore.yaml @@ -0,0 +1,27 @@ +vulnerabilities: + - id: CVE-2026-25547 + statement: "brace-expansion: brace-expansion: Denial of Service via unbounded brace range expansion" + purls: + - "pkg:npm/%40isaacs/brace-expansion@5.0.0" + expired_at: 2026-08-12 + - id: CVE-2025-64756 + statement: "glob: glob: Command Injection Vulnerability via Malicious Filenames" + purls: + - "pkg:npm/glob@10.4.5" + - "pkg:npm/glob@11.0.3" + expired_at: 2026-08-12 + - id: CVE-2026-23745 + statement: "node-tar: tar: node-tar: Arbitrary file overwrite and symlink poisoning via unsanitized linkpaths in archives" + purls: + - "pkg:npm/tar@7.5.1" + expired_at: 2026-08-12 + - id: CVE-2026-23950 + statement: "node-tar: tar: node-tar: Arbitrary file overwrite via Unicode path collision race condition" + purls: + - "pkg:npm/tar@7.5.1" + expired_at: 2026-08-12 + - id: CVE-2026-24842 + statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" + purls: + - "pkg:npm/tar@7.5.1" + expired_at: 2026-08-12 diff --git a/src/base_node/node_24/trivy.yaml b/src/base_node/node_24/trivy.yaml new file mode 100644 index 0000000..48cfe23 --- /dev/null +++ b/src/base_node/node_24/trivy.yaml @@ -0,0 +1 @@ +ignorefile: "src/languages/node_24_python_3_12/.trivyignore_combined.yaml" diff --git a/src/common_node_24/.trivyignore.yaml b/src/common_node_24/.trivyignore.yaml new file mode 100644 index 0000000..bd4d87e --- /dev/null +++ b/src/common_node_24/.trivyignore.yaml @@ -0,0 +1,309 @@ +vulnerabilities: + - id: CVE-2024-35870 + statement: "kernel: smb: client: fix UAF in smb2_reconnect_server()" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2024-53179 + statement: "kernel: smb: client: fix use-after-free of signing key" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-37849 + statement: "kernel: KVM: arm64: Tear down vGIC on failed vCPU creation" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-37899 + statement: "kernel: ksmbd: fix use-after-free in session logoff" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-38118 + statement: "kernel: Linux kernel: Bluetooth MGMT use-after-free vulnerability allows privilege escalation" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2026-26007 + statement: "cryptography: cryptography Subgroup Attack Due to Missing Subgroup Validation for SECT Curves" + purls: + - "pkg:pypi/cryptography@46.0.3" + expired_at: 2026-08-12 + - id: CVE-2024-49761 + statement: "rexml: REXML ReDoS vulnerability" + purls: + - "pkg:gem/rexml@3.2.6" + expired_at: 2026-08-12 + - id: CVE-2025-68121 + statement: "During session resumption in crypto/tls, if the underlying Config has ..." + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + - "pkg:golang/stdlib@v1.24.9" + - "pkg:golang/stdlib@v1.25.5" + expired_at: 2026-08-12 + - id: CVE-2025-61726 + statement: "golang: net/url: Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + - "pkg:golang/stdlib@v1.24.9" + - "pkg:golang/stdlib@v1.25.5" + expired_at: 2026-08-12 + - id: CVE-2025-61728 + statement: "golang: archive/zip: Excessive CPU consumption when building archive index in archive/zip" + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + - "pkg:golang/stdlib@v1.24.9" + - "pkg:golang/stdlib@v1.25.5" + expired_at: 2026-08-12 + - id: CVE-2025-61730 + statement: "During the TLS 1.3 handshake if multiple messages are sent in records ..." + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + - "pkg:golang/stdlib@v1.24.9" + - "pkg:golang/stdlib@v1.25.5" + expired_at: 2026-08-12 + - id: CVE-2025-47907 + statement: "database/sql: Postgres Scan Race Condition" + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-08-12 + - id: CVE-2025-58183 + statement: "golang: archive/tar: Unbounded allocation when parsing GNU sparse map" + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-08-12 + - id: CVE-2025-61729 + statement: "crypto/x509: golang: Denial of Service due to excessive resource consumption via crafted certificate" + purls: + - "pkg:golang/stdlib@v1.16.15" + - "pkg:golang/stdlib@v1.23.4" + - "pkg:golang/stdlib@v1.24.4" + - "pkg:golang/stdlib@v1.24.9" + expired_at: 2026-08-12 + - id: CVE-2023-24538 + statement: "golang: html/template: backticks not treated as string delimiters" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-24540 + statement: "golang: html/template: improper handling of JavaScript whitespace" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2024-24790 + statement: "golang: net/netip: Unexpected behavior from Is methods for IPv4-mapped IPv6 addresses" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-24675 + statement: "golang: encoding/pem: fix stack overflow in Decode" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-27664 + statement: "golang: net/http: handle server errors after sending GOAWAY" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-28131 + statement: "golang: encoding/xml: stack exhaustion in Decoder.Skip" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-28327 + statement: "golang: crypto/elliptic: panic caused by oversized scalar" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-2879 + statement: "golang: archive/tar: github.com/vbatts/tar-split: unbounded memory consumption when reading headers" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-2880 + statement: "golang: net/http/httputil: ReverseProxy should not forward unparseable query parameters" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-29804 + statement: "ELSA-2022-17957: ol8addon security update (IMPORTANT)" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30580 + statement: "golang: os/exec: Code injection in Cmd.Start" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30630 + statement: "golang: io/fs: stack exhaustion in Glob" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30631 + statement: "golang: compress/gzip: stack exhaustion in Reader.Read" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30632 + statement: "golang: path/filepath: stack exhaustion in Glob" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30633 + statement: "golang: encoding/xml: stack exhaustion in Unmarshal" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30634 + statement: "ELSA-2022-17957: ol8addon security update (IMPORTANT)" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-30635 + statement: "golang: encoding/gob: stack exhaustion in Decoder.Decode" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-32189 + statement: "golang: math/big: decoding big.Float and big.Rat types can panic if the encoded message is too short, potentially allowing a denial of service" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41715 + statement: "golang: regexp/syntax: limit memory used by parsing regexps" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41716 + statement: "Due to unsanitized NUL values, attackers may be able to maliciously se ..." + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41720 + statement: "golang: os, net/http: avoid escapes from os.DirFS and http.Dir on Windows" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41722 + statement: "golang: path/filepath: path-filepath filepath.Clean path traversal" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41723 + statement: "golang.org/x/net/http2: avoid quadratic complexity in HPACK decoding" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41724 + statement: "golang: crypto/tls: large handshake records may cause panics" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2022-41725 + statement: "golang: net/http, mime/multipart: denial of service from excessive resource consumption" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-24534 + statement: "golang: net/http, net/textproto: denial of service from excessive memory allocation" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-24536 + statement: "golang: net/http, net/textproto, mime/multipart: denial of service from excessive resource consumption" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-24537 + statement: "golang: go/parser: Infinite loop in parsing" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-24539 + statement: "golang: html/template: improper sanitization of CSS values" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-29400 + statement: "golang: html/template: improper handling of empty HTML attributes" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-29403 + statement: "golang: runtime: unexpected behavior of setuid/setgid binaries" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-39325 + statement: "golang: net/http, x/net/http2: rapid stream resets can cause excessive work (CVE-2023-44487)" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-45283 + statement: "The filepath package does not recognize paths with a \\??\\ prefix as sp ..." + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-45287 + statement: "golang: crypto/tls: Timing Side Channel attack in RSA based TLS key exchanges." + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2023-45288 + statement: "golang: net/http, x/net/http2: unlimited number of CONTINUATION frames causes DoS" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2024-34156 + statement: "encoding/gob: golang: Calling Decoder.Decode on a message which contains deeply nested structures can cause a panic due to stack exhaustion" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-08-12 + - id: CVE-2024-25621 + statement: "github.com/containerd/containerd: containerd local privilege escalation" + purls: + - "pkg:golang/github.com/containerd/containerd/v2@v2.1.4" + expired_at: 2026-08-12 + - id: CVE-2024-35870 + statement: "kernel: smb: client: fix UAF in smb2_reconnect_server()" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2024-53179 + statement: "kernel: smb: client: fix use-after-free of signing key" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-37849 + statement: "kernel: KVM: arm64: Tear down vGIC on failed vCPU creation" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-37899 + statement: "kernel: ksmbd: fix use-after-free in session logoff" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-38118 + statement: "kernel: Linux kernel: Bluetooth MGMT use-after-free vulnerability allows privilege escalation" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" + expired_at: 2026-08-12 + - id: CVE-2025-68121 + statement: "crypto/tls: Unexpected session resumption in crypto/tls" + purls: + - "pkg:golang/stdlib@v1.25.6" + expired_at: 2026-08-13 diff --git a/src/common_node_24/Dockerfile b/src/common_node_24/Dockerfile new file mode 100644 index 0000000..9227065 --- /dev/null +++ b/src/common_node_24/Dockerfile @@ -0,0 +1,44 @@ +ARG BASE_VERSION_TAG=latest +ARG BASE_IMAGE=ghcr.io/nhsdigital/eps-devcontainers/node_24:${BASE_VERSION_TAG} + +FROM ${BASE_IMAGE} + +ARG BASE_VERSION_TAG=latest +ARG BASE_IMAGE=ghcr.io/nhsdigital/eps-devcontainers/node_24:${BASE_VERSION_TAG} +ARG SCRIPTS_DIR=/usr/local/share/eps +ARG CONTAINER_NAME +ARG MULTI_ARCH_TAG +ARG BASE_VERSION_TAG +ARG IMAGE_TAG +ARG TARGETARCH + +ENV SCRIPTS_DIR=${SCRIPTS_DIR} +ENV TARGETARCH=${TARGETARCH} + +USER root +COPY --chmod=755 scripts/root_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/root_install.sh +WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} +RUN ./root_install.sh + +COPY --chmod=755 scripts/vscode_install.sh ${SCRIPTS_DIR}/${CONTAINER_NAME}/vscode_install.sh +USER vscode + +WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} +COPY .tool-versions /tmp/.tool-versions +RUN cat /tmp/.tool-versions >> /home/vscode/.tool-versions + +RUN ./vscode_install.sh + +# Switch back to root to install the devcontainer CLI globally +USER root + +ENV CONTAINER_NAME=${CONTAINER_NAME} +ENV MULTI_ARCH_TAG=${MULTI_ARCH_TAG} +ENV BASE_VERSION_TAG=${BASE_VERSION_TAG} +ENV IMAGE_TAG=${IMAGE_TAG} +ENV BASE_IMAGE=${BASE_IMAGE} + +LABEL org.opencontainers.image.description="EPS devcontainer ${CONTAINER_NAME}:${IMAGE_TAG}" +LABEL org.opencontainers.image.version=${IMAGE_TAG} +LABEL org.opencontainers.image.base.name=${BASE_IMAGE} +LABEL org.opencontainers.image.containerName=${CONTAINER_NAME} diff --git a/src/languages/node_24_python_3_12/.devcontainer/.tool-versions b/src/languages/node_24_python_3_12/.devcontainer/.tool-versions index a27ded2..9dedcf5 100644 --- a/src/languages/node_24_python_3_12/.devcontainer/.tool-versions +++ b/src/languages/node_24_python_3_12/.devcontainer/.tool-versions @@ -1,3 +1,2 @@ -nodejs 24.13.0 python 3.12.12 poetry 2.3.2 diff --git a/src/languages/node_24_python_3_12/.devcontainer/devcontainer.json b/src/languages/node_24_python_3_12/.devcontainer/devcontainer.json index 100a86b..0ac0328 100644 --- a/src/languages/node_24_python_3_12/.devcontainer/devcontainer.json +++ b/src/languages/node_24_python_3_12/.devcontainer/devcontainer.json @@ -4,7 +4,7 @@ "name": "EPS Devcontainer node_24 python_3.13", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { - "dockerfile": "../../../common/Dockerfile", + "dockerfile": "../../../common_node_24/Dockerfile", "args": { "CONTAINER_NAME": "eps_devcontainer_${localEnv:CONTAINER_NAME}", "MULTI_ARCH_TAG": "${localEnv:MULTI_ARCH_TAG}", 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 7b9883b..2ef142b 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 @@ -3,7 +3,6 @@ set -e asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git -asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git asdf install python asdf install diff --git a/src/languages/node_24_python_3_13/.devcontainer/.tool-versions b/src/languages/node_24_python_3_13/.devcontainer/.tool-versions index 19c9a1a..85e2d7a 100644 --- a/src/languages/node_24_python_3_13/.devcontainer/.tool-versions +++ b/src/languages/node_24_python_3_13/.devcontainer/.tool-versions @@ -1,3 +1,2 @@ -nodejs 24.13.0 python 3.13.12 poetry 2.3.2 diff --git a/src/languages/node_24_python_3_13/.devcontainer/devcontainer.json b/src/languages/node_24_python_3_13/.devcontainer/devcontainer.json index 100a86b..0ac0328 100644 --- a/src/languages/node_24_python_3_13/.devcontainer/devcontainer.json +++ b/src/languages/node_24_python_3_13/.devcontainer/devcontainer.json @@ -4,7 +4,7 @@ "name": "EPS Devcontainer node_24 python_3.13", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { - "dockerfile": "../../../common/Dockerfile", + "dockerfile": "../../../common_node_24/Dockerfile", "args": { "CONTAINER_NAME": "eps_devcontainer_${localEnv:CONTAINER_NAME}", "MULTI_ARCH_TAG": "${localEnv:MULTI_ARCH_TAG}", 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 7b9883b..2ef142b 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 @@ -3,7 +3,6 @@ set -e asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git -asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git asdf install python asdf install diff --git a/src/languages/node_24_python_3_14/.devcontainer/.tool-versions b/src/languages/node_24_python_3_14/.devcontainer/.tool-versions index ed99ea2..65e66b7 100644 --- a/src/languages/node_24_python_3_14/.devcontainer/.tool-versions +++ b/src/languages/node_24_python_3_14/.devcontainer/.tool-versions @@ -1,3 +1,2 @@ -nodejs 24.13.0 python 3.14.3 poetry 2.3.2 diff --git a/src/languages/node_24_python_3_14/.devcontainer/devcontainer.json b/src/languages/node_24_python_3_14/.devcontainer/devcontainer.json index 19adae8..8580944 100644 --- a/src/languages/node_24_python_3_14/.devcontainer/devcontainer.json +++ b/src/languages/node_24_python_3_14/.devcontainer/devcontainer.json @@ -4,7 +4,7 @@ "name": "EPS Devcontainer node_24 python_3.14", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { - "dockerfile": "../../../common/Dockerfile", + "dockerfile": "../../../common_node_24/Dockerfile", "args": { "CONTAINER_NAME": "eps_devcontainer_${localEnv:CONTAINER_NAME}", "MULTI_ARCH_TAG": "${localEnv:MULTI_ARCH_TAG}", 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 7b9883b..2ef142b 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 @@ -3,7 +3,6 @@ set -e asdf plugin add python asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git -asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git asdf install python asdf install From ef5a91a5b2be2414bffc550d559480ef1fd28a7e Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 13:02:29 +0000 Subject: [PATCH 02/19] build node_24 python 3.10 --- .../.devcontainer/.tool-versions | 0 .../.devcontainer/devcontainer.json | 2 +- .../.devcontainer/scripts/root_install.sh | 0 .../.devcontainer/scripts/vscode_install.sh | 0 .../{python_3_10 => node_24_python_3_10}/.trivyignore.yaml | 0 src/languages/{python_3_10 => node_24_python_3_10}/trivy.yaml | 0 6 files changed, 1 insertion(+), 1 deletion(-) rename src/languages/{python_3_10 => node_24_python_3_10}/.devcontainer/.tool-versions (100%) rename src/languages/{python_3_10 => node_24_python_3_10}/.devcontainer/devcontainer.json (91%) rename src/languages/{python_3_10 => node_24_python_3_10}/.devcontainer/scripts/root_install.sh (100%) rename src/languages/{python_3_10 => node_24_python_3_10}/.devcontainer/scripts/vscode_install.sh (100%) rename src/languages/{python_3_10 => node_24_python_3_10}/.trivyignore.yaml (100%) rename src/languages/{python_3_10 => node_24_python_3_10}/trivy.yaml (100%) diff --git a/src/languages/python_3_10/.devcontainer/.tool-versions b/src/languages/node_24_python_3_10/.devcontainer/.tool-versions similarity index 100% rename from src/languages/python_3_10/.devcontainer/.tool-versions rename to src/languages/node_24_python_3_10/.devcontainer/.tool-versions diff --git a/src/languages/python_3_10/.devcontainer/devcontainer.json b/src/languages/node_24_python_3_10/.devcontainer/devcontainer.json similarity index 91% rename from src/languages/python_3_10/.devcontainer/devcontainer.json rename to src/languages/node_24_python_3_10/.devcontainer/devcontainer.json index f593cf2..a810718 100644 --- a/src/languages/python_3_10/.devcontainer/devcontainer.json +++ b/src/languages/node_24_python_3_10/.devcontainer/devcontainer.json @@ -4,7 +4,7 @@ "name": "EPS Devcontainer node_24 python_3.10", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { - "dockerfile": "../../../common/Dockerfile", + "dockerfile": "../../../common_node_24/Dockerfile", "args": { "CONTAINER_NAME": "eps_devcontainer_${localEnv:CONTAINER_NAME}", "MULTI_ARCH_TAG": "${localEnv:MULTI_ARCH_TAG}", diff --git a/src/languages/python_3_10/.devcontainer/scripts/root_install.sh b/src/languages/node_24_python_3_10/.devcontainer/scripts/root_install.sh similarity index 100% rename from src/languages/python_3_10/.devcontainer/scripts/root_install.sh rename to src/languages/node_24_python_3_10/.devcontainer/scripts/root_install.sh diff --git a/src/languages/python_3_10/.devcontainer/scripts/vscode_install.sh b/src/languages/node_24_python_3_10/.devcontainer/scripts/vscode_install.sh similarity index 100% rename from src/languages/python_3_10/.devcontainer/scripts/vscode_install.sh rename to src/languages/node_24_python_3_10/.devcontainer/scripts/vscode_install.sh diff --git a/src/languages/python_3_10/.trivyignore.yaml b/src/languages/node_24_python_3_10/.trivyignore.yaml similarity index 100% rename from src/languages/python_3_10/.trivyignore.yaml rename to src/languages/node_24_python_3_10/.trivyignore.yaml diff --git a/src/languages/python_3_10/trivy.yaml b/src/languages/node_24_python_3_10/trivy.yaml similarity index 100% rename from src/languages/python_3_10/trivy.yaml rename to src/languages/node_24_python_3_10/trivy.yaml From 514f63b994fe99aa136cabc4911d92a622394e2d Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 13:32:54 +0000 Subject: [PATCH 03/19] common vulns --- .github/workflows/build_all_images.yml | 13 +- .github/workflows/build_multi_arch_image.yml | 6 +- Makefile | 13 +- README.md | 3 +- src/common_node_24/.trivyignore.yaml | 317 ++---------------- .../node_24_python_3_12/.trivyignore.yaml | 26 -- .../node_24_python_3_13/.trivyignore.yaml | 26 -- .../node_24_python_3_14/.trivyignore.yaml | 31 -- 8 files changed, 43 insertions(+), 392 deletions(-) diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index 38c39ce..6c569c8 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest outputs: base_node_folders: ${{ steps.find-folders.outputs.base_node }} - language_folders: ${{ steps.find-folders.outputs.languages }} + node_24_language_folders: ${{ steps.find-folders.outputs.node_24_languages }} project_folders: ${{ steps.find-folders.outputs.projects }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -26,11 +26,11 @@ jobs: - id: find-folders run: | base_node_folders=$(find src/base_node -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') - language_folders=$(find src/languages -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') + node_24_language_folders=$(find src/languages -mindepth 1 -maxdepth 1 -type d -name 'node_24*' -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') project_folders=$(find src/projects -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]') { echo "base_node=$base_node_folders" - echo "languages=$language_folders" + echo "node_24_languages=$node_24_language_folders" echo "projects=$project_folders" } >> "$GITHUB_OUTPUT" package_base_docker_image: @@ -56,7 +56,7 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "base_node" NO_CACHE: ${{ inputs.NO_CACHE }} - package_language_docker_images: + package_node_24_language_docker_images: needs: - package_base_docker_image - package_base_node_images @@ -64,7 +64,7 @@ jobs: strategy: fail-fast: false matrix: - container_name: ${{ fromJson(needs.discover_folders.outputs.language_folders) }} + container_name: ${{ fromJson(needs.discover_folders.outputs.node_24_language_folders) }} uses: ./.github/workflows/build_multi_arch_image.yml with: tag_latest: ${{ inputs.tag_latest }} @@ -72,9 +72,10 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "languages" NO_CACHE: ${{ inputs.NO_CACHE }} + EXTRA_COMMON: "common_node_24" package_project_docker_images: needs: - - package_language_docker_images + - package_node_24_language_docker_images - discover_folders strategy: fail-fast: false diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index 266b768..761e416 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -17,6 +17,9 @@ name: Build and push docker image NO_CACHE: required: true type: boolean + EXTRA_COMMON: + required: false + type: string jobs: build_and_push_image: @@ -88,6 +91,7 @@ jobs: BASE_FOLDER: "${{ inputs.base_folder }}" IMAGE_TAG: "${{ inputs.docker_tag }}-${{ matrix.arch }}" EXIT_CODE: 0 + EXTRA_COMMON: "${{ inputs.extra_common }}" - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f name: Upload scan results with: @@ -101,7 +105,7 @@ jobs: BASE_FOLDER: "${{ inputs.base_folder }}" IMAGE_TAG: "${{ inputs.docker_tag }}-${{ matrix.arch }}" EXIT_CODE: "1" - + EXTRA_COMMON: "${{ inputs.extra_common }}" - name: Show docker vulnerability output if: always() run: | diff --git a/Makefile b/Makefile index 999f69c..a6f537e 100644 --- a/Makefile +++ b/Makefile @@ -41,30 +41,35 @@ build-githubactions-image: guard-BASE_IMAGE_NAME guard-BASE_IMAGE_TAG guard-IMAG . scan-image: guard-CONTAINER_NAME guard-BASE_FOLDER + mkdir -p .out @combined="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore_combined.yaml"; \ common="src/common/.trivyignore.yaml"; \ + extra_common="src/$${EXTRA_COMMON}/.trivyignore.yaml"; \ specific="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore.yaml"; \ exit_code="$${EXIT_CODE:-1}"; \ echo "vulnerabilities:" > "$$combined"; \ if [ -f "$$common" ]; then sed -n '2,$$p' "$$common" >> "$$combined"; fi; \ - if [ -f "$$specific" ]; then sed -n '2,$$p' "$$specific" >> "$$combined"; fi + if [ -f "$$extra_common" ]; then sed -n '2,$$p' "$$extra_common" >> "$$combined"; fi; \ + if [ -f "$$specific" ]; then sed -n '2,$$p' "$$specific" >> "$$combined"; fi; \ trivy image \ --severity HIGH,CRITICAL \ --config src/${BASE_FOLDER}/${CONTAINER_NAME}/trivy.yaml \ --scanners vuln \ - --exit-code "$$exit_code" \ + --exit-code $$exit_code \ --format table \ --output .out/scan_results_docker.txt "${CONTAINER_PREFIX}$${CONTAINER_NAME}:$${IMAGE_TAG}" scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER guard-IMAGE_TAG + mkdir -p .out @combined="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore_combined.yaml"; \ common="src/common/.trivyignore.yaml"; \ + extra_common="src/$${EXTRA_COMMON}/.trivyignore.yaml"; \ specific="src/$${BASE_FOLDER}/$${CONTAINER_NAME}/.trivyignore.yaml"; \ exit_code="$${EXIT_CODE:-1}"; \ echo "vulnerabilities:" > "$$combined"; \ if [ -f "$$common" ]; then sed -n '2,$$p' "$$common" >> "$$combined"; fi; \ - if [ -f "$$specific" ]; then sed -n '2,$$p' "$$specific" >> "$$combined"; fi - mkdir -p .out + if [ -f "$$extra_common" ]; then sed -n '2,$$p' "$$extra_common" >> "$$combined"; fi; \ + if [ -f "$$specific" ]; then sed -n '2,$$p' "$$specific" >> "$$combined"; fi; \ trivy image \ --severity HIGH,CRITICAL \ --config src/${BASE_FOLDER}/${CONTAINER_NAME}/trivy.yaml \ diff --git a/README.md b/README.md index e7983f1..eceae7a 100644 --- a/README.md +++ b/README.md @@ -230,9 +230,10 @@ CONTAINER_NAME=node_24 \ ``` Language images ``` -CONTAINER_NAME=node_24_python_3_12 \ +CONTAINER_NAME=node_24_python_3_14 \ BASE_FOLDER=languages \ IMAGE_TAG=local-build \ + EXTRA_COMMON=common_node_24 \ make scan-image ``` Project images diff --git a/src/common_node_24/.trivyignore.yaml b/src/common_node_24/.trivyignore.yaml index bd4d87e..72db141 100644 --- a/src/common_node_24/.trivyignore.yaml +++ b/src/common_node_24/.trivyignore.yaml @@ -1,309 +1,32 @@ vulnerabilities: - - id: CVE-2024-35870 - statement: "kernel: smb: client: fix UAF in smb2_reconnect_server()" + - id: CVE-2026-25547 + statement: "brace-expansion: brace-expansion: Denial of Service via unbounded brace range expansion" purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + - "pkg:npm/%40isaacs/brace-expansion@5.0.0" expired_at: 2026-08-12 - - id: CVE-2024-53179 - statement: "kernel: smb: client: fix use-after-free of signing key" + - id: CVE-2025-64756 + statement: "glob: glob: Command Injection Vulnerability via Malicious Filenames" purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + - "pkg:npm/glob@10.4.5" + - "pkg:npm/glob@11.0.3" expired_at: 2026-08-12 - - id: CVE-2025-37849 - statement: "kernel: KVM: arm64: Tear down vGIC on failed vCPU creation" + - id: CVE-2026-23745 + statement: "node-tar: tar: node-tar: Arbitrary file overwrite and symlink poisoning via unsanitized linkpaths in archives" purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + - "pkg:npm/tar@7.5.1" expired_at: 2026-08-12 - - id: CVE-2025-37899 - statement: "kernel: ksmbd: fix use-after-free in session logoff" + - id: CVE-2026-23950 + statement: "node-tar: tar: node-tar: Arbitrary file overwrite via Unicode path collision race condition" purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + - "pkg:npm/tar@7.5.1" expired_at: 2026-08-12 - - id: CVE-2025-38118 - statement: "kernel: Linux kernel: Bluetooth MGMT use-after-free vulnerability allows privilege escalation" + - id: CVE-2026-24842 + statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=amd64&distro=ubuntu-22.04" + - "pkg:npm/tar@7.5.1" expired_at: 2026-08-12 - - id: CVE-2026-26007 - statement: "cryptography: cryptography Subgroup Attack Due to Missing Subgroup Validation for SECT Curves" + - id: CVE-2026-26960 + statement: "Arbitrary File Read/Write via Hardlink Target Escape Through Symlink Chain in node-tar Extraction" purls: - - "pkg:pypi/cryptography@46.0.3" - expired_at: 2026-08-12 - - id: CVE-2024-49761 - statement: "rexml: REXML ReDoS vulnerability" - purls: - - "pkg:gem/rexml@3.2.6" - expired_at: 2026-08-12 - - id: CVE-2025-68121 - statement: "During session resumption in crypto/tls, if the underlying Config has ..." - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - - "pkg:golang/stdlib@v1.24.9" - - "pkg:golang/stdlib@v1.25.5" - expired_at: 2026-08-12 - - id: CVE-2025-61726 - statement: "golang: net/url: Memory exhaustion in query parameter parsing in net/url" - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - - "pkg:golang/stdlib@v1.24.9" - - "pkg:golang/stdlib@v1.25.5" - expired_at: 2026-08-12 - - id: CVE-2025-61728 - statement: "golang: archive/zip: Excessive CPU consumption when building archive index in archive/zip" - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - - "pkg:golang/stdlib@v1.24.9" - - "pkg:golang/stdlib@v1.25.5" - expired_at: 2026-08-12 - - id: CVE-2025-61730 - statement: "During the TLS 1.3 handshake if multiple messages are sent in records ..." - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - - "pkg:golang/stdlib@v1.24.9" - - "pkg:golang/stdlib@v1.25.5" - expired_at: 2026-08-12 - - id: CVE-2025-47907 - statement: "database/sql: Postgres Scan Race Condition" - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - expired_at: 2026-08-12 - - id: CVE-2025-58183 - statement: "golang: archive/tar: Unbounded allocation when parsing GNU sparse map" - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - expired_at: 2026-08-12 - - id: CVE-2025-61729 - statement: "crypto/x509: golang: Denial of Service due to excessive resource consumption via crafted certificate" - purls: - - "pkg:golang/stdlib@v1.16.15" - - "pkg:golang/stdlib@v1.23.4" - - "pkg:golang/stdlib@v1.24.4" - - "pkg:golang/stdlib@v1.24.9" - expired_at: 2026-08-12 - - id: CVE-2023-24538 - statement: "golang: html/template: backticks not treated as string delimiters" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-24540 - statement: "golang: html/template: improper handling of JavaScript whitespace" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2024-24790 - statement: "golang: net/netip: Unexpected behavior from Is methods for IPv4-mapped IPv6 addresses" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-24675 - statement: "golang: encoding/pem: fix stack overflow in Decode" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-27664 - statement: "golang: net/http: handle server errors after sending GOAWAY" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-28131 - statement: "golang: encoding/xml: stack exhaustion in Decoder.Skip" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-28327 - statement: "golang: crypto/elliptic: panic caused by oversized scalar" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-2879 - statement: "golang: archive/tar: github.com/vbatts/tar-split: unbounded memory consumption when reading headers" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-2880 - statement: "golang: net/http/httputil: ReverseProxy should not forward unparseable query parameters" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-29804 - statement: "ELSA-2022-17957: ol8addon security update (IMPORTANT)" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30580 - statement: "golang: os/exec: Code injection in Cmd.Start" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30630 - statement: "golang: io/fs: stack exhaustion in Glob" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30631 - statement: "golang: compress/gzip: stack exhaustion in Reader.Read" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30632 - statement: "golang: path/filepath: stack exhaustion in Glob" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30633 - statement: "golang: encoding/xml: stack exhaustion in Unmarshal" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30634 - statement: "ELSA-2022-17957: ol8addon security update (IMPORTANT)" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-30635 - statement: "golang: encoding/gob: stack exhaustion in Decoder.Decode" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-32189 - statement: "golang: math/big: decoding big.Float and big.Rat types can panic if the encoded message is too short, potentially allowing a denial of service" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41715 - statement: "golang: regexp/syntax: limit memory used by parsing regexps" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41716 - statement: "Due to unsanitized NUL values, attackers may be able to maliciously se ..." - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41720 - statement: "golang: os, net/http: avoid escapes from os.DirFS and http.Dir on Windows" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41722 - statement: "golang: path/filepath: path-filepath filepath.Clean path traversal" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41723 - statement: "golang.org/x/net/http2: avoid quadratic complexity in HPACK decoding" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41724 - statement: "golang: crypto/tls: large handshake records may cause panics" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2022-41725 - statement: "golang: net/http, mime/multipart: denial of service from excessive resource consumption" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-24534 - statement: "golang: net/http, net/textproto: denial of service from excessive memory allocation" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-24536 - statement: "golang: net/http, net/textproto, mime/multipart: denial of service from excessive resource consumption" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-24537 - statement: "golang: go/parser: Infinite loop in parsing" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-24539 - statement: "golang: html/template: improper sanitization of CSS values" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-29400 - statement: "golang: html/template: improper handling of empty HTML attributes" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-29403 - statement: "golang: runtime: unexpected behavior of setuid/setgid binaries" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-39325 - statement: "golang: net/http, x/net/http2: rapid stream resets can cause excessive work (CVE-2023-44487)" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-45283 - statement: "The filepath package does not recognize paths with a \\??\\ prefix as sp ..." - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-45287 - statement: "golang: crypto/tls: Timing Side Channel attack in RSA based TLS key exchanges." - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2023-45288 - statement: "golang: net/http, x/net/http2: unlimited number of CONTINUATION frames causes DoS" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2024-34156 - statement: "encoding/gob: golang: Calling Decoder.Decode on a message which contains deeply nested structures can cause a panic due to stack exhaustion" - purls: - - "pkg:golang/stdlib@v1.16.15" - expired_at: 2026-08-12 - - id: CVE-2024-25621 - statement: "github.com/containerd/containerd: containerd local privilege escalation" - purls: - - "pkg:golang/github.com/containerd/containerd/v2@v2.1.4" - expired_at: 2026-08-12 - - id: CVE-2024-35870 - statement: "kernel: smb: client: fix UAF in smb2_reconnect_server()" - purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" - expired_at: 2026-08-12 - - id: CVE-2024-53179 - statement: "kernel: smb: client: fix use-after-free of signing key" - purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" - expired_at: 2026-08-12 - - id: CVE-2025-37849 - statement: "kernel: KVM: arm64: Tear down vGIC on failed vCPU creation" - purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" - expired_at: 2026-08-12 - - id: CVE-2025-37899 - statement: "kernel: ksmbd: fix use-after-free in session logoff" - purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" - expired_at: 2026-08-12 - - id: CVE-2025-38118 - statement: "kernel: Linux kernel: Bluetooth MGMT use-after-free vulnerability allows privilege escalation" - purls: - - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-170.180?arch=arm64&distro=ubuntu-22.04" - expired_at: 2026-08-12 - - id: CVE-2025-68121 - statement: "crypto/tls: Unexpected session resumption in crypto/tls" - purls: - - "pkg:golang/stdlib@v1.25.6" - expired_at: 2026-08-13 + - "pkg:npm/tar@7.5.1" + expired_at: 2026-08-18 diff --git a/src/languages/node_24_python_3_12/.trivyignore.yaml b/src/languages/node_24_python_3_12/.trivyignore.yaml index a8010cf..8697da6 100644 --- a/src/languages/node_24_python_3_12/.trivyignore.yaml +++ b/src/languages/node_24_python_3_12/.trivyignore.yaml @@ -1,27 +1 @@ vulnerabilities: - - id: CVE-2026-25547 - statement: "brace-expansion: brace-expansion: Denial of Service via unbounded brace range expansion" - purls: - - "pkg:npm/%40isaacs/brace-expansion@5.0.0" - expired_at: 2026-08-12 - - id: CVE-2025-64756 - statement: "glob: glob: Command Injection Vulnerability via Malicious Filenames" - purls: - - "pkg:npm/glob@10.4.5" - - "pkg:npm/glob@11.0.3" - expired_at: 2026-08-12 - - id: CVE-2026-23745 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite and symlink poisoning via unsanitized linkpaths in archives" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 - - id: CVE-2026-23950 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite via Unicode path collision race condition" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 - - id: CVE-2026-24842 - statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 diff --git a/src/languages/node_24_python_3_13/.trivyignore.yaml b/src/languages/node_24_python_3_13/.trivyignore.yaml index a8010cf..8697da6 100644 --- a/src/languages/node_24_python_3_13/.trivyignore.yaml +++ b/src/languages/node_24_python_3_13/.trivyignore.yaml @@ -1,27 +1 @@ vulnerabilities: - - id: CVE-2026-25547 - statement: "brace-expansion: brace-expansion: Denial of Service via unbounded brace range expansion" - purls: - - "pkg:npm/%40isaacs/brace-expansion@5.0.0" - expired_at: 2026-08-12 - - id: CVE-2025-64756 - statement: "glob: glob: Command Injection Vulnerability via Malicious Filenames" - purls: - - "pkg:npm/glob@10.4.5" - - "pkg:npm/glob@11.0.3" - expired_at: 2026-08-12 - - id: CVE-2026-23745 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite and symlink poisoning via unsanitized linkpaths in archives" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 - - id: CVE-2026-23950 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite via Unicode path collision race condition" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 - - id: CVE-2026-24842 - statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 diff --git a/src/languages/node_24_python_3_14/.trivyignore.yaml b/src/languages/node_24_python_3_14/.trivyignore.yaml index 57d92bd..8799951 100644 --- a/src/languages/node_24_python_3_14/.trivyignore.yaml +++ b/src/languages/node_24_python_3_14/.trivyignore.yaml @@ -1,14 +1,4 @@ vulnerabilities: - - id: CVE-2026-25547 - statement: "brace-expansion: brace-expansion: Denial of Service via unbounded brace range expansion" - purls: - - "pkg:npm/%40isaacs/brace-expansion@5.0.0" - expired_at: 2026-08-12 - - id: CVE-2026-24842 - statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" - purls: - - "pkg:npm/tar@7.5.4" - expired_at: 2026-08-12 - id: CVE-2026-23949 statement: "jaraco.context: jaraco.context: Path traversal via malicious tar archives" purls: @@ -19,24 +9,3 @@ vulnerabilities: purls: - "pkg:pypi/wheel@0.45.1" expired_at: 2026-08-12 - - id: CVE-2025-64756 - statement: "glob: glob: Command Injection Vulnerability via Malicious Filenames" - purls: - - "pkg:npm/glob@10.4.5" - - "pkg:npm/glob@11.0.3" - expired_at: 2026-08-13 - - id: CVE-2026-23745 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite and symlink poisoning via unsanitized linkpaths in archives" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-13 - - id: CVE-2026-23950 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite via Unicode path collision race condition" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-13 - - id: CVE-2026-24842 - statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-13 From de930c20f565e91c80a0acff257eb915af602528 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:11:04 +0000 Subject: [PATCH 04/19] use image --- .devcontainer/Dockerfile | 108 +++---------------- .devcontainer/devcontainer.json | 23 ++-- .github/workflows/build_all_images.yml | 7 ++ .github/workflows/build_multi_arch_image.yml | 13 +++ .github/workflows/ci.yml | 20 +++- .github/workflows/pull_request.yml | 17 +++ .github/workflows/release.yml | 20 +++- README.md | 11 +- 8 files changed, 104 insertions(+), 115 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 0e7ee62..3903c81 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,98 +1,14 @@ -FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04 -ARG TARGETARCH -ENV TARGETARCH=${TARGETARCH} - -# Install essential packages first -RUN apt-get update && apt-get install -y \ - curl \ - wget \ - git \ - sudo \ - unzip \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Copy ASDF version file -ARG ASDF_VERSION -COPY .tool-versions.asdf /tmp/.tool-versions.asdf - -# Add amd64 architecture if on arm64 -RUN if [ "$TARGETARCH" == "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then dpkg --add-architecture amd64; fi - -RUN apt-get update \ - && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y dist-upgrade \ - && apt-get -y install --no-install-recommends htop vim curl git build-essential \ - libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev libbz2-dev \ - zlib1g-dev unixodbc unixodbc-dev libsecret-1-0 libsecret-1-dev libsqlite3-dev \ - jq apt-transport-https ca-certificates gnupg-agent \ - software-properties-common bash-completion python3-pip make libbz2-dev \ - libreadline-dev libsqlite3-dev wget llvm libncurses5-dev libncursesw5-dev \ - xz-utils tk-dev liblzma-dev netcat-traditional libyaml-dev uuid-runtime xxd unzip - -# install aws stuff -# Download correct AWS CLI for arch -RUN if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then \ - wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"; \ - else \ - wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"; \ - fi && \ - unzip /tmp/awscliv2.zip -d /tmp/aws-cli && \ - /tmp/aws-cli/aws/install && \ - rm /tmp/awscliv2.zip && rm -rf /tmp/aws-cli - -# Install ASDF -RUN ASDF_VERSION=$(awk '!/^#/ && NF {print $1; exit}' /tmp/.tool-versions.asdf) && \ - if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then \ - wget -O /tmp/asdf.tar.gz "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-arm64.tar.gz"; \ +ARG IMAGE_NAME=node_24_python_3_14 +ARG IMAGE_VERSION=latest +FROM ghcr.io/nhsdigital/eps-devcontainers/${IMAGE_NAME}:${IMAGE_VERSION} + +USER root +# specify DOCKER_GID to force container docker group id to match host +RUN if [ -n "${DOCKER_GID}" ]; then \ + if ! getent group docker; then \ + groupadd -g ${DOCKER_GID} docker; \ else \ - wget -O /tmp/asdf.tar.gz "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-amd64.tar.gz"; \ + groupmod -g ${DOCKER_GID} docker; \ 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 - -# install gitsecrets -RUN git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets && \ - cd /tmp/git-secrets && \ - make install && \ - cd && \ - rm -rf /tmp/git-secrets && \ - mkdir -p /usr/share/secrets-scanner && \ - 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 - -USER vscode - -ENV PATH="/home/vscode/.asdf/shims/:$PATH:/workspaces/eps-devcontainers/node_modules/.bin" -RUN \ - echo 'PATH="/home/vscode/.asdf/shims/:$PATH:/workspaces/eps-devcontainers/node_modules/.bin"' >> ~/.bashrc; \ - echo '. <(asdf completion bash)' >> ~/.bashrc; \ - echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc; \ - echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc; \ - echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc; - -# Install ASDF plugins -RUN asdf plugin add python; \ - asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git; \ - asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git; \ - asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git; \ - asdf plugin add direnv; \ - asdf plugin add actionlint; \ - asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git; \ - asdf plugin add trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git; \ - asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git - - -WORKDIR /workspaces/eps-devcontainers -COPY .tool-versions /workspaces/eps-devcontainers/.tool-versions -COPY .tool-versions /home/vscode/.tool-versions - -# install python before poetry to ensure correct python version is used -RUN asdf install python; \ - asdf install - -RUN git-secrets --register-aws --global && \ - git-secrets --add-provider --global -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt + usermod -aG docker vscode; \ + fi diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b08221a..bd51852 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,11 +3,19 @@ { "name": "eps-devcontainers", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "build": { - "dockerfile": "Dockerfile", - "context": "..", - "args": {} + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "args": { + "DOCKER_GID": "${env:DOCKER_GID:}", + "IMAGE_NAME": "node_24_python_3_14", + "IMAGE_VERSION": "v1.0.4", + "USER_UID": "${localEnv:USER_ID:}", + "USER_GID": "${localEnv:GROUP_ID:}" }, + "updateRemoteUserUID": false + }, + "postAttachCommand": "git-secrets --register-aws; git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt", "mounts": [ "source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind", "source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind", @@ -18,14 +26,7 @@ "--network=host" ], "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" }, - "postAttachCommand": "docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v4.0.4/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . && poetry run pre-commit install --install-hooks -f", "features": { - "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { - "version": "latest", - "moby": "true", - "installDockerBuildx": "true" - }, - "ghcr.io/devcontainers/features/github-cli:1": {} }, "customizations": { "vscode": { diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index 6c569c8..61433bb 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -11,6 +11,9 @@ name: build_all_images NO_CACHE: required: true type: boolean + runtime_docker_image: + type: string + required: true env: BRANCH_NAME: '${{ github.event.pull_request.head.ref }}' jobs: @@ -41,6 +44,7 @@ jobs: container_name: base base_folder: "." NO_CACHE: ${{ inputs.NO_CACHE }} + runtime_docker_image: ${{ inputs.runtime_docker_image }} package_base_node_images: needs: - package_base_docker_image @@ -56,6 +60,7 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "base_node" NO_CACHE: ${{ inputs.NO_CACHE }} + runtime_docker_image: ${{ inputs.runtime_docker_image }} package_node_24_language_docker_images: needs: - package_base_docker_image @@ -73,6 +78,7 @@ jobs: base_folder: "languages" NO_CACHE: ${{ inputs.NO_CACHE }} EXTRA_COMMON: "common_node_24" + runtime_docker_image: ${{ inputs.runtime_docker_image }} package_project_docker_images: needs: - package_node_24_language_docker_images @@ -88,3 +94,4 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "projects" NO_CACHE: ${{ inputs.NO_CACHE }} + runtime_docker_image: ${{ inputs.runtime_docker_image }} diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index 761e416..0efe030 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -20,6 +20,9 @@ name: Build and push docker image EXTRA_COMMON: required: false type: string + runtime_docker_image: + type: string + required: true jobs: build_and_push_image: @@ -30,6 +33,13 @@ jobs: attestations: write id-token: write runs-on: '${{ matrix.runner }}' + container: + image: ghcr.io/nhsdigital/eps-devcontainers/${{ inputs.runtime_docker_image }} + options: --user 1001:1001 --group-add 128 + defaults: + run: + shell: bash + strategy: fail-fast: false matrix: @@ -39,6 +49,9 @@ jobs: - arch: arm64 runner: ubuntu-22.04-arm steps: + - name: copy .tool-versions + run: | + cp /home/vscode/.tool-versions "$HOME/.tool-versions" - name: Free Disk Space for Docker uses: endersonmenezes/free-disk-space@e6ed9b02e683a3b55ed0252f1ee469ce3b39a885 with: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a83ccb..4ada558 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,21 @@ on: branches: [main] jobs: + get_config_values: + runs-on: ubuntu-22.04 + outputs: + devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }} + devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_VERSION }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Load config value + id: load-config + run: | + DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json) + DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json) + echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT" + echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_IMAGE_VERSION" >> "$GITHUB_OUTPUT" get_asdf_version: runs-on: ubuntu-22.04 outputs: @@ -40,9 +55,12 @@ jobs: tag_format: ${{ needs.get_asdf_version.outputs.tag_format }} secrets: inherit build_all_images: - needs: tag_release + needs: + - tag_release + - get_config_values uses: ./.github/workflows/build_all_images.yml with: docker_tag: 'ci-${{ needs.tag_release.outputs.version_tag }}' tag_latest: false NO_CACHE: false + runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image_name }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_image_version }}" diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 7edbec3..692af0b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -6,6 +6,21 @@ name: pull_request env: BRANCH_NAME: '${{ github.event.pull_request.head.ref }}' jobs: + get_config_values: + runs-on: ubuntu-22.04 + outputs: + devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }} + devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_VERSION }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Load config value + id: load-config + run: | + DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json) + DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json) + echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT" + echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_IMAGE_VERSION" >> "$GITHUB_OUTPUT" dependabot-auto-approve-and-merge: needs: quality_checks uses: >- @@ -88,8 +103,10 @@ jobs: needs: - get_issue_number - get_commit_id + - get_config_values uses: ./.github/workflows/build_all_images.yml with: docker_tag: 'pr-${{ needs.get_issue_number.outputs.issue_number }}-${{ needs.get_commit_id.outputs.sha_short }}' tag_latest: false NO_CACHE: false + runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image_name }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_image_version }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15d64c1..acf2ed9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,21 @@ on: - cron: "0 18 * * 4" jobs: + get_config_values: + runs-on: ubuntu-22.04 + outputs: + devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }} + devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_VERSION }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Load config value + id: load-config + run: | + DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json) + DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json) + echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT" + echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_IMAGE_VERSION" >> "$GITHUB_OUTPUT" get_asdf_version: runs-on: ubuntu-22.04 outputs: @@ -41,9 +56,12 @@ jobs: tag_format: ${{ needs.get_asdf_version.outputs.tag_format }} secrets: inherit build_all_images: - needs: tag_release + needs: + - tag_release + - get_config_values uses: ./.github/workflows/build_all_images.yml with: docker_tag: '${{ needs.tag_release.outputs.version_tag }}' tag_latest: true NO_CACHE: true + runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image_name }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_image_version }}" diff --git a/README.md b/README.md index eceae7a..077ae9e 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,11 @@ It is important that - there is `options: --user 1001:1001 --group-add 128` below image to ensure it uses the correct user id and is added to the docker group - the default shell is set to be bash - the first step copies .tool-versions from /home/vscode to $HOME/.tool-versions +## Using local or pull request images in visual studio code +You can use local or pull request images by changing IMAGE_VERSION in devcontainer.json. +For an image built locally following instructions below, you should put the IMAGE_VERSION=local-build. +For an image built from a pull request, you should put the IMAGE_VERSION=. +You can only use images built from a pull request for testing changes in github actions. # Project structure We have 5 types of dev container. These are defined under src @@ -271,12 +276,6 @@ CONTAINER_NAME=base \ make shell-image ``` -## Using local or pull request images in visual studio code -You can use local or pull request images by changing IMAGE_VERSION in devcontainer.json. -For an image built locally, you should put the IMAGE_VERSION=local-build. -For an image built from a pull request, you should put the IMAGE_VERSION=. -You can only use images built from a pull request for testing changes in github actions. - ## Generating a .trivyignore file You can generate a .trivyignore file for known vulnerabilities by either downloading the json scan output generated by the build, or by generating it locally using the scanning images commands above with a make target of scan-image-json From bfc01c7f5935844afa191ae95f9af12e4361c18f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:16:20 +0000 Subject: [PATCH 05/19] fix devcontainer.json --- .devcontainer/devcontainer.json | 136 +++++++++++++++----------------- 1 file changed, 64 insertions(+), 72 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bd51852..2b7fd08 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,5 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu { - "name": "eps-devcontainers", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "name": "eps-devcontainers", "build": { "dockerfile": "Dockerfile", "context": "..", @@ -16,72 +13,67 @@ "updateRemoteUserUID": false }, "postAttachCommand": "git-secrets --register-aws; git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt", - "mounts": [ - "source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind", - "source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind", - "source=${env:HOME}${env:USERPROFILE}/.gnupg,target=/home/vscode/.gnupg,type=bind", - "source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind" - ], - "runArgs": [ - "--network=host" - ], - "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" }, - "features": { - }, - "customizations": { - "vscode": { - "extensions": [ - "AmazonWebServices.aws-toolkit-vscode", - "redhat.vscode-yaml", - "ms-python.python", - "ms-python.flake8", - "eamodio.gitlens", - "github.vscode-pull-request-github", - "orta.vscode-jest", - "42crunch.vscode-openapi", - "mermade.openapi-lint", - "christian-kohler.npm-intellisense", - "dbaeumer.vscode-eslint", - "lfm.vscode-makefile-term", - "GrapeCity.gc-excelviewer", - "redhat.vscode-xml", - "streetsidesoftware.code-spell-checker", - "timonwong.shellcheck", - "mkhl.direnv", - "github.vscode-github-actions", - "Gruntfuggly.todo-tree", - "ms-vscode.makefile-tools" + "mounts": [ + "source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind", + "source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind", + "source=${env:HOME}${env:USERPROFILE}/.gnupg,target=/home/vscode/.gnupg,type=bind", + "source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind" + ], + "runArgs": [ + "--network=host" + ], + "remoteEnv": { + "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" + }, + "features": {}, + "customizations": { + "vscode": { + "extensions": [ + "AmazonWebServices.aws-toolkit-vscode", + "redhat.vscode-yaml", + "ms-python.python", + "ms-python.flake8", + "eamodio.gitlens", + "github.vscode-pull-request-github", + "orta.vscode-jest", + "42crunch.vscode-openapi", + "mermade.openapi-lint", + "christian-kohler.npm-intellisense", + "dbaeumer.vscode-eslint", + "lfm.vscode-makefile-term", + "GrapeCity.gc-excelviewer", + "redhat.vscode-xml", + "streetsidesoftware.code-spell-checker", + "timonwong.shellcheck", + "mkhl.direnv", + "github.vscode-github-actions", + "Gruntfuggly.todo-tree", + "ms-vscode.makefile-tools" + ], + "settings": { + "python.defaultInterpreterPath": "/workspaces/eps-devcontainers/.venv/bin/python", + "python.analysis.autoSearchPaths": true, + "python.analysis.extraPaths": [], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "pylint.enabled": false, + "python.linting.flake8Enabled": true, + "python.linting.enabled": true, + "editor.formatOnPaste": false, + "editor.formatOnType": false, + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + "cSpell.words": [ + "fhir", + "Formik", + "pino", + "serialisation" ], - "settings": { - "python.defaultInterpreterPath": "/workspaces/eps-devcontainers/.venv/bin/python", - "python.analysis.autoSearchPaths": true, - "python.analysis.extraPaths": [], - "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true, - "pylint.enabled": false, - "python.linting.flake8Enabled": true, - "python.linting.enabled": true, // required to format on save - "editor.formatOnPaste": false, // required - "editor.formatOnType": false, // required - "editor.formatOnSave": true, // optional - "editor.formatOnSaveMode": "file", - "cSpell.words": ["fhir", "Formik", "pino", "serialisation"], - "editor.defaultFormatter": "dbaeumer.vscode-eslint" - - }, - "eslint.useFlatConfig": true, - "eslint.format.enable": true - } - }, - "postCreateCommand": "rm -f ~/.docker/config.json; git config --global --add safe.directory /workspaces/eps-devcontainers; make install; direnv allow ." - // "features": {}, - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "" - // Configure tool-specific properties. - // "customizations": {}, - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" - } - + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + "eslint.useFlatConfig": true, + "eslint.format.enable": true + } + }, + "postCreateCommand": "rm -f ~/.docker/config.json; git config --global --add safe.directory /workspaces/eps-devcontainers; make install; direnv allow ." +} From 4456909ce53b3fc4eaa811b3679da01ad179cf23 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:36:02 +0000 Subject: [PATCH 06/19] do not need setup-node --- .github/workflows/build_multi_arch_image.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index 0efe030..86f9714 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -75,10 +75,6 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 - - name: setup node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 - with: - node-version-file: .tool-versions - name: make install run: | From 9af4241742e57c96c8220a344d8abbfa112f7f76 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:43:40 +0000 Subject: [PATCH 07/19] revert --- .devcontainer/Dockerfile | 108 +++++++++++-- .devcontainer/devcontainer.json | 159 ++++++++++--------- .github/workflows/build_all_images.yml | 7 - .github/workflows/build_multi_arch_image.yml | 12 -- .github/workflows/ci.yml | 17 -- .github/workflows/pull_request.yml | 1 - .github/workflows/release.yml | 17 -- 7 files changed, 179 insertions(+), 142 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 3903c81..0e7ee62 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,14 +1,98 @@ -ARG IMAGE_NAME=node_24_python_3_14 -ARG IMAGE_VERSION=latest -FROM ghcr.io/nhsdigital/eps-devcontainers/${IMAGE_NAME}:${IMAGE_VERSION} - -USER root -# specify DOCKER_GID to force container docker group id to match host -RUN if [ -n "${DOCKER_GID}" ]; then \ - if ! getent group docker; then \ - groupadd -g ${DOCKER_GID} docker; \ +FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04 +ARG TARGETARCH +ENV TARGETARCH=${TARGETARCH} + +# Install essential packages first +RUN apt-get update && apt-get install -y \ + curl \ + wget \ + git \ + sudo \ + unzip \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Copy ASDF version file +ARG ASDF_VERSION +COPY .tool-versions.asdf /tmp/.tool-versions.asdf + +# Add amd64 architecture if on arm64 +RUN if [ "$TARGETARCH" == "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then dpkg --add-architecture amd64; fi + +RUN apt-get update \ + && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y dist-upgrade \ + && apt-get -y install --no-install-recommends htop vim curl git build-essential \ + libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev libbz2-dev \ + zlib1g-dev unixodbc unixodbc-dev libsecret-1-0 libsecret-1-dev libsqlite3-dev \ + jq apt-transport-https ca-certificates gnupg-agent \ + software-properties-common bash-completion python3-pip make libbz2-dev \ + libreadline-dev libsqlite3-dev wget llvm libncurses5-dev libncursesw5-dev \ + xz-utils tk-dev liblzma-dev netcat-traditional libyaml-dev uuid-runtime xxd unzip + +# install aws stuff +# Download correct AWS CLI for arch +RUN if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then \ + wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"; \ + else \ + wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"; \ + fi && \ + unzip /tmp/awscliv2.zip -d /tmp/aws-cli && \ + /tmp/aws-cli/aws/install && \ + rm /tmp/awscliv2.zip && rm -rf /tmp/aws-cli + +# Install ASDF +RUN ASDF_VERSION=$(awk '!/^#/ && NF {print $1; exit}' /tmp/.tool-versions.asdf) && \ + if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then \ + wget -O /tmp/asdf.tar.gz "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-arm64.tar.gz"; \ else \ - groupmod -g ${DOCKER_GID} docker; \ + wget -O /tmp/asdf.tar.gz "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-amd64.tar.gz"; \ fi && \ - usermod -aG docker vscode; \ - 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 + +# install gitsecrets +RUN git clone https://github.com/awslabs/git-secrets.git /tmp/git-secrets && \ + cd /tmp/git-secrets && \ + make install && \ + cd && \ + rm -rf /tmp/git-secrets && \ + mkdir -p /usr/share/secrets-scanner && \ + 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 + +USER vscode + +ENV PATH="/home/vscode/.asdf/shims/:$PATH:/workspaces/eps-devcontainers/node_modules/.bin" +RUN \ + echo 'PATH="/home/vscode/.asdf/shims/:$PATH:/workspaces/eps-devcontainers/node_modules/.bin"' >> ~/.bashrc; \ + echo '. <(asdf completion bash)' >> ~/.bashrc; \ + echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc; \ + echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc; \ + echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc; + +# Install ASDF plugins +RUN asdf plugin add python; \ + asdf plugin add poetry https://github.com/asdf-community/asdf-poetry.git; \ + asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git; \ + asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git; \ + asdf plugin add direnv; \ + asdf plugin add actionlint; \ + asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git; \ + asdf plugin add trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git; \ + asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git + + +WORKDIR /workspaces/eps-devcontainers +COPY .tool-versions /workspaces/eps-devcontainers/.tool-versions +COPY .tool-versions /home/vscode/.tool-versions + +# install python before poetry to ensure correct python version is used +RUN asdf install python; \ + asdf install + +RUN git-secrets --register-aws --global && \ + git-secrets --add-provider --global -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2b7fd08..b08221a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,79 +1,86 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu { - "name": "eps-devcontainers", - "build": { - "dockerfile": "Dockerfile", - "context": "..", - "args": { - "DOCKER_GID": "${env:DOCKER_GID:}", - "IMAGE_NAME": "node_24_python_3_14", - "IMAGE_VERSION": "v1.0.4", - "USER_UID": "${localEnv:USER_ID:}", - "USER_GID": "${localEnv:GROUP_ID:}" + "name": "eps-devcontainers", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "args": {} }, - "updateRemoteUserUID": false - }, - "postAttachCommand": "git-secrets --register-aws; git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt", - "mounts": [ - "source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind", - "source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind", - "source=${env:HOME}${env:USERPROFILE}/.gnupg,target=/home/vscode/.gnupg,type=bind", - "source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind" - ], - "runArgs": [ - "--network=host" - ], - "remoteEnv": { - "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" - }, - "features": {}, - "customizations": { - "vscode": { - "extensions": [ - "AmazonWebServices.aws-toolkit-vscode", - "redhat.vscode-yaml", - "ms-python.python", - "ms-python.flake8", - "eamodio.gitlens", - "github.vscode-pull-request-github", - "orta.vscode-jest", - "42crunch.vscode-openapi", - "mermade.openapi-lint", - "christian-kohler.npm-intellisense", - "dbaeumer.vscode-eslint", - "lfm.vscode-makefile-term", - "GrapeCity.gc-excelviewer", - "redhat.vscode-xml", - "streetsidesoftware.code-spell-checker", - "timonwong.shellcheck", - "mkhl.direnv", - "github.vscode-github-actions", - "Gruntfuggly.todo-tree", - "ms-vscode.makefile-tools" - ], - "settings": { - "python.defaultInterpreterPath": "/workspaces/eps-devcontainers/.venv/bin/python", - "python.analysis.autoSearchPaths": true, - "python.analysis.extraPaths": [], - "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true, - "pylint.enabled": false, - "python.linting.flake8Enabled": true, - "python.linting.enabled": true, - "editor.formatOnPaste": false, - "editor.formatOnType": false, - "editor.formatOnSave": true, - "editor.formatOnSaveMode": "file", - "cSpell.words": [ - "fhir", - "Formik", - "pino", - "serialisation" - ], - "editor.defaultFormatter": "dbaeumer.vscode-eslint" + "mounts": [ + "source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind", + "source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind", + "source=${env:HOME}${env:USERPROFILE}/.gnupg,target=/home/vscode/.gnupg,type=bind", + "source=${env:HOME}${env:USERPROFILE}/.npmrc,target=/home/vscode/.npmrc,type=bind" + ], + "runArgs": [ + "--network=host" + ], + "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" }, + "postAttachCommand": "docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v4.0.4/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . && poetry run pre-commit install --install-hooks -f", + "features": { + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "version": "latest", + "moby": "true", + "installDockerBuildx": "true" }, - "eslint.useFlatConfig": true, - "eslint.format.enable": true - } - }, - "postCreateCommand": "rm -f ~/.docker/config.json; git config --global --add safe.directory /workspaces/eps-devcontainers; make install; direnv allow ." -} + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "AmazonWebServices.aws-toolkit-vscode", + "redhat.vscode-yaml", + "ms-python.python", + "ms-python.flake8", + "eamodio.gitlens", + "github.vscode-pull-request-github", + "orta.vscode-jest", + "42crunch.vscode-openapi", + "mermade.openapi-lint", + "christian-kohler.npm-intellisense", + "dbaeumer.vscode-eslint", + "lfm.vscode-makefile-term", + "GrapeCity.gc-excelviewer", + "redhat.vscode-xml", + "streetsidesoftware.code-spell-checker", + "timonwong.shellcheck", + "mkhl.direnv", + "github.vscode-github-actions", + "Gruntfuggly.todo-tree", + "ms-vscode.makefile-tools" + ], + "settings": { + "python.defaultInterpreterPath": "/workspaces/eps-devcontainers/.venv/bin/python", + "python.analysis.autoSearchPaths": true, + "python.analysis.extraPaths": [], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "pylint.enabled": false, + "python.linting.flake8Enabled": true, + "python.linting.enabled": true, // required to format on save + "editor.formatOnPaste": false, // required + "editor.formatOnType": false, // required + "editor.formatOnSave": true, // optional + "editor.formatOnSaveMode": "file", + "cSpell.words": ["fhir", "Formik", "pino", "serialisation"], + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + + }, + "eslint.useFlatConfig": true, + "eslint.format.enable": true + } + }, + "postCreateCommand": "rm -f ~/.docker/config.json; git config --global --add safe.directory /workspaces/eps-devcontainers; make install; direnv allow ." + // "features": {}, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "" + // Configure tool-specific properties. + // "customizations": {}, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" + } + diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index 61433bb..6c569c8 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -11,9 +11,6 @@ name: build_all_images NO_CACHE: required: true type: boolean - runtime_docker_image: - type: string - required: true env: BRANCH_NAME: '${{ github.event.pull_request.head.ref }}' jobs: @@ -44,7 +41,6 @@ jobs: container_name: base base_folder: "." NO_CACHE: ${{ inputs.NO_CACHE }} - runtime_docker_image: ${{ inputs.runtime_docker_image }} package_base_node_images: needs: - package_base_docker_image @@ -60,7 +56,6 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "base_node" NO_CACHE: ${{ inputs.NO_CACHE }} - runtime_docker_image: ${{ inputs.runtime_docker_image }} package_node_24_language_docker_images: needs: - package_base_docker_image @@ -78,7 +73,6 @@ jobs: base_folder: "languages" NO_CACHE: ${{ inputs.NO_CACHE }} EXTRA_COMMON: "common_node_24" - runtime_docker_image: ${{ inputs.runtime_docker_image }} package_project_docker_images: needs: - package_node_24_language_docker_images @@ -94,4 +88,3 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "projects" NO_CACHE: ${{ inputs.NO_CACHE }} - runtime_docker_image: ${{ inputs.runtime_docker_image }} diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index 86f9714..7e5a753 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -20,9 +20,6 @@ name: Build and push docker image EXTRA_COMMON: required: false type: string - runtime_docker_image: - type: string - required: true jobs: build_and_push_image: @@ -33,12 +30,6 @@ jobs: attestations: write id-token: write runs-on: '${{ matrix.runner }}' - container: - image: ghcr.io/nhsdigital/eps-devcontainers/${{ inputs.runtime_docker_image }} - options: --user 1001:1001 --group-add 128 - defaults: - run: - shell: bash strategy: fail-fast: false @@ -49,9 +40,6 @@ jobs: - arch: arm64 runner: ubuntu-22.04-arm steps: - - name: copy .tool-versions - run: | - cp /home/vscode/.tool-versions "$HOME/.tool-versions" - name: Free Disk Space for Docker uses: endersonmenezes/free-disk-space@e6ed9b02e683a3b55ed0252f1ee469ce3b39a885 with: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ada558..4941baf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,21 +4,6 @@ on: branches: [main] jobs: - get_config_values: - runs-on: ubuntu-22.04 - outputs: - devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }} - devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_VERSION }} - steps: - - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Load config value - id: load-config - run: | - DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json) - DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json) - echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT" - echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_IMAGE_VERSION" >> "$GITHUB_OUTPUT" get_asdf_version: runs-on: ubuntu-22.04 outputs: @@ -57,10 +42,8 @@ jobs: build_all_images: needs: - tag_release - - get_config_values uses: ./.github/workflows/build_all_images.yml with: docker_tag: 'ci-${{ needs.tag_release.outputs.version_tag }}' tag_latest: false NO_CACHE: false - runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image_name }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_image_version }}" diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 692af0b..275ec1c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -109,4 +109,3 @@ jobs: docker_tag: 'pr-${{ needs.get_issue_number.outputs.issue_number }}-${{ needs.get_commit_id.outputs.sha_short }}' tag_latest: false NO_CACHE: false - runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image_name }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_image_version }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index acf2ed9..83022ff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,21 +5,6 @@ on: - cron: "0 18 * * 4" jobs: - get_config_values: - runs-on: ubuntu-22.04 - outputs: - devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }} - devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_VERSION }} - steps: - - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Load config value - id: load-config - run: | - DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json) - DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json) - echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT" - echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_IMAGE_VERSION" >> "$GITHUB_OUTPUT" get_asdf_version: runs-on: ubuntu-22.04 outputs: @@ -58,10 +43,8 @@ jobs: build_all_images: needs: - tag_release - - get_config_values uses: ./.github/workflows/build_all_images.yml with: docker_tag: '${{ needs.tag_release.outputs.version_tag }}' tag_latest: true NO_CACHE: true - runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image_name }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_image_version }}" From dc0fb122c8ddb8b275329323090a1367fa972cbd Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:43:49 +0000 Subject: [PATCH 08/19] really revert --- .github/workflows/pull_request.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 275ec1c..7edbec3 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -6,21 +6,6 @@ name: pull_request env: BRANCH_NAME: '${{ github.event.pull_request.head.ref }}' jobs: - get_config_values: - runs-on: ubuntu-22.04 - outputs: - devcontainer_image_name: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_NAME }} - devcontainer_image_version: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE_VERSION }} - steps: - - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Load config value - id: load-config - run: | - DEVCONTAINER_IMAGE_NAME=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json) - DEVCONTAINER_IMAGE_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json) - echo "DEVCONTAINER_IMAGE_NAME=$DEVCONTAINER_IMAGE_NAME" >> "$GITHUB_OUTPUT" - echo "DEVCONTAINER_IMAGE_VERSION=$DEVCONTAINER_IMAGE_VERSION" >> "$GITHUB_OUTPUT" dependabot-auto-approve-and-merge: needs: quality_checks uses: >- @@ -103,7 +88,6 @@ jobs: needs: - get_issue_number - get_commit_id - - get_config_values uses: ./.github/workflows/build_all_images.yml with: docker_tag: 'pr-${{ needs.get_issue_number.outputs.issue_number }}-${{ needs.get_commit_id.outputs.sha_short }}' From 6e644e6301bc59ee34db4516d98e754e610a9c9b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:48:05 +0000 Subject: [PATCH 09/19] install trivy --- .github/workflows/build_multi_arch_image.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index 7e5a753..cddd4be 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -53,6 +53,10 @@ jobs: google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-* remove_packages_one_command: true + - name: Install Trivy + uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 + with: + version: v0.69.1 - name: Login to github container registry uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 with: From b883f0d78c8cf7daa410dfd7d3919894eef89a5b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 14:56:27 +0000 Subject: [PATCH 10/19] setup node again --- .github/workflows/build_multi_arch_image.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index cddd4be..d0a12c5 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -53,10 +53,14 @@ jobs: google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-* remove_packages_one_command: true - - name: Install Trivy + - name: setup trivy uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 with: version: v0.69.1 + - name: setup node + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 + with: + node-version-file: .tool-versions - name: Login to github container registry uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 with: From 1d2cb1f9eba118facaa1d3325d0f6f084e3cabae Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 15:04:10 +0000 Subject: [PATCH 11/19] move things --- .github/workflows/build_multi_arch_image.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index d0a12c5..ab525d2 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -53,14 +53,6 @@ jobs: google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-* remove_packages_one_command: true - - name: setup trivy - uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 - with: - version: v0.69.1 - - name: setup node - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 - with: - node-version-file: .tool-versions - name: Login to github container registry uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 with: @@ -71,6 +63,14 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 + - name: setup trivy + uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 + with: + version: v0.69.1 + - name: setup node + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 + with: + node-version-file: .tool-versions - name: make install run: | From 03adb53d46dca83d3407b39fa264d591f2959eea Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 15:24:31 +0000 Subject: [PATCH 12/19] fix path --- src/base_node/node_24/trivy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base_node/node_24/trivy.yaml b/src/base_node/node_24/trivy.yaml index 48cfe23..20e8f24 100644 --- a/src/base_node/node_24/trivy.yaml +++ b/src/base_node/node_24/trivy.yaml @@ -1 +1 @@ -ignorefile: "src/languages/node_24_python_3_12/.trivyignore_combined.yaml" +ignorefile: "src/base_node/node_24/.trivyignore_combined.yaml" From 747a1a47a6e183a6b3727dfcc8f291de85ed5089 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 15:26:00 +0000 Subject: [PATCH 13/19] update makefile --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index a6f537e..c829f69 100644 --- a/Makefile +++ b/Makefile @@ -97,3 +97,8 @@ github-login: lint-githubaction-scripts: shellcheck .github/scripts/*.sh + +clean: + rm -rf .out + find . -type f -name '.trivyignore_combined.yaml' -delete + From 9fef6c912eaddc91bcc94c09bf42bced7df326fa Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 15:41:47 +0000 Subject: [PATCH 14/19] fix scan --- .github/workflows/build_multi_arch_image.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index ab525d2..36e3c0f 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -102,9 +102,9 @@ jobs: with: name: "scan_results_docker_${{ inputs.container_name }}_${{ matrix.arch }}.json" path: .out/scan_results_docker.json - - name: Check docker vulnerabilities - json output + - name: Check docker vulnerabilities - table output run: | - make scan-image-json + make scan-image env: CONTAINER_NAME: '${{ inputs.container_name }}' BASE_FOLDER: "${{ inputs.base_folder }}" From 7a10e0820ff5cbd6262b778e8fd9257d460b0fed Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 15:58:01 +0000 Subject: [PATCH 15/19] fix it --- .github/workflows/build_all_images.yml | 1 + README.md | 3 ++- src/base_node/node_24/.trivyignore.yaml | 27 ------------------------- src/common_node_24/.trivyignore.yaml | 5 +++++ 4 files changed, 8 insertions(+), 28 deletions(-) delete mode 100644 src/base_node/node_24/.trivyignore.yaml diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index 6c569c8..f6cc14c 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -56,6 +56,7 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "base_node" NO_CACHE: ${{ inputs.NO_CACHE }} + EXTRA_COMMON: "common_node_24" package_node_24_language_docker_images: needs: - package_base_docker_image diff --git a/README.md b/README.md index 077ae9e..e20c8e3 100644 --- a/README.md +++ b/README.md @@ -229,8 +229,9 @@ CONTAINER_NAME=base \ Base node 24 image ``` CONTAINER_NAME=node_24 \ - BASE_FOLDER=languages \ + BASE_FOLDER=base_node \ IMAGE_TAG=local-build \ + EXTRA_COMMON=common_node_24 \ make scan-image ``` Language images diff --git a/src/base_node/node_24/.trivyignore.yaml b/src/base_node/node_24/.trivyignore.yaml deleted file mode 100644 index a8010cf..0000000 --- a/src/base_node/node_24/.trivyignore.yaml +++ /dev/null @@ -1,27 +0,0 @@ -vulnerabilities: - - id: CVE-2026-25547 - statement: "brace-expansion: brace-expansion: Denial of Service via unbounded brace range expansion" - purls: - - "pkg:npm/%40isaacs/brace-expansion@5.0.0" - expired_at: 2026-08-12 - - id: CVE-2025-64756 - statement: "glob: glob: Command Injection Vulnerability via Malicious Filenames" - purls: - - "pkg:npm/glob@10.4.5" - - "pkg:npm/glob@11.0.3" - expired_at: 2026-08-12 - - id: CVE-2026-23745 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite and symlink poisoning via unsanitized linkpaths in archives" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 - - id: CVE-2026-23950 - statement: "node-tar: tar: node-tar: Arbitrary file overwrite via Unicode path collision race condition" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 - - id: CVE-2026-24842 - statement: "node-tar: tar: node-tar: Arbitrary file creation via path traversal bypass in hardlink security check" - purls: - - "pkg:npm/tar@7.5.1" - expired_at: 2026-08-12 diff --git a/src/common_node_24/.trivyignore.yaml b/src/common_node_24/.trivyignore.yaml index 72db141..46d9b0c 100644 --- a/src/common_node_24/.trivyignore.yaml +++ b/src/common_node_24/.trivyignore.yaml @@ -30,3 +30,8 @@ vulnerabilities: purls: - "pkg:npm/tar@7.5.1" expired_at: 2026-08-18 + - id: CVE-2026-26960 + statement: "Arbitrary File Read/Write via Hardlink Target Escape Through Symlink Chain in node-tar Extraction" + purls: + - "pkg:npm/tar@7.5.1" + expired_at: 2026-08-18 From d59f45fcaf10ff963c03cc82296eed4f67977d82 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 16:23:25 +0000 Subject: [PATCH 16/19] fix path --- src/languages/node_24_python_3_10/trivy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/node_24_python_3_10/trivy.yaml b/src/languages/node_24_python_3_10/trivy.yaml index fe0d67f..549851b 100644 --- a/src/languages/node_24_python_3_10/trivy.yaml +++ b/src/languages/node_24_python_3_10/trivy.yaml @@ -1 +1 @@ -ignorefile: "src/languages/python_3_10/.trivyignore_combined.yaml" +ignorefile: "src/languages/node_24_python_3_10/.trivyignore_combined.yaml" From 755bded6a48600a4880278c7eb9f1ed9f0cb2960 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 16:53:39 +0000 Subject: [PATCH 17/19] add extra to fhir image --- .github/workflows/build_all_images.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_all_images.yml b/.github/workflows/build_all_images.yml index f6cc14c..111abf8 100644 --- a/.github/workflows/build_all_images.yml +++ b/.github/workflows/build_all_images.yml @@ -89,3 +89,4 @@ jobs: container_name: ${{ matrix.container_name }} base_folder: "projects" NO_CACHE: ${{ inputs.NO_CACHE }} + EXTRA_COMMON: "common_node_24" From a26060494fa7476dc0a35cf930060757371597df Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 18:08:34 +0000 Subject: [PATCH 18/19] fix for cfn-lint --- src/base/.devcontainer/Mk/check.mk | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/base/.devcontainer/Mk/check.mk b/src/base/.devcontainer/Mk/check.mk index 031b732..4beddbf 100644 --- a/src/base/.devcontainer/Mk/check.mk +++ b/src/base/.devcontainer/Mk/check.mk @@ -16,8 +16,12 @@ shellcheck: fi cfn-lint: - cfn-lint -I "cloudformation/**/*.y*ml" 2>&1 | awk '/Run scan/ { print } /^[EW][0-9]/ { print; getline; print }' - cfn-lint -I "SAMtemplates/**/*.y*ml" 2>&1 | awk '/Run scan/ { print } /^[EW][0-9]/ { print; getline; print }' + @if find cloudformation -type f \( -name "*.yaml" -o -name "*.yml" \) 2>/dev/null | grep -q .; then \ + cfn-lint -I "cloudformation/**/*.y*ml" 2>&1 | awk '/Run scan/ { print } /^[EW][0-9]/ { print; getline; print; found=1 } END { exit found }'; \ + fi + @if find SAMtemplates -type f \( -name "*.yaml" -o -name "*.yml" \) 2>/dev/null | grep -q .; then \ + cfn-lint -I "SAMtemplates/**/*.y*ml" 2>&1 | awk '/Run scan/ { print } /^[EW][0-9]/ { print; getline; print; found=1 } END { exit found }'; \ + fi cdk-synth: echo "Not implemented" From 6aa14e20b1baa1e968f9bf471bc74ae064976f05 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 18 Feb 2026 18:43:24 +0000 Subject: [PATCH 19/19] install parallel --- src/base/.devcontainer/scripts/root_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index 2352747..386f398 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -27,7 +27,7 @@ apt-get -y install --no-install-recommends htop vim curl git build-essential \ libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev libbz2-dev \ zlib1g-dev unixodbc unixodbc-dev libsecret-1-0 libsecret-1-dev libsqlite3-dev \ jq apt-transport-https ca-certificates gnupg-agent \ - software-properties-common bash-completion make \ + software-properties-common bash-completion make parallel \ libreadline-dev wget llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev liblzma-dev netcat-traditional libyaml-dev uuid-runtime xxd unzip