diff --git a/.gitallowed b/.gitallowed new file mode 100644 index 0000000..bb5927a --- /dev/null +++ b/.gitallowed @@ -0,0 +1,3 @@ +id-token: write +password: \${{secrets\.GITHUB_TOKEN}} +\.gitallowed diff --git a/.github/config/settings.yml b/.github/config/settings.yml new file mode 100644 index 0000000..05dbcda --- /dev/null +++ b/.github/config/settings.yml @@ -0,0 +1 @@ +TAG_FORMAT: "v${version}" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..4a87436 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,46 @@ +######################################################################### +# Dependabot configuration file +######################################################################### + +version: 2 + +updates: + - package-ecosystem: "github-actions" + # Workflow files stored in the + # default location of `.github/workflows` + directory: "/" + schedule: + interval: "weekly" + day: "friday" + time: "18:00" # UTC + open-pull-requests-limit: 20 + commit-message: + prefix: "Upgrade: [dependabot] - " + + ################################### + # NPM workspace ################## + ################################### + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + day: "friday" + time: "18:00" + open-pull-requests-limit: 20 + versioning-strategy: increase + commit-message: + prefix: "Upgrade: [dependabot] - " + + ################################### + # Poetry ######################### + ################################### + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + day: "friday" + time: "18:00" + open-pull-requests-limit: 20 + versioning-strategy: increase + commit-message: + prefix: "Upgrade: [dependabot] - " diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..203df63 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,59 @@ +## Summary + +**Remove items from this list if they are not relevant. Remove this line once this has been done** + +- Routine Change +- :exclamation: Breaking Change +- :robot: Operational or Infrastructure Change +- :sparkles: New Feature +- :warning: Potential issues that might be caused by this change + +### Details + +Add any summary information of what is in the change. **Remove this line if you have nothing to add.** + +## Pull Request Naming + +Pull requests should be named using the following format: + +```text +Tag: [AEA-NNNN] - Short description +``` + +Tag can be one of: + +- `Fix` - for a bug fix. (Patch release) +- `Update` - either for a backwards-compatible enhancement or for a rule change that adds reported problems. (Patch release) +- `New` - implemented a new feature. (Minor release) +- `Breaking` - for a backwards-incompatible enhancement or feature. (Major release) +- `Docs` - changes to documentation only. (Patch release) +- `Build` - changes to build process only. (No release) +- `Upgrade` - for a dependency upgrade. (Patch release) +- `Chore` - for refactoring, adding tests, etc. (anything that isn't user-facing). (Patch release) + +If the current release is x.y.z then +- a patch release increases z by 1 +- a minor release increases y by 1 +- a major release increases x by 1 + +Correct tagging is necessary for our automated versioning and release process. + +The description of your pull request will be used as the commit message for the merge, and also be included in the changelog. Please ensure that your title is sufficiently descriptive. + +### Rerunning Checks + +If you need to rename your pull request, you can restart the checks by either: + +- Closing and reopening the pull request +- pushing an empty commit + ```bash + git commit --allow-empty -m 'trigger build' + git push + ``` +- Amend your last commit and force push to the branch + ```bash + git commit --amend --no-edit + git push --force + ``` + +Rerunning the checks from within the pull request will not use the updated title. diff --git a/.github/workflows/build_multi_arch_image.yml b/.github/workflows/build_multi_arch_image.yml new file mode 100644 index 0000000..8006211 --- /dev/null +++ b/.github/workflows/build_multi_arch_image.yml @@ -0,0 +1,190 @@ +name: Build and push docker image +'on': + workflow_call: + inputs: + publish_image: + required: true + type: boolean + docker_tag: + required: true + type: string + secrets: + EPS_REPO_STATUS_PEM: + required: true + +jobs: + build_image: + permissions: + id-token: write + runs-on: '${{ matrix.runner }}' + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + runner: ubuntu-22.04 + - arch: arm64 + runner: ubuntu-22.04-arm + steps: + - name: Free Disk Space for Docker + uses: >- + endersonmenezes/free-disk-space@e6ed9b02e683a3b55ed0252f1ee469ce3b39a885 + with: + remove_android: true + remove_dotnet: true + remove_haskell: true + remove_tool_cache: true + rm_cmd: rm + remove_packages: >- + azure-cli google-cloud-cli microsoft-edge-stable + google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* + dotnet-sdk-* + remove_packages_one_command: true + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + with: + fetch-depth: 0 + - name: setup node + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f + with: + node-version-file: .tool-versions + - name: Generate a token to get details from other repositories + id: generate-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf + with: + app-id: ${{ vars.EPS_REPO_STATUS_APP_ID }} + private-key: ${{ secrets.EPS_REPO_STATUS_PEM }} + owner: "NHSDigital" + + - name: make install + run: | + make install-node + - name: Build container + run: > + make build-base-image + + docker tag ghcr.io/nhsdigital/eps-devcontainer-base:latest "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-${ARCHITECTURE}" + + docker save "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-${ARCHITECTURE}" -o "eps-devcontainer-base-${DOCKER_TAG}-${ARCHITECTURE}.img" + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + ARCHITECTURE: '${{ matrix.arch }}' + DOCKER_TAG: '${{ inputs.docker_tag }}' + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + name: Upload docker images + with: + name: "eps-devcontainer-base-${{ inputs.docker_tag }}-${{ matrix.arch }}.img" + path: | + eps-devcontainer-base-${{ inputs.docker_tag }}-${{ matrix.arch }}.img + - name: Check docker vulnerabilities - json output + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 + with: + scan-type: "image" + image-ref: "ghcr.io/nhsdigital/eps-devcontainers:${{ 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: trivy.yaml + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + name: Upload scan results + with: + name: "scan_results_docker_${{ matrix.arch }}.json" + path: | + "scan_results_docker.json" + - name: Check docker vulnerabilities - table output + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 + with: + scan-type: "image" + image-ref: "ghcr.io/nhsdigital/eps-devcontainers:${{ 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: trivy.yaml + + - name: Show docker vulnerability output + if: always() + run: | + echo "Scan output for ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-${ARCHITECTURE}" + if [ -f scan_results_docker.txt ]; then + cat scan_results_docker.txt + fi + env: + ARCHITECTURE: '${{ matrix.arch }}' + DOCKER_TAG: '${{ inputs.docker_tag }}' + + publish_image: + needs: build_image + runs-on: ubuntu-22.04 + if: ${{ inputs.publish_image }} + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - name: Free Disk Space for Docker + uses: >- + endersonmenezes/free-disk-space@e6ed9b02e683a3b55ed0252f1ee469ce3b39a885 + with: + remove_android: true + remove_dotnet: true + remove_haskell: true + remove_tool_cache: true + rm_cmd: rm + remove_packages: >- + azure-cli google-cloud-cli microsoft-edge-stable + google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* + dotnet-sdk-* + remove_packages_one_command: true + - name: Download amd64 images + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: eps-devcontainer-base-${{ inputs.docker_tag }}-amd64.img + - name: Download arm64 images + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: eps-devcontainer-base-${{ inputs.docker_tag }}-arm64.img + - name: Login to github container registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 + with: + registry: ghcr.io + username: ${{github.actor}} + password: ${{secrets.GITHUB_TOKEN}} + + + - name: Load and push multi-arch image + run: | + echo "loading images" + docker load -i "eps-devcontainer-base-${DOCKER_TAG}-amd64.img" + docker load -i "eps-devcontainer-base-${DOCKER_TAG}-arm64.img" + + echo "Tagging latest images" + docker tag "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-amd64" "ghcr.io/nhsdigital/eps-devcontainers:latest-amd64" + docker tag "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-arm64" "ghcr.io/nhsdigital/eps-devcontainers:latest-arm64" + + echo "pushing images" + docker push "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-amd64" + docker push "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-arm64" + docker push ghcr.io/nhsdigital/eps-devcontainers:latest-amd64 + docker push ghcr.io/nhsdigital/eps-devcontainers:latest-arm64 + + echo "creating manifest" + docker manifest create "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}" \ + --amend "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-amd64" \ + --amend "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}-arm64" + docker manifest create "ghcr.io/nhsdigital/eps-devcontainers:latest" \ + --amend "ghcr.io/nhsdigital/eps-devcontainers:latest-amd64" \ + --amend "ghcr.io/nhsdigital/eps-devcontainers:latest-arm64" + + echo "pushing manifest" + docker manifest push "ghcr.io/nhsdigital/eps-devcontainers:${DOCKER_TAG}" + docker manifest push "ghcr.io/nhsdigital/eps-devcontainers:latest" + env: + DOCKER_TAG: ${{ inputs.docker_tag }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..1052066 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,96 @@ +name: pull_request +'on': + pull_request: + branches: + - main +env: + BRANCH_NAME: '${{ github.event.pull_request.head.ref }}' +jobs: + dependabot-auto-approve-and-merge: + needs: quality_checks + uses: >- + NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml@2b3ddfd1e59daf9905522d0140c6cd08e2547432 + secrets: + AUTOMERGE_APP_ID: '${{ secrets.AUTOMERGE_APP_ID }}' + AUTOMERGE_PEM: '${{ secrets.AUTOMERGE_PEM }}' + get_asdf_version: + runs-on: ubuntu-22.04 + outputs: + asdf_version: '${{ steps.asdf-version.outputs.version }}' + tag_format: '${{ steps.load-config.outputs.TAG_FORMAT }}' + steps: + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + - name: Get asdf version + id: asdf-version + run: >- + echo "version=$(awk '!/^#/ && NF {print $1; exit}' + .tool-versions.asdf)" >> "$GITHUB_OUTPUT" + - name: Load config value + id: load-config + run: | + TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml) + echo "TAG_FORMAT=$TAG_FORMAT" >> "$GITHUB_OUTPUT" + quality_checks: + uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@trivy + needs: + - get_asdf_version + with: + asdfVersion: '${{ needs.get_asdf_version.outputs.asdf_version }}' + secrets: + SONAR_TOKEN: '${{ secrets.SONAR_TOKEN }}' + pr_title_format_check: + uses: >- + NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml@2b3ddfd1e59daf9905522d0140c6cd08e2547432 + get_issue_number: + runs-on: ubuntu-22.04 + needs: quality_checks + outputs: + issue_number: '${{ steps.get_issue_number.outputs.result }}' + version: '${{ steps.get_issue_number.outputs.version_number }}' + steps: + - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd + name: get issue number + id: get_issue_number + with: + script: | + if (context.issue.number) { + // Return issue number if present + return context.issue.number; + } else { + // Otherwise return issue number from commit + return ( + await github.rest.repos.listPullRequestsAssociatedWithCommit({ + commit_sha: context.sha, + owner: context.repo.owner, + repo: context.repo.repo, + }) + ).data[0].number; + } + result-encoding: string + get_commit_id: + runs-on: ubuntu-22.04 + outputs: + commit_id: '${{ steps.commit_id.outputs.commit_id }}' + sha_short: '${{ steps.commit_id.outputs.sha_short }}' + steps: + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + with: + ref: '${{ env.BRANCH_NAME }}' + - name: Get Commit ID + id: commit_id + run: | + # echo "commit_id=${{ github.sha }}" >> "$GITHUB_ENV" + echo "commit_id=${{ github.sha }}" >> "$GITHUB_OUTPUT" + echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + package_docker_image: + uses: ./.github/workflows/build_multi_arch_image.yml + needs: + - get_issue_number + - get_commit_id + with: + publish_image: true + docker_tag: 'pr${{ needs.get_issue_number.outputs.issue_number }}-${{ needs.get_commit_id.outputs.sha_short }}' + secrets: + EPS_REPO_STATUS_PEM: ${{ secrets.EPS_REPO_STATUS_PEM }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8da9db2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,49 @@ +name: merge to main workflow +on: + push: + branches: [main] + +jobs: + get_asdf_version: + runs-on: ubuntu-22.04 + outputs: + asdf_version: '${{ steps.asdf-version.outputs.version }}' + tag_format: '${{ steps.load-config.outputs.TAG_FORMAT }}' + steps: + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + - name: Get asdf version + id: asdf-version + run: >- + echo "version=$(awk '!/^#/ && NF {print $1; exit}' + .tool-versions.asdf)" >> "$GITHUB_OUTPUT" + - name: Load config value + id: load-config + run: | + TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml) + echo "TAG_FORMAT=$TAG_FORMAT" >> "$GITHUB_OUTPUT" + quality_checks: + uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e + needs: + - get_asdf_version + with: + asdfVersion: '${{ needs.get_asdf_version.outputs.asdf_version }}' + secrets: + SONAR_TOKEN: '${{ secrets.SONAR_TOKEN }}' + tag_release: + needs: [quality_checks, get_asdf_version] + uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e + with: + dry_run: false + asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} + branch_name: main + tag_format: ${{ needs.get_asdf_version.outputs.tag_format }} + secrets: inherit + package_docker_image: + needs: tag_release + uses: ./.github/workflows/build_multi_arch_image.yml + with: + publish_image: true + docker_tag: '${{ needs.tag_release.outputs.version_tag }}' + secrets: + EPS_REPO_STATUS_PEM: ${{ secrets.EPS_REPO_STATUS_PEM }} diff --git a/.trivyignore.yaml b/.trivyignore.yaml new file mode 100644 index 0000000..ca32650 --- /dev/null +++ b/.trivyignore.yaml @@ -0,0 +1,496 @@ +vulnerabilities: + - id: CVE-2026-25547 + statement: "@isaacs/brace-expansion has Uncontrolled Resource Consumption" + purls: + - "pkg:npm/%40isaacs/brace-expansion@5.0.0" + expired_at: 2026-06-01 + - id: CVE-2021-3807 + statement: "nodejs-ansi-regex Regular expression denial of service (ReDoS) matching ANSI escape codes" + purls: + - "pkg:npm/ansi-regex@3.0.0" + expired_at: 2026-06-01 + - id: CVE-2021-3807 + statement: "nodejs-ansi-regex Regular expression denial of service (ReDoS) matching ANSI escape codes" + purls: + - "pkg:npm/ansi-regex@5.0.0" + expired_at: 2026-06-01 + - id: CVE-2025-64756 + statement: "glob glob Command Injection Vulnerability via Malicious Filenames" + purls: + - "pkg:npm/glob@10.4.5" + expired_at: 2026-06-01 + - id: CVE-2025-64756 + statement: "glob glob Command Injection Vulnerability via Malicious Filenames" + purls: + - "pkg:npm/glob@11.0.3" + expired_at: 2026-06-01 + - id: CVE-2022-25881 + statement: "http-cache-semantics Regular Expression Denial of Service (ReDoS) vulnerability" + purls: + - "pkg:npm/http-cache-semantics@4.1.0" + expired_at: 2026-06-01 + - id: CVE-2024-29415 + statement: "node-ip Incomplete fix for CVE-2023-42282" + purls: + - "pkg:npm/ip@1.1.5" + expired_at: 2026-06-01 + - id: CVE-2022-3517 + statement: "nodejs-minimatch ReDoS via the braceExpand function" + purls: + - "pkg:npm/minimatch@3.0.4" + expired_at: 2026-06-01 + - id: CVE-2026-0775 + statement: "npmcli npm cli Incorrect Permission Assignment Local Privilege Escalation Vulnerability" + purls: + - "pkg:npm/npm@11.6.2" + expired_at: 2026-06-01 + - id: CVE-2022-29244 + statement: "nodejs npm pack ignores root-level .gitignore and .npmignore file exclusion directives when run in a workspace" + purls: + - "pkg:npm/npm@8.5.0" + expired_at: 2026-06-01 + - id: CVE-2026-0775 + statement: "npmcli npm cli Incorrect Permission Assignment Local Privilege Escalation Vulnerability" + purls: + - "pkg:npm/npm@8.5.0" + expired_at: 2026-06-01 + - id: CVE-2022-25883 + statement: "nodejs-semver Regular expression denial of service" + purls: + - "pkg:npm/semver@7.3.5" + expired_at: 2026-06-01 + - 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@6.1.11" + expired_at: 2026-06-01 + - id: CVE-2026-23950 + statement: "node-tar tar node-tar Arbitrary file overwrite via Unicode path collision race condition" + purls: + - "pkg:npm/tar@6.1.11" + expired_at: 2026-06-01 + - 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@6.1.11" + expired_at: 2026-06-01 + - 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-06-01 + - 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-06-01 + - 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-06-01 + - id: CVE-2022-40897 + statement: "pypa-setuptools Regular Expression Denial of Service (ReDoS) in package_index.py" + purls: + - "pkg:pypi/setuptools@56.0.0" + expired_at: 2026-06-01 + - id: CVE-2024-6345 + statement: "pypa/setuptools Remote code execution via download functions in the package_index module in pypa/setuptools" + purls: + - "pkg:pypi/setuptools@56.0.0" + expired_at: 2026-06-01 + - id: CVE-2025-47273 + statement: "setuptools Path Traversal Vulnerability in setuptools PackageIndex" + purls: + - "pkg:pypi/setuptools@56.0.0" + expired_at: 2026-06-01 + - id: CVE-2022-40897 + statement: "pypa-setuptools Regular Expression Denial of Service (ReDoS) in package_index.py" + purls: + - "pkg:pypi/setuptools@65.5.0" + expired_at: 2026-06-01 + - id: CVE-2024-6345 + statement: "pypa/setuptools Remote code execution via download functions in the package_index module in pypa/setuptools" + purls: + - "pkg:pypi/setuptools@65.5.0" + expired_at: 2026-06-01 + - id: CVE-2025-47273 + statement: "setuptools Path Traversal Vulnerability in setuptools PackageIndex" + purls: + - "pkg:pypi/setuptools@65.5.0" + expired_at: 2026-06-01 + - id: CVE-2024-49761 + statement: "rexml REXML ReDoS vulnerability" + purls: + - "pkg:gem/rexml@3.2.6" + expired_at: 2026-06-01 + - id: CVE-2025-61726 + statement: "golang net/url Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.25.5" + expired_at: 2026-06-01 + - id: CVE-2025-61728 + statement: "golang archive/zip Excessive CPU consumption when building archive index in archive/zip" + purls: + - "pkg:golang/stdlib@v1.25.5" + expired_at: 2026-06-01 + - id: CVE-2025-47907 + statement: "database/sql Postgres Scan Race Condition" + purls: + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-06-01 + - id: CVE-2025-58183 + statement: "golang archive/tar Unbounded allocation when parsing GNU sparse map" + purls: + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-06-01 + - id: CVE-2025-61726 + statement: "golang net/url Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-06-01 + - id: CVE-2025-61728 + statement: "golang archive/zip Excessive CPU consumption when building archive index in archive/zip" + purls: + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-06-01 + - id: CVE-2025-61729 + statement: "crypto/x509 golang Denial of Service due to excessive resource consumption via crafted certificate" + purls: + - "pkg:golang/stdlib@v1.24.4" + expired_at: 2026-06-01 + - id: CVE-2025-22874 + statement: "crypto/x509 Usage of ExtKeyUsageAny disables policy validation in crypto/x509" + purls: + - "pkg:golang/stdlib@v1.24.3" + expired_at: 2026-06-01 + - id: CVE-2025-47907 + statement: "database/sql Postgres Scan Race Condition" + purls: + - "pkg:golang/stdlib@v1.24.3" + expired_at: 2026-06-01 + - id: CVE-2025-58183 + statement: "golang archive/tar Unbounded allocation when parsing GNU sparse map" + purls: + - "pkg:golang/stdlib@v1.24.3" + expired_at: 2026-06-01 + - id: CVE-2025-61726 + statement: "golang net/url Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.24.3" + expired_at: 2026-06-01 + - id: CVE-2025-61728 + statement: "golang archive/zip Excessive CPU consumption when building archive index in archive/zip" + purls: + - "pkg:golang/stdlib@v1.24.3" + expired_at: 2026-06-01 + - id: CVE-2025-61729 + statement: "crypto/x509 golang Denial of Service due to excessive resource consumption via crafted certificate" + purls: + - "pkg:golang/stdlib@v1.24.3" + expired_at: 2026-06-01 + - id: CVE-2025-66564 + statement: "github.com/sigstore/timestamp-authority Sigstore Timestamp Authority Denial of Service via excessive OID or Content-Type header parsing" + purls: + - "pkg:golang/github.com/sigstore/timestamp-authority@v1.2.2" + expired_at: 2026-06-01 + - id: CVE-2025-47907 + statement: "database/sql Postgres Scan Race Condition" + purls: + - "pkg:golang/stdlib@v1.23.4" + expired_at: 2026-06-01 + - id: CVE-2025-58183 + statement: "golang archive/tar Unbounded allocation when parsing GNU sparse map" + purls: + - "pkg:golang/stdlib@v1.23.4" + expired_at: 2026-06-01 + - id: CVE-2025-61726 + statement: "golang net/url Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.23.4" + expired_at: 2026-06-01 + - id: CVE-2025-61728 + statement: "golang archive/zip Excessive CPU consumption when building archive index in archive/zip" + purls: + - "pkg:golang/stdlib@v1.23.4" + expired_at: 2026-06-01 + - id: CVE-2025-61729 + statement: "crypto/x509 golang Denial of Service due to excessive resource consumption via crafted certificate" + purls: + - "pkg:golang/stdlib@v1.23.4" + expired_at: 2026-06-01 + - id: CVE-2023-24538 + statement: "golang html/template backticks not treated as string delimiters" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2023-24540 + statement: "golang html/template improper handling of JavaScript whitespace" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - id: CVE-2022-24675 + statement: "golang encoding/pem fix stack overflow in Decode" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-27664 + statement: "golang net/http handle server errors after sending GOAWAY" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-28131 + statement: "golang encoding/xml stack exhaustion in Decoder.Skip" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-28327 + statement: "golang crypto/elliptic panic caused by oversized scalar" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - 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-06-01 + - id: CVE-2022-29804 + statement: "ELSA-2022-17957 ol8addon security update (IMPORTANT)" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30580 + statement: "golang os/exec Code injection in Cmd.Start" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30630 + statement: "golang io/fs stack exhaustion in Glob" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30631 + statement: "golang compress/gzip stack exhaustion in Reader.Read" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30632 + statement: "golang path/filepath stack exhaustion in Glob" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30633 + statement: "golang encoding/xml stack exhaustion in Unmarshal" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30634 + statement: "ELSA-2022-17957 ol8addon security update (IMPORTANT)" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2022-30635 + statement: "golang encoding/gob stack exhaustion in Decoder.Decode" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - id: CVE-2022-41715 + statement: "golang regexp/syntax limit memory used by parsing regexps" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - 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-06-01 + - id: CVE-2022-41722 + statement: "golang path/filepath path-filepath filepath.Clean path traversal" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - id: CVE-2022-41724 + statement: "golang crypto/tls large handshake records may cause panics" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - 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-06-01 + - 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-06-01 + - id: CVE-2023-24537 + statement: "golang go/parser Infinite loop in parsing" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2023-24539 + statement: "golang html/template improper sanitization of CSS values" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2023-29400 + statement: "golang html/template improper handling of empty HTML attributes" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2023-29403 + statement: "golang runtime unexpected behavior of setuid/setgid binaries" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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-06-01 + - 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-06-01 + - 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-06-01 + - 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-06-01 + - 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-06-01 + - id: CVE-2025-47907 + statement: "database/sql Postgres Scan Race Condition" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2025-58183 + statement: "golang archive/tar Unbounded allocation when parsing GNU sparse map" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - id: CVE-2025-61726 + statement: "golang net/url Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.16.15" + expired_at: 2026-06-01 + - 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" + expired_at: 2026-06-01 + - 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" + expired_at: 2026-06-01 + - 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-06-01 + - id: CVE-2025-61726 + statement: "golang net/url Memory exhaustion in query parameter parsing in net/url" + purls: + - "pkg:golang/stdlib@v1.24.9" + expired_at: 2026-06-01 + - id: CVE-2025-61728 + statement: "golang archive/zip Excessive CPU consumption when building archive index in archive/zip" + purls: + - "pkg:golang/stdlib@v1.24.9" + expired_at: 2026-06-01 + - id: CVE-2025-61729 + statement: "crypto/x509 golang Denial of Service due to excessive resource consumption via crafted certificate" + purls: + - "pkg:golang/stdlib@v1.24.9" + expired_at: 2026-06-01 + - id: CVE-2024-35870 + statement: "kernel: smb: client: fix UAF in smb2_reconnect_server()" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-168.178?arch=amd64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - 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-168.178?arch=amd64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - id: CVE-2025-21780 + statement: "kernel: drm/amdgpu: avoid buffer overflow attach in smu_sys_set_pp_table()" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-168.178?arch=amd64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - id: CVE-2025-37899 + statement: "kernel: ksmbd: fix use-after-free in session logoff" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-168.178?arch=amd64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - 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-168.178?arch=amd64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - id: CVE-2024-35870 + statement: "kernel: smb: client: fix UAF in smb2_reconnect_server()" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-168.178?arch=arm64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - 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-168.178?arch=arm64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - id: CVE-2025-21780 + statement: "kernel: drm/amdgpu: avoid buffer overflow attach in smu_sys_set_pp_table() " + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-168.178?arch=arm64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - id: CVE-2025-37899 + statement: "kernel: ksmbd: fix use-after-free in session logoff" + purls: + - "pkg:deb/ubuntu/linux-libc-dev@5.15.0-168.178?arch=arm64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 + - 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-168.178?arch=arm64\u0026distro=ubuntu-22.04" + expired_at: 2026-06-01 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..65cf5ff --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9f62523 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,61 @@ +# Contribution Guidelines + +## Raising an Issue + +If you raise an issue against this repository, please include as much information as possible to reproduce any bugs, +or specific locations in the case of content errors. + +## Contributing code + +To contribute code, please fork the repository and raise a pull request. + +Ideally pull requests should be fairly granular and aim to solve one problem each. It would also be helpful if they +linked to an issue. If the maintainers cannot understand why a pull request was raised, it will be rejected, +so please explain why the changes need to be made (unless it is self-evident). + +### Merge responsibility + +- It is the responsibility of the reviewer to merge branches they have approved. +- It is the responsibility of the author of the merge to ensure their merge is in a mergeable state. +- It is the responsibility of the maintainers to ensure the merge process is unambiguous and automated where possible. + +### Branch naming + +Branch names should be of the format: + +`aea-nnn-short-issue-description` + +Multiple branches are permitted for the same ticket. + +### Commit messages + +We do not enforce any conventions on commit messages to a branch, as we use squash commits when merging to main branch. + +Commits from a pull request get squashed into a single commit on merge, using the pull request title as the commit message. +Please format your pull request title using tags from [ESLint Convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-eslint) as follows: + +```text +Tag: [AEA-NNNN] - Short description +``` + +Tag can be one of: + +- `Fix` - for a bug fix. (Patch release) +- `Update` - either for a backwards-compatible enhancement or for a rule change that adds reported problems. (Patch release) +- `New` - implemented a new feature. (Minor release) +- `Breaking` - for a backwards-incompatible enhancement or feature. (Major release) +- `Docs` - changes to documentation only. (Patch release) +- `Build` - changes to build process only. (No release) +- `Upgrade` - for a dependency upgrade. (Patch release) +- `Chore` - for refactoring, adding tests, etc. (anything that isn't user-facing). (Patch release) + +If the current release is x.y.z then +- a patch release increases z by 1 +- a minor release increases y by 1 +- a major release increases x by 1 + +Correct tagging is necessary for our automated versioning and release process ([Release](./RELEASE.md)). + +### Changelog + +Release changelogs are generated from the titles of pull requests merged into the `main` branch. Please ensure that your pull request title is sufficiently descriptive of the changes made. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ba95e8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Crown Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile index 0fc362a..454c5bf 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,10 @@ install-hooks: install-python install-hooks: build-base-image: generate-language-version-files CONTAINER_NAME=$(CONTAINER_NAME) \ - devcontainer build \ + npx devcontainer build \ --workspace-folder ./src/base/ \ --push false \ + --platform linux/${ARCHITECTURE} \ --image-name "${IMAGE_NAME}" generate-language-version-files: @@ -29,5 +30,14 @@ scan-base-image: trivy image \ --severity HIGH,CRITICAL \ --ignorefile .trivyignore.yaml \ + --scanners vuln \ --exit-code 1 \ --format table ${IMAGE_NAME} + +lint: lint-githubactions + +test: + echo "Not implemented" + +lint-githubactions: + actionlint diff --git a/README.md b/README.md new file mode 100644 index 0000000..692f065 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +EPS DEV CONTAINERS +================== + +# Introduction +This repo contains code to build a vscode devcontainer that is used as a base image for all EPS projects. +Images are build for amd64 and arm64 and a manifest file created that can be pulled for both architectures. +Images are based on mcr.microsoft.com/devcontainers/base:ubuntu-22.04 +Images contain + - latest os packages + - asdf + - aws cli + - aws sam cli + + It installs the following dev container features + - docker outside of docker + - github cli + +As the vscode user the following also happens + +asdf install and setup for these so they are available globally as vscode user + - shellcheck + - direnv + - actionlint + - ruby (for github pages) + - trivy + +Install asdf plugins for all tools we use +Install asdf versions of node, python, java, terraform, golang used by all EPS projects to speed up initial build of local dev container +Install and setup git-secrets + +# Project structure +The dev container is defined in src/base/.devcontainer folder. This folder contains a Dockerfile and a devcontainer.json file which is used to build the container. +As part of the dockerfile, there are scripts in the scripts folder that run as root and vscode user that setup and install various programs. + +The dev container is built using https://github.com/devcontainers/cli + +The script `scripts/generate_language_version_files.sh` gets the version of node, python, java and terraform from all EPS repositories. It uses the list of repos from https://github.com/NHSDigital/eps-repo-status/blob/main/repos.json to find all EPS repos. + +# Build process +Docker images are built for each pull request, and on merges to main + +Docker images are scanned for vulnerabilities using trivy as part of a build step, and the build fails if vulnerabilities are found not in .trivyignore file. + +On merges to main, a new release is created and the images are pushed to github. The images are tagged with `latest` and the version of the release. + +# Local testing +For local testing, you can run +``` +ARCHITECTURE=amd64 make build-base-image +``` +to build a local image, and then +``` +make scan-base-image +``` +to scan for vulnerabilities diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..15baeac --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,35 @@ +# Security + +NHS England takes security and the protection of private data extremely seriously. If you believe you have found a vulnerability or other issue which has compromised or could compromise the security of any of our systems and/or private data managed by our systems, please do not hesitate to contact us using the methods outlined below. + +## Table of Contents + +- [Security](#security) + - [Table of Contents](#table-of-contents) + - [Reporting a vulnerability](#reporting-a-vulnerability) + - [Email](#email) + - [NCSC](#ncsc) + - [General Security Enquiries](#general-security-enquiries) + +## Reporting a vulnerability + +Please note, email is our preferred method of receiving reports. + +### Email + +If you wish to notify us of a vulnerability via email, please include detailed information on the nature of the vulnerability and any steps required to reproduce it. + +You can reach us at: + +- [epssupport@nhs.net](epssupport@nhs.net) +- [cybersecurity@nhs.net](cybersecurity@nhs.net) + +### NCSC + +You can send your report to the National Cyber Security Centre, who will assess your report and pass it on to NHS England if necessary. + +You can report vulnerabilities here: [https://www.ncsc.gov.uk/information/vulnerability-reporting](https://www.ncsc.gov.uk/information/vulnerability-reporting) + +## General Security Enquiries + +If you have general enquiries regarding our cybersecurity, please reach out to us at [cybersecurity@nhs.net](cybersecurity@nhs.net) diff --git a/scripts/generate_language_version_files.sh b/scripts/generate_language_version_files.sh index b10626f..7f4821d 100755 --- a/scripts/generate_language_version_files.sh +++ b/scripts/generate_language_version_files.sh @@ -1,41 +1,37 @@ #!/usr/bin/env bash +set -e -# Define repositories to fetch .tool-versions from -REPOS=( - "NHSDigital/electronic-prescription-service-clinical-prescription-tracker" - "NHSDigital/prescriptionsforpatients" - "NHSDigital/prescriptions-for-patients" - "NHSDigital/electronic-prescription-service-api" - "NHSDigital/electronic-prescription-service-release-notes" - "NHSDigital/electronic-prescription-service-account-resources" - "NHSDigital/eps-prescription-status-update-api" - "NHSDigital/eps-FHIR-validator-lambda" - "NHSDigital/eps-load-test" - "NHSDigital/eps-prescription-tracker-ui" - "NHSDigital/eps-aws-dashboards" - "NHSDigital/eps-cdk-utils" - "NHSDigital/eps-vpc-resources" - "NHSDigital/eps-assist-me" - "NHSDigital/validation-service-fhir-r4" - "NHSDigital/electronic-prescription-service-get-secrets" - "NHSDigital/nhs-fhir-middy-error-handler" - "NHSDigital/nhs-eps-spine-client" - "NHSDigital/electronic-prescription-service-api-regression-tests" - "NHSDigital/eps-action-sbom" - "NHSDigital/eps-action-cfn-lint" - "NHSDigital/eps-common-workflows" - "NHSDigital/eps-storage-terraform" - "NHSDigital/eps-spine-shared" -) +# Get the current directory of the script +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LANGUAGE_VERSIONS_DIR="${SCRIPT_DIR}/../src/base/.devcontainer/language_versions" +# Check if the user is logged in with GitHub CLI +if ! gh auth status > /dev/null 2>&1; then + echo "You are not logged in to GitHub CLI. Initiating login..." + gh auth login +fi + +# Fetch the repos.json file from the eps-repo-status repository using GitHub CLI +REPOS_JSON_PATH="repos/NHSDigital/eps-repo-status/contents/repos.json" +TEMP_REPOS_JSON="/tmp/repos.json" + +# Download the repos.json file +if ! gh api -H 'Accept: application/vnd.github.v3.raw' "$REPOS_JSON_PATH" > "$TEMP_REPOS_JSON"; then + echo "Failed to fetch repos.json using GitHub CLI. Exiting." + exit 1 +fi + +# Parse the repoUrl values from the JSON file +mapfile -t REPOS < <(jq -r '.[].repoUrl' "$TEMP_REPOS_JSON") # Define output files -NODEJS_FILE="/workspaces/eps-devcontainers/src/base/.devcontainer/language_versions/nodejs-versions.txt" -PYTHON_FILE="/workspaces/eps-devcontainers/src/base/.devcontainer/language_versions/python-versions.txt" -JAVA_FILE="/workspaces/eps-devcontainers/src/base/.devcontainer/language_versions/java-versions.txt" -TERRAFORM_FILE="/workspaces/eps-devcontainers/src/base/.devcontainer/language_versions/terraform-versions.txt" -GOLANG_FILE="/workspaces/eps-devcontainers/src/base/.devcontainer/language_versions/golang-versions.txt" -ALL_LANGUAGES_FILE="/workspaces/eps-devcontainers/src/base/.devcontainer/language_versions/language-versions.txt" +mkdir -p "${LANGUAGE_VERSIONS_DIR}" +NODEJS_FILE="${LANGUAGE_VERSIONS_DIR}/nodejs-versions.txt" +PYTHON_FILE="${LANGUAGE_VERSIONS_DIR}/python-versions.txt" +JAVA_FILE="${LANGUAGE_VERSIONS_DIR}/java-versions.txt" +TERRAFORM_FILE="${LANGUAGE_VERSIONS_DIR}/terraform-versions.txt" +GOLANG_FILE="${LANGUAGE_VERSIONS_DIR}/golang-versions.txt" +ALL_LANGUAGES_FILE="${LANGUAGE_VERSIONS_DIR}/language-versions.txt" # Clear existing files true > "$NODEJS_FILE" true > "$PYTHON_FILE" diff --git a/src/base/.devcontainer/devcontainer.json b/src/base/.devcontainer/devcontainer.json index ae0f548..9f369d3 100644 --- a/src/base/.devcontainer/devcontainer.json +++ b/src/base/.devcontainer/devcontainer.json @@ -1,7 +1,7 @@ // 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": "Ubuntu", + "name": "EPS Devcontainer Base", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "build": { "dockerfile": "Dockerfile", diff --git a/src/base/.devcontainer/scripts/root_install.sh b/src/base/.devcontainer/scripts/root_install.sh index fd3a1ae..bdc0bc6 100755 --- a/src/base/.devcontainer/scripts/root_install.sh +++ b/src/base/.devcontainer/scripts/root_install.sh @@ -1,29 +1,27 @@ #!/usr/bin/env bash set -e - -# Install essential packages first -apt-get update -apt-get install -y \ - curl \ - wget \ - git \ - sudo \ - unzip -apt-get clean -rm -rf /var/lib/apt/lists/* +export DEBIAN_FRONTEND=noninteractive # Add amd64 architecture if on arm64 if [ "$TARGETARCH" == "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then + echo "Adding amd64 architecture support" dpkg --add-architecture amd64 + + # Update sources.list to include amd64 repositories + echo "Configuring sources.list for amd64 and arm64" + sed -i.bak '/^deb / s|http://ports.ubuntu.com/ubuntu-ports|[arch=arm64] http://ports.ubuntu.com/ubuntu-ports|' /etc/apt/sources.list + # shellcheck disable=SC2129 + echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main universe" >> /etc/apt/sources.list + echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main universe" >> /etc/apt/sources.list + echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-security main universe" >> /etc/apt/sources.list fi -# uninstall unnecessary packages -apt-get remove -y \ - python3 -# install necessary libraries for asdf and language runtimes +echo "Running apt-get update" apt-get update -export DEBIAN_FRONTEND=noninteractive -apt-get -y dist-upgrade +apt-get upgrade -y + +# install necessary libraries for asdf and language runtimes +echo "Installing necessary packages" 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 \ @@ -34,33 +32,36 @@ apt-get -y install --no-install-recommends htop vim curl git build-essential \ # install aws stuff # Download correct AWS CLI for arch +echo "Installing aws cli" if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then - wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"; \ + wget -O /tmp/awscliv2.zip --no-verbose "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"; \ + wget -O /tmp/awscliv2.zip --no-verbose "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" fi - unzip /tmp/awscliv2.zip -d /tmp/aws-cli + unzip -q /tmp/awscliv2.zip -d /tmp/aws-cli /tmp/aws-cli/aws/install rm /tmp/awscliv2.zip rm -rf /tmp/aws-cli # Download correct SAM CLI for arch +echo "Installing aws-sam cli" if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" = "aarch64" ]; then - wget -O /tmp/aws-sam-cli.zip "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-arm64.zip"; \ + wget -O /tmp/aws-sam-cli.zip --no-verbose "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-arm64.zip" else - wget -O /tmp/aws-sam-cli.zip "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip"; \ + wget -O /tmp/aws-sam-cli.zip --no-verbose "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip" fi - unzip /tmp/aws-sam-cli.zip -d /tmp/aws-sam-cli + unzip -q /tmp/aws-sam-cli.zip -d /tmp/aws-sam-cli /tmp/aws-sam-cli/install rm /tmp/aws-sam-cli.zip rm -rf /tmp/aws-sam-cli # Install ASDF +echo "Installing asdf" 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"; \ + wget -O /tmp/asdf.tar.gz --no-verbose "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-arm64.tar.gz" else - wget -O /tmp/asdf.tar.gz "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-amd64.tar.gz"; \ + wget -O /tmp/asdf.tar.gz --no-verbose "https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-amd64.tar.gz" fi tar -xzf /tmp/asdf.tar.gz -C /tmp mkdir -p /usr/bin diff --git a/src/base/.devcontainer/scripts/vscode_install.sh b/src/base/.devcontainer/scripts/vscode_install.sh index 0349116..838353a 100755 --- a/src/base/.devcontainer/scripts/vscode_install.sh +++ b/src/base/.devcontainer/scripts/vscode_install.sh @@ -42,9 +42,9 @@ while IFS= read -r version; do done < /tmp/python-versions.txt # Read Java versions from file and install -while IFS= read -r version; do - asdf install java "$version" -done < /tmp/java-versions.txt +# while IFS= read -r version; do +# asdf install java "$version" +# done < /tmp/java-versions.txt # Read Terraform versions from file and install while IFS= read -r version; do diff --git a/trivy.yaml b/trivy.yaml new file mode 100644 index 0000000..eb24337 --- /dev/null +++ b/trivy.yaml @@ -0,0 +1 @@ +ignorefile: ".trivyignore.yaml"