diff --git a/.github/workflows/container-scan.yml b/.github/workflows/container-scan.yml index 8dc9b047..c5c4cc2d 100644 --- a/.github/workflows/container-scan.yml +++ b/.github/workflows/container-scan.yml @@ -23,7 +23,7 @@ jobs: TRIVY_SCA_SARIF_OUTPUT: sca-trivy-container.sarif OSV_SCA_SARIF_OUTPUT: sca-osv-container.sarif - # SAST /Linting + # SAST / Linting SEMGREP_CONFIG_RULESETS: >- semgrep-rules/dockerfile auto OPENGREP_SAST_SARIF_OUTPUT: sast-opengrep-dockerfile.sarif @@ -51,52 +51,49 @@ jobs: run: python ci/container_scan.py --scan-type sast - name: Run SCA scanning - if: always() + if: ${{ !cancelled() }} run: python ci/container_scan.py --scan-type sca --image ${{ env.IMAGE_NAME }} - - name: Upload Trivy SARIF to GitHub Security tab - id: upload_trivy - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 - with: - sarif_file: ${{ env.TRIVY_SCA_SARIF_OUTPUT }} - category: trivy-container-scanning - - - name: Upload OSV Scanner SARIF to GitHub Security tab - id: upload_osv - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 - with: - sarif_file: ${{ env.OSV_SCA_SARIF_OUTPUT }} - category: osv-scanner-container-scanning - - - name: Upload OpenGrep SARIF to GitHub Security tab - id: upload_opengrep - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 - with: - sarif_file: ${{ env.OPENGREP_SAST_SARIF_OUTPUT }} - category: opengrep-sast - - - name: Upload Hadolint SARIF to GitHub Security tab - id: upload_hadolint - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 - with: - sarif_file: ${{ env.HADOLINT_SAST_SARIF_OUTPUT }} - category: hadolint-sast - - name: Merge all SARIF reports - if: always() + if: ${{ !cancelled() }} run: | python ci/container_scan.py \ --merge-sarif "${{ env.TRIVY_SCA_SARIF_OUTPUT }}" "${{ env.OSV_SCA_SARIF_OUTPUT }}" "${{ env.OPENGREP_SAST_SARIF_OUTPUT }}" "${{ env.HADOLINT_SAST_SARIF_OUTPUT }}" \ --merge-output "${{ env.CONTAINER_SCAN_MERGED_SARIF_OUTPUT }}" - - name: Upload SARIF artifacts - if: always() - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1 + - name: Upload merged SARIF to GitHub Security tab + if: ${{ !cancelled() && hashFiles(env.CONTAINER_SCAN_MERGED_SARIF_OUTPUT) != '' }} + uses: github/codeql-action/upload-sarif@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v4.31.2 + with: + sarif_file: ${{ env.CONTAINER_SCAN_MERGED_SARIF_OUTPUT }} + category: container-scan + + - name: Encrypt SARIF report + id: encrypt + if: ${{ !cancelled() && hashFiles(env.CONTAINER_SCAN_MERGED_SARIF_OUTPUT) != '' }} + env: + PW: ${{ secrets.ARTIFACT_PASSWORD }} + OUT: ${{ env.CONTAINER_SCAN_MERGED_SARIF_OUTPUT }}.gpg + run: | + if [ -z "$PW" ]; then + echo "::warning title=SARIF report not uploaded::ARTIFACT_PASSWORD is not available in this run (Dependabot, Renovate or fork PR). Skipping encryption and upload." + rm -f -- "$CONTAINER_SCAN_MERGED_SARIF_OUTPUT" + exit 0 + fi + printf '%s' "$PW" | gpg --symmetric --batch --yes --quiet \ + --pinentry-mode loopback --passphrase-fd 0 \ + --no-symkey-cache \ + --cipher-algo AES256 \ + --s2k-mode 3 --s2k-digest-algo SHA512 --s2k-count 65011712 \ + --output "$OUT" -- "$CONTAINER_SCAN_MERGED_SARIF_OUTPUT" + rm -f -- "$CONTAINER_SCAN_MERGED_SARIF_OUTPUT" + echo "encrypted=$OUT" >> "$GITHUB_OUTPUT" + + - name: Upload encrypted SARIF artifact + if: ${{ !cancelled() && steps.encrypt.outputs.encrypted != '' }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: container-scan-sarif-report - path: ${{ env.CONTAINER_SCAN_MERGED_SARIF_OUTPUT }} + path: ${{ steps.encrypt.outputs.encrypted }} retention-days: 30 + if-no-files-found: error diff --git a/.github/workflows/sast.yml b/.github/workflows/sast.yml index 1da6989d..5390f608 100644 --- a/.github/workflows/sast.yml +++ b/.github/workflows/sast.yml @@ -37,17 +37,39 @@ jobs: - name: Run SAST scanning run: python ci/sast_scan.py - - name: Upload Semgrep SARIF to GitHub Security tab - id: upload_semgrep - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 + - name: Upload SARIF to GitHub Security tab + if: ${{ !cancelled() && hashFiles(env.OPENGREP_SARIF_OUTPUT) != '' }} + uses: github/codeql-action/upload-sarif@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v4.31.2 with: sarif_file: ${{ env.OPENGREP_SARIF_OUTPUT }} category: semgrep-app - - name: Upload SARIF artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1 + - name: Encrypt SARIF report + id: encrypt + if: ${{ !cancelled() && hashFiles(env.OPENGREP_SARIF_OUTPUT) != '' }} + env: + PW: ${{ secrets.ARTIFACT_PASSWORD }} + OUT: ${{ env.OPENGREP_SARIF_OUTPUT }}.gpg + run: | + if [ -z "$PW" ]; then + echo "::warning title=SARIF report not uploaded::ARTIFACT_PASSWORD is not available in this run (Dependabot, Renovate or fork PR). Skipping encryption and upload." + rm -f -- "$OPENGREP_SARIF_OUTPUT" + exit 0 + fi + printf '%s' "$PW" | gpg --symmetric --batch --yes --quiet \ + --pinentry-mode loopback --passphrase-fd 0 \ + --no-symkey-cache \ + --cipher-algo AES256 \ + --s2k-mode 3 --s2k-digest-algo SHA512 --s2k-count 65011712 \ + --output "$OUT" -- "$OPENGREP_SARIF_OUTPUT" + rm -f -- "$OPENGREP_SARIF_OUTPUT" + echo "encrypted=$OUT" >> "$GITHUB_OUTPUT" + + - name: Upload encrypted SARIF artifact + if: ${{ !cancelled() && steps.encrypt.outputs.encrypted != '' }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: sast-scan-sarif-report - path: ${{ env.OPENGREP_SARIF_OUTPUT }} + path: ${{ steps.encrypt.outputs.encrypted }} retention-days: 30 + if-no-files-found: error diff --git a/.github/workflows/sca.yml b/.github/workflows/sca.yml index f917d337..4ef4cc0f 100644 --- a/.github/workflows/sca.yml +++ b/.github/workflows/sca.yml @@ -20,6 +20,9 @@ jobs: TRIVY_SARIF_OUTPUT: trivy-platform-backend.sarif OSV_SARIF_OUTPUT: osv-scanner-platform-backend.sarif SCA_MERGED_SARIF_OUTPUT: SCA-platform-backend-merged.sarif + # CVSS gate: fail at >= FAIL, warn between WARN and FAIL. + GATE_FAIL_THRESHOLD: "8.0" + GATE_WARN_THRESHOLD: "5.0" steps: - name: Check out repository @@ -32,41 +35,51 @@ jobs: python-version: '3.14.7' - name: Cache Maven packages - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 #v6.1.0 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: ~/.m2/repository # /.m2 only is too broad and can cause cache corruption issues key: ${{ runner.os }}-m2-v1-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2-v1- - - name: Resolve Maven dependencies - run: mvn dependency:resolve -q - - - name: Setup tools + - name: Setup tools and generate SBOM run: bash ci/setup-tools.sh --install-tool trivy,osv-scanner --sbom-ecosystem maven - name: Run SCA tools run: python ci/sca_scan.py - - name: Upload Trivy SARIF to GitHub Security tab - id: upload_trivy - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 + - name: Upload merged SARIF to GitHub Security tab + if: ${{ !cancelled() && hashFiles(env.SCA_MERGED_SARIF_OUTPUT) != '' }} + uses: github/codeql-action/upload-sarif@4e94bd11f71e507f7f87df81788dff88d1dacbfb # v4.31.2 with: - sarif_file: ${{ env.TRIVY_SARIF_OUTPUT }} - category: trivy-app + sarif_file: ${{ env.SCA_MERGED_SARIF_OUTPUT }} + category: sca-app - - name: Upload OSV Scanner SARIF to GitHub Security tab - id: upload_osv - if: always() - uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 #v4.38.0 - with: - sarif_file: ${{ env.OSV_SARIF_OUTPUT }} - category: osv-scanner-app + - name: Encrypt SARIF report + id: encrypt + if: ${{ !cancelled() && hashFiles(env.SCA_MERGED_SARIF_OUTPUT) != '' }} + env: + PW: ${{ secrets.ARTIFACT_PASSWORD }} + OUT: ${{ env.SCA_MERGED_SARIF_OUTPUT }}.gpg + run: | + if [ -z "$PW" ]; then + echo "::warning title=SARIF report not uploaded::ARTIFACT_PASSWORD is not available in this run (Dependabot, Renovate or fork PR). Skipping encryption and upload." + rm -f -- "$SCA_MERGED_SARIF_OUTPUT" + exit 0 + fi + printf '%s' "$PW" | gpg --symmetric --batch --yes --quiet \ + --pinentry-mode loopback --passphrase-fd 0 \ + --no-symkey-cache \ + --cipher-algo AES256 \ + --s2k-mode 3 --s2k-digest-algo SHA512 --s2k-count 65011712 \ + --output "$OUT" -- "$SCA_MERGED_SARIF_OUTPUT" + rm -f -- "$SCA_MERGED_SARIF_OUTPUT" + echo "encrypted=$OUT" >> "$GITHUB_OUTPUT" - - name: Upload SARIF artifacts - if: always() - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1 + - name: Upload encrypted SARIF artifact + if: ${{ !cancelled() && steps.encrypt.outputs.encrypted != '' }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: sca-scan-sarif-report - path: ${{ env.SCA_MERGED_SARIF_OUTPUT }} + path: ${{ steps.encrypt.outputs.encrypted }} retention-days: 30 + if-no-files-found: error diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml new file mode 100644 index 00000000..cd8bb584 --- /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 e0d92dfd..c2a0f044 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 # frozen: v6.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -13,3 +13,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: 83d9cd684c87d95d656c1458ef04895a7f1cbd8e # frozen: v8.30.1 + hooks: + - id: gitleaks diff --git a/ci/README.md b/ci/README.md index ca91b851..eb8eb4ae 100644 --- a/ci/README.md +++ b/ci/README.md @@ -25,20 +25,22 @@ Following the OWASP DevSecOps model, scanning is split into three independent pi ``` .github/ -├── workflows/ -│ ├── container-scan.yml # builds the image, scans the Dockerfile (SAST) and image (SCA) -│ ├── sca.yml # resolves deps, generates SBOM, scans it (SCA) -│ └── sast.yml # scans source code (SAST) -└── scripts/ - ├── setup-tools.sh # installs trivy, osv-scanner, opengrep, hadolint, semgrep-rules - ├── container_scan.py # orchestrator for container-scan.yml - ├── sca_scan.py # orchestrator for sca.yml - ├── sast_scan.py # orchestrator for sast.yml - ├── parse_sarif.py # shared: reads SARIF security-severity scores - ├── suppress_trivy.yaml # shared Trivy ignore file - └── suppress_osv_scanner.toml # shared OSV-Scanner ignore file +└── workflows/ + ├── container-scan.yml # builds the image, scans the Dockerfile (SAST) and image (SCA) + ├── sca.yml # resolves deps, generates SBOM, scans it (SCA) + ├── sast.yml # scans source code (SAST) + ├── publish_images.yml # publishes built images + └── ebrains.yml # EBRAINS-specific pipeline + +ci/ +├── setup-tools.sh # installs trivy, osv-scanner, opengrep, hadolint, semgrep-rules +├── container_scan.py # orchestrator for container-scan.yml +├── sca_scan.py # orchestrator for sca.yml +├── sast_scan.py # orchestrator for sast.yml +├── parse_sarif.py # shared: reads SARIF security-severity scores +├── suppress_trivy.yaml # shared Trivy ignore file +└── suppress_osv_scanner.toml # shared OSV-Scanner ignore file ``` - > **Note:** all three workflows trigger on `pull_request`, `workflow_dispatch`, and a weekly Monday 02:00 UTC schedule, and run independently in parallel. Each has its own gate and its own category in the GitHub Security tab. ## 2. Architecture diff --git a/ci/container_scan.py b/ci/container_scan.py index e909dc01..d0cbf8b1 100644 --- a/ci/container_scan.py +++ b/ci/container_scan.py @@ -4,7 +4,7 @@ import logging import json import argparse -from parse_sarif import evaluate +from parse_sarif import evaluate, GATE_FAIL_THRESHOLD, GATE_WARN_THRESHOLD GREEN = '\033[92m' @@ -92,12 +92,12 @@ def handle_sca(): eval_result = evaluate(path) if eval_result.gate_failed: - tool_status[name] = "FAILED" # this tool found CVSS >= 8.0 + tool_status[name] = "FAILED" gate_failed = True elif eval_result.gate_warn: - tool_status[name] = "WARNING" # this tool found 5.0 <= CVSS < 8.0 + tool_status[name] = "WARNING" else: - tool_status[name] = "PASSED" # this tool found nothing >= 5.0 + tool_status[name] = "PASSED" # Print summary of results logger.info(f"\n{BOLD}========== SCA PIPELINE SUMMARY =========={RESET}") @@ -105,12 +105,11 @@ def handle_sca(): if status == "PASSED": logger.info(f"[{name}]: {GREEN}PASSED{RESET}") elif status == "WARNING": - logger.warning(f"[{name}]: {YELLOW}WARNING (findings between 5.0 and 8.0){RESET}") + logger.warning(f"[{name}]: {YELLOW}WARNING (findings between {GATE_WARN_THRESHOLD} and {GATE_FAIL_THRESHOLD}){RESET}") elif status == "ERROR": logger.error(f"[{name}]: {RED}ERROR (tool did not run correctly){RESET}") else: - logger.error(f"[{name}]: {RED}FAILED (CVSS >= 8.0 found){RESET}") - logger.info(f"{BOLD}=========================================={RESET}\n") + logger.error(f"[{name}]: {RED}FAILED (CVSS >= {GATE_FAIL_THRESHOLD} found){RESET}") # Exit with non-zero code if any tool failed the gate if gate_failed: diff --git a/ci/parse_sarif.py b/ci/parse_sarif.py index 5d35c970..793a2e6e 100644 --- a/ci/parse_sarif.py +++ b/ci/parse_sarif.py @@ -1,6 +1,10 @@ import json +import os from dataclasses import dataclass +GATE_FAIL_THRESHOLD = float(os.getenv("GATE_FAIL_THRESHOLD", "8.0")) +GATE_WARN_THRESHOLD = float(os.getenv("GATE_WARN_THRESHOLD", "5.0")) + @dataclass class EvaluationResult: gate_failed: bool @@ -34,6 +38,6 @@ def evaluate(sarif_paths): max_score = max(max_score, float(score)) return EvaluationResult( - gate_failed=max_score >= 8, - gate_warn=5 <= max_score < 8, + gate_failed=max_score >= GATE_FAIL_THRESHOLD, + gate_warn=GATE_WARN_THRESHOLD <= max_score < GATE_FAIL_THRESHOLD, ) diff --git a/ci/sast_scan.py b/ci/sast_scan.py index 5c40496d..98e9d358 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" ).split() OPENGREP_EXCLUDE = os.getenv( "OPENGREP_EXCLUDE", diff --git a/ci/sca_scan.py b/ci/sca_scan.py index b3297d94..2c651ec7 100644 --- a/ci/sca_scan.py +++ b/ci/sca_scan.py @@ -3,7 +3,7 @@ import sys import logging import json -from parse_sarif import evaluate +from parse_sarif import evaluate, GATE_FAIL_THRESHOLD, GATE_WARN_THRESHOLD GREEN = '\033[92m' RED = '\033[91m' @@ -114,12 +114,11 @@ def main(): if status == "PASSED": logger.info(f"[{name}]: {GREEN}PASSED{RESET}") elif status == "WARNING": - logger.warning(f"[{name}]: {YELLOW}WARNING (findings between 5.0 and 8.0){RESET}") + logger.warning(f"[{name}]: {YELLOW}WARNING (findings between {GATE_WARN_THRESHOLD} and {GATE_FAIL_THRESHOLD}){RESET}") elif status == "ERROR": logger.error(f"[{name}]: {RED}ERROR (tool did not run correctly){RESET}") else: - logger.error(f"[{name}]: {RED}FAILED (CVSS >= 8.0 found){RESET}") - logger.info(f"{BOLD}=========================================={RESET}\n") + logger.error(f"[{name}]: {RED}FAILED (CVSS >= {GATE_FAIL_THRESHOLD} found){RESET}") # Exit with non-zero code if any tool failed the gate if gate_failed: diff --git a/ci/setup-tools.sh b/ci/setup-tools.sh index 95d6b542..ec539a09 100644 --- a/ci/setup-tools.sh +++ b/ci/setup-tools.sh @@ -22,7 +22,7 @@ OSV_SCANNER_SHA256="${OSV_SCANNER_SHA256:-f9f25499a2c8cc367b3af45df2ea7eeca7fbcc OPENGREP_VERSION="${OPENGREP_VERSION:-v1.30.0}" OPENGREP_SHA256="${OPENGREP_SHA256:-35779bdd72e92129c8df2a77f0c55e8c08356801ea92591ef32108d6b28d564c}" -# renovate: datasource=github-tags depName=semgrep/semgrep-rules +# renovate: datasource=git-refs depName=https://github.com/semgrep/semgrep-rules SEMGREP_RULES_REF="${SEMGREP_RULES_REF:-40b8c63f75dc7c22c8a77482d73bfb864b146f7e}" SEMGREP_RULES_DIR="semgrep-rules" @@ -30,6 +30,10 @@ SEMGREP_RULES_DIR="semgrep-rules" HADOLINT_VERSION="${HADOLINT_VERSION:-v2.15.1}" HADOLINT_SHA256="${HADOLINT_SHA256:-c7187db94eeeeca956519a6af171adc31453941a1e777961f6e680f697c8c507}" +# 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.1}" @@ -128,14 +132,29 @@ 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) echo "Generating SBOM for Maven project" - mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom -q + mvn -B -ntp dependency:resolve -q + mvn -B -ntp org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom -q ;; npm) echo "Generating SBOM for NPM project" + npm ci npx --yes "@cyclonedx/cyclonedx-npm@${CYCLONEDX_NPM_VERSION}" --output-file target/bom.json ;; none) diff --git a/ci/suppress_gitleaks.toml b/ci/suppress_gitleaks.toml new file mode 100644 index 00000000..5673600f --- /dev/null +++ b/ci/suppress_gitleaks.toml @@ -0,0 +1,4 @@ +[allowlist] +paths = [ + '''AGENTS\.md''', +] diff --git a/renovate.json b/renovate.json index 7094f757..1af49b6f 100644 --- a/renovate.json +++ b/renovate.json @@ -21,10 +21,32 @@ "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.]*)" + ] + }, + { + "currentValueTemplate": "develop", + "customType": "regex", + "description": "Track a git branch head pinned as a commit SHA in CI setup scripts", + "managerFilePatterns": [ + "/(^|/)setup-tools\\.sh$/" + ], + "matchStrings": [ + "# renovate: datasource=(?git-refs) depName=(?[^\\s]+)\\n[A-Z_]+_REF=\"\\$\\{[A-Z_]+_REF:-(?[a-f0-9]{40})\\}\"" + ] } ], "enabledManagers": [ - "custom.regex" + "custom.regex", + "pre-commit" ], "extends": [ "config:recommended" @@ -48,8 +70,10 @@ "matchDatasources": [ "github-release-attachments", "github-tags", + "github-releases", "npm", - "python-version" + "python-version", + "git-refs" ], "minimumReleaseAge": "7 days" } diff --git a/src/main/java/hbp/mip/configurations/OpenApiConfig.java b/src/main/java/hbp/mip/configurations/OpenApiConfig.java index 0ee5264d..9ecc8e29 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 faca46b3..a34561cd 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 3b68be5c..48a62b4a 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/Exceptions/BadRequestException.java b/src/main/java/hbp/mip/utils/Exceptions/BadRequestException.java index a8383066..cd3bfb4d 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 30373550..cfec9a6e 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 31357164..2439779b 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 6ac31b89..66e2ba16 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 1cbe3cf2..bb07f6f5 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 +}