From 62ee9543f8ca13aa72f4a1bca5f034e8fbf5de0b Mon Sep 17 00:00:00 2001 From: moghit-eou Date: Sun, 16 Aug 2026 16:07:53 +0100 Subject: [PATCH 1/5] chore: setup pre-commit and initial lint fixes --- .pre-commit-config.yaml | 5 +++++ config/disabledAlgorithms.json | 8 ++++---- src/main/java/hbp/mip/configurations/OpenApiConfig.java | 2 +- src/main/java/hbp/mip/experiment/ExperimentAPI.java | 2 +- src/main/java/hbp/mip/user/UserDTO.java | 2 +- .../java/hbp/mip/utils/ControllerExceptionHandler.java | 2 +- src/main/java/hbp/mip/utils/CustomResourceLoader.java | 2 +- .../hbp/mip/utils/Exceptions/BadRequestException.java | 2 +- .../mip/utils/Exceptions/ExperimentNotFoundException.java | 2 +- .../hbp/mip/utils/Exceptions/InternalServerError.java | 2 +- src/main/java/hbp/mip/utils/Exceptions/NoContent.java | 2 +- .../hbp/mip/utils/Exceptions/UnauthorizedException.java | 2 +- 12 files changed, 19 insertions(+), 14 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e0d92dfdd..60dc5bee0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,3 +13,8 @@ repos: - id: pretty-format-json args: ["--autofix"] exclude: slack.json + +- repo: https://github.com/gitleaks/gitleaks + rev: v8.21.2 + hooks: + - id: gitleaks diff --git a/config/disabledAlgorithms.json b/config/disabledAlgorithms.json index 6fc4a5d46..01cb167b7 100644 --- a/config/disabledAlgorithms.json +++ b/config/disabledAlgorithms.json @@ -1,4 +1,4 @@ -[ - "THREE_C", - "KAPLAN_MEIER" -] \ No newline at end of file +[ + "THREE_C", + "KAPLAN_MEIER" +] diff --git a/src/main/java/hbp/mip/configurations/OpenApiConfig.java b/src/main/java/hbp/mip/configurations/OpenApiConfig.java index 0ee5264d3..9ecc8e290 100644 --- a/src/main/java/hbp/mip/configurations/OpenApiConfig.java +++ b/src/main/java/hbp/mip/configurations/OpenApiConfig.java @@ -15,4 +15,4 @@ public OpenAPI usersMicroserviceOpenAPI() { .info(new Info().title("Platform-backend API") .version("1.0")); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/experiment/ExperimentAPI.java b/src/main/java/hbp/mip/experiment/ExperimentAPI.java index faca46b36..a34561cd8 100644 --- a/src/main/java/hbp/mip/experiment/ExperimentAPI.java +++ b/src/main/java/hbp/mip/experiment/ExperimentAPI.java @@ -132,4 +132,4 @@ public ResponseEntity createTransientExperiment(Authentication au return new ResponseEntity<>(experimentResponse, HttpStatus.OK); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/user/UserDTO.java b/src/main/java/hbp/mip/user/UserDTO.java index 3b68be5cf..48a62b4ac 100644 --- a/src/main/java/hbp/mip/user/UserDTO.java +++ b/src/main/java/hbp/mip/user/UserDTO.java @@ -10,4 +10,4 @@ public UserDTO(UserDAO userDAO){ userDAO.getAgreeNDA() ); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/utils/ControllerExceptionHandler.java b/src/main/java/hbp/mip/utils/ControllerExceptionHandler.java index a86cfb492..1f284f6b8 100644 --- a/src/main/java/hbp/mip/utils/ControllerExceptionHandler.java +++ b/src/main/java/hbp/mip/utils/ControllerExceptionHandler.java @@ -27,7 +27,7 @@ public ResponseEntity handleExperimentNotFoundException(ExperimentNotFou return new ResponseEntity<>(message, HttpStatus.NOT_FOUND); } - + @ExceptionHandler(BadRequestException.class) public ResponseEntity handleBadRequestException(BadRequestException ex, WebRequest request) { ErrorMessage message = new ErrorMessage( diff --git a/src/main/java/hbp/mip/utils/CustomResourceLoader.java b/src/main/java/hbp/mip/utils/CustomResourceLoader.java index 89552146c..4fd0f5dd7 100644 --- a/src/main/java/hbp/mip/utils/CustomResourceLoader.java +++ b/src/main/java/hbp/mip/utils/CustomResourceLoader.java @@ -18,4 +18,4 @@ public void setResourceLoader(@NonNull ResourceLoader resourceLoader) { public Resource getResource(String resourceLocation) { return resourceLoader.getResource(resourceLocation); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/utils/Exceptions/BadRequestException.java b/src/main/java/hbp/mip/utils/Exceptions/BadRequestException.java index a83830665..cd3bfb4d1 100644 --- a/src/main/java/hbp/mip/utils/Exceptions/BadRequestException.java +++ b/src/main/java/hbp/mip/utils/Exceptions/BadRequestException.java @@ -5,4 +5,4 @@ public class BadRequestException extends RuntimeException { public BadRequestException(String msg) { super(msg); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java b/src/main/java/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java index 303735509..cfec9a6ed 100644 --- a/src/main/java/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java +++ b/src/main/java/hbp/mip/utils/Exceptions/ExperimentNotFoundException.java @@ -5,4 +5,4 @@ public class ExperimentNotFoundException extends RuntimeException { public ExperimentNotFoundException(String msg) { super(msg); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/utils/Exceptions/InternalServerError.java b/src/main/java/hbp/mip/utils/Exceptions/InternalServerError.java index 31357164f..2439779b2 100644 --- a/src/main/java/hbp/mip/utils/Exceptions/InternalServerError.java +++ b/src/main/java/hbp/mip/utils/Exceptions/InternalServerError.java @@ -5,4 +5,4 @@ public class InternalServerError extends RuntimeException { public InternalServerError(String msg) { super(msg); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/utils/Exceptions/NoContent.java b/src/main/java/hbp/mip/utils/Exceptions/NoContent.java index 6ac31b899..66e2ba167 100644 --- a/src/main/java/hbp/mip/utils/Exceptions/NoContent.java +++ b/src/main/java/hbp/mip/utils/Exceptions/NoContent.java @@ -5,4 +5,4 @@ public class NoContent extends RuntimeException { public NoContent(String msg) { super(msg); } -} \ No newline at end of file +} diff --git a/src/main/java/hbp/mip/utils/Exceptions/UnauthorizedException.java b/src/main/java/hbp/mip/utils/Exceptions/UnauthorizedException.java index 1cbe3cf20..bb07f6f57 100644 --- a/src/main/java/hbp/mip/utils/Exceptions/UnauthorizedException.java +++ b/src/main/java/hbp/mip/utils/Exceptions/UnauthorizedException.java @@ -5,4 +5,4 @@ public class UnauthorizedException extends RuntimeException { public UnauthorizedException(String msg) { super(msg); } -} \ No newline at end of file +} From 570d0389ec708aa2ca8598d84dca6e9c155a4142 Mon Sep 17 00:00:00 2001 From: moghit-eou Date: Sun, 16 Aug 2026 16:18:05 +0100 Subject: [PATCH 2/5] pre-commit-config negative testing --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60dc5bee0..3e4d5f7c9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,6 +10,7 @@ repos: - id: check-added-large-files - id: check-yaml - id: check-json + - id: check-xml - id: pretty-format-json args: ["--autofix"] exclude: slack.json From eb2b2e8cf1ac701004bb5ee2d1988c4d8a5eb719 Mon Sep 17 00:00:00 2001 From: moghit-eou Date: Sun, 16 Aug 2026 17:20:43 +0100 Subject: [PATCH 3/5] pin pre-commit hook revisions to commit SHAs --- .pre-commit-config.yaml | 8 ++++++-- src/main/java/hbp/mip/utils/CustomResourceLoader.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e4d5f7c9..7d7ffe017 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 + rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c #v6.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -14,8 +14,12 @@ repos: - id: pretty-format-json args: ["--autofix"] exclude: slack.json + - id: check-xml + - id: detect-private-key + - id: check-case-conflict + - id: mixed-line-ending - repo: https://github.com/gitleaks/gitleaks - rev: v8.21.2 + rev: afc89f91c0795f9763920d40848d770e44341b06 #v8.21.2 hooks: - id: gitleaks diff --git a/src/main/java/hbp/mip/utils/CustomResourceLoader.java b/src/main/java/hbp/mip/utils/CustomResourceLoader.java index 4fd0f5dd7..6f6e536bc 100644 --- a/src/main/java/hbp/mip/utils/CustomResourceLoader.java +++ b/src/main/java/hbp/mip/utils/CustomResourceLoader.java @@ -18,4 +18,4 @@ public void setResourceLoader(@NonNull ResourceLoader resourceLoader) { public Resource getResource(String resourceLocation) { return resourceLoader.getResource(resourceLocation); } -} +} From 1a428d9d8ce98053134f7332b31431a90368a378 Mon Sep 17 00:00:00 2001 From: moghit-eou Date: Sun, 16 Aug 2026 17:28:48 +0100 Subject: [PATCH 4/5] fix(docker): pin base images to digests and use JSON notation for HEALTHCHECK --- .github/workflows/sast.yml | 2 +- .github/workflows/secrets-scan.yml | 40 ++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 5 ++-- Dockerfile | 24 +++--------------- ci/sast_scan.py | 2 +- ci/setup-tools.sh | 17 +++++++++++++ ci/suppress_gitleaks.toml | 4 +++ pom.xml | 4 +-- 8 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/secrets-scan.yml create mode 100644 ci/suppress_gitleaks.toml diff --git a/.github/workflows/sast.yml b/.github/workflows/sast.yml index 786dbc816..6bedefeb3 100644 --- a/.github/workflows/sast.yml +++ b/.github/workflows/sast.yml @@ -16,7 +16,7 @@ jobs: env: SEMGREP_CONFIG_RULESETS: >- semgrep-rules/generic semgrep-rules/problem-based-packs semgrep-rules/bash semgrep-rules/java auto - semgrep-rules/yaml semgrep-rules/package_managers p/default + semgrep-rules/yaml semgrep-rules/package_managers p/default p/gitleaks OPENGREP_EXCLUDE: >- *.sarif ci/ Dockerfile* .pre-commit-config.yaml docs/** README.md AGENTS.md OPENGREP_SARIF_OUTPUT: sast-semgrep-app.sarif diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml new file mode 100644 index 000000000..cd8bb5848 --- /dev/null +++ b/.github/workflows/secrets-scan.yml @@ -0,0 +1,40 @@ +name: Secret Scanning (gitleaks) + +on: + pull_request: + push: + branches: + - master + workflow_dispatch: + +permissions: + contents: read + security-events: write + +jobs: + gitleaks: + runs-on: ubuntu-latest + env: + GITLEAKS_SARIF_OUTPUT: gitleaks.sarif + + steps: + - name: Check out repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Install gitleaks + run: bash ci/setup-tools.sh --install-tool gitleaks + + - name: Install and run gitleaks + run: > + gitleaks dir . + --config ci/suppress_gitleaks.toml + --redact + --report-format sarif + --report-path "$GITLEAKS_SARIF_OUTPUT" + + - name: Upload SARIF to code scanning + if: always() + uses: github/codeql-action/upload-sarif@c35d1b164463ee62a100735382aaaa525c5d3496 #v2.25.6 + with: + sarif_file: ${{ env.GITLEAKS_SARIF_OUTPUT }} + category: gitleaks diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d7ffe017..3fd08481c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c #v6.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -10,7 +10,6 @@ repos: - id: check-added-large-files - id: check-yaml - id: check-json - - id: check-xml - id: pretty-format-json args: ["--autofix"] exclude: slack.json @@ -20,6 +19,6 @@ repos: - id: mixed-line-ending - repo: https://github.com/gitleaks/gitleaks - rev: afc89f91c0795f9763920d40848d770e44341b06 #v8.21.2 + rev: v8.30.0 hooks: - id: gitleaks diff --git a/Dockerfile b/Dockerfile index b08839aff..2cd21516f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ ####################################################### # Build the spring boot maven project ####################################################### -FROM maven:3.9.11-amazoncorretto-21 AS mvn-build-env +FROM maven:3.9.11-amazoncorretto-21@sha256:82d98fbed447e3f7dfbf1089840a51bfaeb5651cb47a9c5820139d054db3dde1 AS mvn-build-env LABEL maintainer="Thanasis Karampatsis " ENV CODE_PATH="/opt/code" @@ -9,7 +9,6 @@ WORKDIR $CODE_PATH COPY pom.xml $CODE_PATH/ -# Pre-fetch dependencies first to improve build cache efficiency. RUN mvn -B -ntp dependency:go-offline COPY src/ $CODE_PATH/src @@ -19,17 +18,11 @@ RUN mvn -B -ntp clean package ####################################################### # Setup the running container ####################################################### -FROM amazoncorretto:21-alpine3.21 +FROM amazoncorretto:21-alpine3.21@sha256:392b286e53c7f4cd366bd2f752f509b7e24de9f414564bccd7d152a58214a8b6 -####################################################### -# Setting up timezone -####################################################### ENV TZ=Etc/GMT RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -####################################################### -# Setting up environment -####################################################### ENV APP_CONFIG_TEMPLATE="/opt/config/application.tmpl" ENV APP_CONFIG_LOCATION="/opt/config/application.yml" ENV SPRING_CONFIG_LOCATION="file:/opt/config/application.yml" @@ -43,25 +36,14 @@ WORKDIR /opt RUN apk add --no-cache curl -####################################################### -# Install dockerize -####################################################### ENV DOCKERIZE_VERSION=v0.14.0 RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz - -####################################################### -# Prepare the spring boot application files -####################################################### COPY config/application.tmpl $APP_CONFIG_TEMPLATE COPY --from=mvn-build-env /opt/code/target/platform-backend.jar /usr/share/jars/ - -####################################################### -# Configuration for the backend config files -####################################################### ENV DISABLED_ALGORITHMS_CONFIG_PATH="/opt/platform/algorithms/disabledAlgorithms.json" COPY config/disabledAlgorithms.json $DISABLED_ALGORITHMS_CONFIG_PATH VOLUME /opt/platform/api @@ -73,4 +55,4 @@ RUN addgroup -S appgroup && adduser -S appuser -G appgroup \ USER appuser ENTRYPOINT ["sh", "-ec", "exec dockerize -template ${APP_CONFIG_TEMPLATE}:${APP_CONFIG_LOCATION} java --add-opens java.base/java.io=ALL-UNNAMED -Daeron.term.buffer.length -jar /usr/share/jars/platform-backend.jar"] EXPOSE 8080 -HEALTHCHECK --start-period=60s CMD curl --fail --silent --show-error http://localhost:8080/services/actuator/health | grep -q '"status":"UP"' +HEALTHCHECK --start-period=60s CMD ["sh", "-c", "curl --fail --silent --show-error http://localhost:8080/services/actuator/health | grep -q '\"status\":\"UP\"'"] diff --git a/ci/sast_scan.py b/ci/sast_scan.py index 5c40496d9..f127ae0db 100644 --- a/ci/sast_scan.py +++ b/ci/sast_scan.py @@ -19,7 +19,7 @@ SEMGREP_CONFIG_RULESETS = os.getenv( "SEMGREP_CONFIG_RULESETS", " semgrep-rules/generic semgrep-rules/problem-based-packs semgrep-rules/bash " - " semgrep-rules/java auto semgrep-rules/yaml semgrep-rules/package_managers p/default " + " semgrep-rules/java auto semgrep-rules/yaml semgrep-rules/package_managers p/default p/gitleaks " ).split() OPENGREP_EXCLUDE = os.getenv( "OPENGREP_EXCLUDE", diff --git a/ci/setup-tools.sh b/ci/setup-tools.sh index c24ca8de7..510453ee5 100644 --- a/ci/setup-tools.sh +++ b/ci/setup-tools.sh @@ -30,6 +30,10 @@ SEMGREP_RULES_DIR="semgrep-rules" HADOLINT_VERSION="${HADOLINT_VERSION:-v2.14.0}" HADOLINT_SHA256="${HADOLINT_SHA256:-6bf226944684f56c84dd014e8b979d27425c0148f61b3bd99bcc6f39e9dc5a47}" +# renovate: datasource=github-release-attachments depName=gitleaks/gitleaks +GITLEAKS_VERSION="${GITLEAKS_VERSION:-v8.30.1}" +GITLEAKS_SHA256="${GITLEAKS_SHA256:-551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb}" + # renovate: datasource=npm depName=@cyclonedx/cyclonedx-npm CYCLONEDX_NPM_VERSION="${CYCLONEDX_NPM_VERSION:-6.0.0}" @@ -128,6 +132,19 @@ if should_install "hadolint"; then echo "Hadolint installed OK" fi +# --- Gitleaks ----------------------------------------------------------- +if should_install "gitleaks"; then + echo "[setup-tools] Installing Gitleaks ${GITLEAKS_VERSION}" + GITLEAKS_TARBALL="gitleaks_${GITLEAKS_VERSION#v}_linux_x64.tar.gz" + download_and_verify \ + "https://github.com/gitleaks/gitleaks/releases/download/${GITLEAKS_VERSION}/${GITLEAKS_TARBALL}" \ + "${TMP_DIR}/${GITLEAKS_TARBALL}" \ + "${GITLEAKS_SHA256}" + sudo tar -xzf "${TMP_DIR}/${GITLEAKS_TARBALL}" -C /usr/local/bin gitleaks + gitleaks version + echo "Gitleaks installed OK" +fi + # --- SBOM generation ---------------------------------------------------- case "$SBOM_ECOSYSTEM" in maven) diff --git a/ci/suppress_gitleaks.toml b/ci/suppress_gitleaks.toml new file mode 100644 index 000000000..5673600f3 --- /dev/null +++ b/ci/suppress_gitleaks.toml @@ -0,0 +1,4 @@ +[allowlist] +paths = [ + '''AGENTS\.md''', +] diff --git a/pom.xml b/pom.xml index 69cfbf0a8..38c9bf80c 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ org.springframework.boot spring-boot-starter-parent - 4.0.6 + 4.0.7 @@ -31,7 +31,7 @@ 2.6 10.9.1 2.21.5 - 3.1.4 + 3.1.5 From e25a3ba5eb1f53fe0640baa3942bda2695f20633 Mon Sep 17 00:00:00 2001 From: moghit-eou Date: Wed, 19 Aug 2026 11:39:52 +0100 Subject: [PATCH 5/5] chore(renovate): track DOCKERIZE_VERSION --- Dockerfile | 1 + renovate.json | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/Dockerfile b/Dockerfile index 2cd21516f..8a87ddc6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,6 +36,7 @@ WORKDIR /opt RUN apk add --no-cache curl +# renovate: datasource=github-releases depName=jwilder/dockerize ENV DOCKERIZE_VERSION=v0.14.0 RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ diff --git a/renovate.json b/renovate.json index 7094f757a..6a7b3e477 100644 --- a/renovate.json +++ b/renovate.json @@ -21,6 +21,16 @@ "matchStrings": [ "# renovate: datasource=(?[a-z-]+) depName=(?[^\\s]+)\\n\\s*python-version:\\s*'(?[0-9][0-9.]*)'" ] + }, + { + "customType": "regex", + "description": "Bump DOCKERIZE_VERSION pinned in Dockerfile", + "managerFilePatterns": [ + "/(^|/)Dockerfile[^/]*$/" + ], + "matchStrings": [ + "# renovate: datasource=(?[a-z-]+) depName=(?[^\\s]+)\\s*\\nENV DOCKERIZE_VERSION=(?v[0-9][0-9.]*)" + ] } ], "enabledManagers": [ @@ -48,6 +58,7 @@ "matchDatasources": [ "github-release-attachments", "github-tags", + "github-releases", "npm", "python-version" ],