From a1b9b25508f80b4007dbe0dc7d080eb970518236 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 16:29:02 +0000 Subject: [PATCH 01/11] finish as root --- src/base/.devcontainer/Dockerfile | 4 +++- src/common/Dockerfile | 3 +++ src/projects/fhir_facade_api/.devcontainer/Dockerfile | 7 +++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index 846d4c7..151a4ae 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -26,4 +26,6 @@ COPY --chown=vscode:vscode .tool-versions.asdf /home/vscode/.tool-versions.asdf COPY --chown=vscode:vscode .tool-versions /home/vscode/.tool-versions RUN ./vscode_install.sh -WORKDIR /home/vscode + +# need to finish as root +USER root diff --git a/src/common/Dockerfile b/src/common/Dockerfile index 7b2cc33..67a939f 100644 --- a/src/common/Dockerfile +++ b/src/common/Dockerfile @@ -22,3 +22,6 @@ RUN cat /tmp/.tool-versions >> /home/vscode/.tool-versions RUN ./vscode_install.sh WORKDIR /home/vscode + +# need to finish as root +USER root diff --git a/src/projects/fhir_facade_api/.devcontainer/Dockerfile b/src/projects/fhir_facade_api/.devcontainer/Dockerfile index 6050632..eec5f51 100644 --- a/src/projects/fhir_facade_api/.devcontainer/Dockerfile +++ b/src/projects/fhir_facade_api/.devcontainer/Dockerfile @@ -11,9 +11,6 @@ COPY --chmod=755 scripts ${SCRIPTS_DIR}/${CONTAINER_NAME} WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} RUN ./root_install.sh - -USER vscode - USER vscode WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} @@ -21,4 +18,6 @@ COPY .tool-versions /tmp/.tool-versions RUN cat /tmp/.tool-versions >> /home/vscode/.tool-versions RUN ./vscode_install.sh -WORKDIR /home/vscode + +# need to finish as root +USER root From cafb3acca1151620bac6ea69468575865fa3c3f5 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 16:53:43 +0000 Subject: [PATCH 02/11] install yq --- .devcontainer/Dockerfile | 3 ++- .tool-versions | 1 + src/base/.devcontainer/.tool-versions | 1 + src/base/.devcontainer/scripts/vscode_install.sh | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a33b787..0e7ee62 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -82,7 +82,8 @@ RUN asdf plugin add python; \ 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 trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git; \ + asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git WORKDIR /workspaces/eps-devcontainers diff --git a/.tool-versions b/.tool-versions index e2bc3a2..e4a19f0 100644 --- a/.tool-versions +++ b/.tool-versions @@ -6,3 +6,4 @@ direnv 2.37.1 actionlint 1.7.10 ruby 3.3.0 trivy 0.69.1 +yq 4.52.2 diff --git a/src/base/.devcontainer/.tool-versions b/src/base/.devcontainer/.tool-versions index 9d748cb..f492e92 100644 --- a/src/base/.devcontainer/.tool-versions +++ b/src/base/.devcontainer/.tool-versions @@ -3,3 +3,4 @@ direnv 2.37.1 actionlint 1.7.10 ruby 3.3.0 trivy 0.69.1 +yq 4.52.2 diff --git a/src/base/.devcontainer/scripts/vscode_install.sh b/src/base/.devcontainer/scripts/vscode_install.sh index 2759bce..8c118d9 100755 --- a/src/base/.devcontainer/scripts/vscode_install.sh +++ b/src/base/.devcontainer/scripts/vscode_install.sh @@ -19,6 +19,7 @@ asdf plugin add actionlint asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git asdf plugin add terraform https://github.com/asdf-community/asdf-hashicorp.git asdf plugin add trivy https://github.com/zufardhiyaulhaq/asdf-trivy.git +asdf plugin add yq https://github.com/sudermanjr/asdf-yq.git # install base asdf versions of common tools cd /home/vscode From 9a4f04b0d3b6cd869e57cc262528c808869f1b9a Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:27:09 +0000 Subject: [PATCH 03/11] do not finish as root --- src/base/.devcontainer/Dockerfile | 3 --- src/common/Dockerfile | 3 --- src/projects/fhir_facade_api/.devcontainer/Dockerfile | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index 151a4ae..80d49c7 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -26,6 +26,3 @@ COPY --chown=vscode:vscode .tool-versions.asdf /home/vscode/.tool-versions.asdf COPY --chown=vscode:vscode .tool-versions /home/vscode/.tool-versions RUN ./vscode_install.sh - -# need to finish as root -USER root diff --git a/src/common/Dockerfile b/src/common/Dockerfile index 67a939f..7b2cc33 100644 --- a/src/common/Dockerfile +++ b/src/common/Dockerfile @@ -22,6 +22,3 @@ RUN cat /tmp/.tool-versions >> /home/vscode/.tool-versions RUN ./vscode_install.sh WORKDIR /home/vscode - -# need to finish as root -USER root diff --git a/src/projects/fhir_facade_api/.devcontainer/Dockerfile b/src/projects/fhir_facade_api/.devcontainer/Dockerfile index eec5f51..a24639d 100644 --- a/src/projects/fhir_facade_api/.devcontainer/Dockerfile +++ b/src/projects/fhir_facade_api/.devcontainer/Dockerfile @@ -18,6 +18,3 @@ COPY .tool-versions /tmp/.tool-versions RUN cat /tmp/.tool-versions >> /home/vscode/.tool-versions RUN ./vscode_install.sh - -# need to finish as root -USER root From b9cf35c7f29608a7d28c8f6df8680321325b6358 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:36:51 +0000 Subject: [PATCH 04/11] use a different user id --- .github/workflows/build_multi_arch_image.yml | 2 ++ src/base/.devcontainer/Dockerfile | 7 +++++++ src/base/.devcontainer/devcontainer.json | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml index 46ba6fe..d12e767 100644 --- a/.github/workflows/build_multi_arch_image.yml +++ b/.github/workflows/build_multi_arch_image.yml @@ -87,6 +87,8 @@ jobs: BASE_VERSION: ${{ inputs.docker_tag}} IMAGE_TAG: ":${{ inputs.docker_tag }}-${{ matrix.arch }}" BASE_FOLDER: "${{ inputs.base_folder }}" + VSCODE_UID: "1001" + VSCODE_GID: "1001" - name: Check docker vulnerabilities - json output uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 with: diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index 80d49c7..8b8f9ff 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -17,6 +17,13 @@ COPY .tool-versions.asdf ${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf COPY --chmod=755 scripts ${SCRIPTS_DIR}/${CONTAINER_NAME} WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} RUN ./root_install.sh +RUN requested_uid="${VSCODE_UID:-1000}" \ + && requested_gid="${VSCODE_GID:-1000}" \ + && current_uid="$(id -u vscode)" \ + && current_gid="$(id -g vscode)" \ + && if [ "${current_gid}" != "${requested_gid}" ]; then groupmod -g "${requested_gid}" vscode; fi \ + && if [ "${current_uid}" != "${requested_uid}" ]; then usermod -u "${requested_uid}" -g "${requested_gid}" vscode; fi \ + && chown -R vscode:vscode /home/vscode USER vscode diff --git a/src/base/.devcontainer/devcontainer.json b/src/base/.devcontainer/devcontainer.json index 6d879af..27c98ce 100644 --- a/src/base/.devcontainer/devcontainer.json +++ b/src/base/.devcontainer/devcontainer.json @@ -6,7 +6,9 @@ "build": { "dockerfile": "Dockerfile", "args": { - "CONTAINER_NAME": "eps_devcontainer_base" + "CONTAINER_NAME": "eps_devcontainer_base", + "VSCODE_UID": "${localEnv:VSCODE_UID}", + "VSCODE_GID": "${localEnv:VSCODE_GID}" } }, "runArgs": [ From 7efa4c4e4b9e776f021310d8d8b6a2131d7bd87c Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:49:01 +0000 Subject: [PATCH 05/11] fix script --- .github/scripts/delete_unused_images.sh | 6 ++--- .github/workflows/delete_old_images.yml | 33 +++---------------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/.github/scripts/delete_unused_images.sh b/.github/scripts/delete_unused_images.sh index 8b49f0d..5be5169 100755 --- a/.github/scripts/delete_unused_images.sh +++ b/.github/scripts/delete_unused_images.sh @@ -71,9 +71,9 @@ delete_pr_images() { if [[ -n "${version_id}" ]]; then echo "Deleting image with tag ${tag} (version ID: ${version_id}) from container ${container_name}..." gh api \ - -H "Accept: application/vnd.github+json" \ - -X DELETE \ - "/orgs/nhsdigital/packages/container/${package_name}/versions/${version_id}" + -H "Accept: application/vnd.github+json" \ + -X DELETE \ + "/orgs/nhsdigital/packages/container/${package_name}/versions/${version_id}" fi done fi diff --git a/.github/workflows/delete_old_images.yml b/.github/workflows/delete_old_images.yml index c6601b2..7f0cdc3 100644 --- a/.github/workflows/delete_old_images.yml +++ b/.github/workflows/delete_old_images.yml @@ -1,4 +1,4 @@ -name: "Delete old cloudformation stacks" +name: "Delete old images" # Controls when the action will run - in this case triggered manually and on schedule on: @@ -9,34 +9,7 @@ on: branches: [main] jobs: - delete-old-cloudformation-stacks: - runs-on: ubuntu-22.04 - permissions: - id-token: write - contents: read - - steps: - - name: Checkout local code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - with: - ref: ${{ env.BRANCH_NAME }} - fetch-depth: 0 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 - with: - aws-region: eu-west-2 - role-to-assume: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} - role-session-name: psu-delete-old-stacks - - - name: delete stacks - shell: bash - working-directory: .github/scripts - run: ./delete_stacks.sh - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - delete-old-proxygen-deployments: + delete-old-pushed-images: runs-on: ubuntu-22.04 permissions: id-token: write @@ -53,3 +26,5 @@ jobs: shell: bash working-directory: .github/scripts run: ./delete_unused_images.sh + env: + GGH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c27cba77e9f024563736691f0761a58d8b899cf6 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:52:20 +0000 Subject: [PATCH 06/11] update it --- Makefile | 2 +- README.md | 4 ++-- src/common/.trivyignore.yaml | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 629085e..00443cc 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ scan-image-json: guard-CONTAINER_NAME guard-BASE_FOLDER --scanners vuln \ --exit-code 1 \ --format json \ - --output .out/scan.out.json "${CONTAINER_PREFIX}$${CONTAINER_NAME}" + --output .out/scan_results_docker.json "${CONTAINER_PREFIX}$${CONTAINER_NAME}" shell-image: guard-CONTAINER_NAME docker run -it \ diff --git a/README.md b/README.md index b018086..0c51aff 100644 --- a/README.md +++ b/README.md @@ -147,12 +147,12 @@ CONTAINER_NAME=fhir_facade_api \ ## 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 -If generated locally, then the output goes into .out/scan.out.json +If generated locally, then the output goes into .out/scan_results_docker.json Once you have the scan output, use the following to generate a .trivyignore ``` poetry run python \ scripts/trivy_to_trivyignore.py \ - --input .out/scan.out.json \ + --input .out/scan_results_docker.json \ --output src/common/.trivyignore.yaml ``` diff --git a/src/common/.trivyignore.yaml b/src/common/.trivyignore.yaml index 618fed5..bd4d87e 100644 --- a/src/common/.trivyignore.yaml +++ b/src/common/.trivyignore.yaml @@ -302,3 +302,8 @@ vulnerabilities: 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 From 96fdde56e6a138d719d9616761b2f1bcabb613ad Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:53:55 +0000 Subject: [PATCH 07/11] fix delete --- .github/workflows/delete_old_images.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/delete_old_images.yml b/.github/workflows/delete_old_images.yml index 7f0cdc3..550529e 100644 --- a/.github/workflows/delete_old_images.yml +++ b/.github/workflows/delete_old_images.yml @@ -24,7 +24,6 @@ jobs: - name: delete unused images shell: bash - working-directory: .github/scripts - run: ./delete_unused_images.sh + run: .github/scripts/delete_unused_images.sh env: - GGH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 40f2de5ffc98f194c2308ef38c74dae99a2b4e6a Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:56:00 +0000 Subject: [PATCH 08/11] fix permissions --- .github/workflows/delete_old_images.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/delete_old_images.yml b/.github/workflows/delete_old_images.yml index 550529e..98ae466 100644 --- a/.github/workflows/delete_old_images.yml +++ b/.github/workflows/delete_old_images.yml @@ -12,8 +12,10 @@ jobs: delete-old-pushed-images: runs-on: ubuntu-22.04 permissions: - id-token: write contents: read + packages: write + attestations: write + id-token: write steps: - name: Checkout local code From a88ea8c90ef91ff0e86a41d1de49ca80009e894f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 17:57:57 +0000 Subject: [PATCH 09/11] do not exit on error --- .github/scripts/delete_unused_images.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/scripts/delete_unused_images.sh b/.github/scripts/delete_unused_images.sh index 5be5169..9ac66ed 100755 --- a/.github/scripts/delete_unused_images.sh +++ b/.github/scripts/delete_unused_images.sh @@ -1,5 +1,4 @@ #!/usr/bin/env bash -set -e get_container_package_name() { local container_name=$1 From 653830e4a74a28b0f2dfa8ca4ae5c9c75b319eb8 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 18:01:30 +0000 Subject: [PATCH 10/11] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0c51aff..5d5e41a 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ asdf install and setup for these so they are available globally as vscode user - actionlint - ruby (for github pages) - trivy + - yq Install and setup git-secrets From a1259031ac0f52ba0fad59d9f8a2d37f6244afed Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 13 Feb 2026 18:30:28 +0000 Subject: [PATCH 11/11] store version --- src/base/.devcontainer/Dockerfile | 19 ++++++------------- .../.devcontainer/scripts/root_install.sh | 13 +++++++++++++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/base/.devcontainer/Dockerfile b/src/base/.devcontainer/Dockerfile index 8b8f9ff..ee1a55c 100644 --- a/src/base/.devcontainer/Dockerfile +++ b/src/base/.devcontainer/Dockerfile @@ -1,35 +1,28 @@ FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04 +ARG BASE_VERSION=latest ARG TARGETARCH -ENV TARGETARCH=${TARGETARCH} ARG SCRIPTS_DIR=/usr/local/share/eps ARG CONTAINER_NAME +ENV TARGETARCH=${TARGETARCH} ENV CONTAINER_NAME=${CONTAINER_NAME} ENV SCRIPTS_DIR=${SCRIPTS_DIR} +ENV BASE_VERSION=${BASE_VERSION} LABEL org.opencontainers.image.source=https://github.com/NHSDigital/eps-devcontainers LABEL org.opencontainers.image.description="EPS base devcontainer" LABEL org.opencontainers.image.licenses=MIT -ARG ASDF_VERSION COPY .tool-versions.asdf ${SCRIPTS_DIR}/${CONTAINER_NAME}/.tool-versions.asdf - COPY --chmod=755 scripts ${SCRIPTS_DIR}/${CONTAINER_NAME} + WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} RUN ./root_install.sh -RUN requested_uid="${VSCODE_UID:-1000}" \ - && requested_gid="${VSCODE_GID:-1000}" \ - && current_uid="$(id -u vscode)" \ - && current_gid="$(id -g vscode)" \ - && if [ "${current_gid}" != "${requested_gid}" ]; then groupmod -g "${requested_gid}" vscode; fi \ - && if [ "${current_uid}" != "${requested_uid}" ]; then usermod -u "${requested_uid}" -g "${requested_gid}" vscode; fi \ - && chown -R vscode:vscode /home/vscode USER vscode - -ENV PATH="/home/vscode/.asdf/shims/:$PATH" -WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} COPY --chown=vscode:vscode .tool-versions.asdf /home/vscode/.tool-versions.asdf COPY --chown=vscode:vscode .tool-versions /home/vscode/.tool-versions +ENV PATH="/home/vscode/.asdf/shims/:$PATH" +WORKDIR ${SCRIPTS_DIR}/${CONTAINER_NAME} RUN ./vscode_install.sh diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index 5457b9f..d8720d0 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -16,6 +16,7 @@ if [ "$TARGETARCH" == "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main universe" >> /etc/apt/sources.list fi +# update and upgrade packages echo "Running apt-get update" apt-get update apt-get upgrade -y @@ -65,3 +66,15 @@ 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 + +# fix user and group ids for vscode user to match host, and ensure vscode owns their home directory +requested_uid="${VSCODE_UID:-1000}" +requested_gid="${VSCODE_GID:-1000}" +current_uid="$(id -u vscode)" +current_gid="$(id -g vscode)" +if [ "${current_gid}" != "${requested_gid}" ]; then groupmod -g "${requested_gid}" vscode; fi +if [ "${current_uid}" != "${requested_uid}" ]; then usermod -u "${requested_uid}" -g "${requested_gid}" vscode; fi +chown -R vscode:vscode /home/vscode + +# store base version in VERSION.txt for reference +echo "VERSION=${BASE_VERSION}" > "${SCRIPTS_DIR}/VERSION.txt"