diff --git a/.github/trivy/license-policy.rego b/.github/trivy/license-policy.rego new file mode 100644 index 00000000..76aae459 --- /dev/null +++ b/.github/trivy/license-policy.rego @@ -0,0 +1,108 @@ +package trivy +import data.lib.trivy + +default ignore := false + +# permissive licenses from export of backend definition in Fossa, +# see policy-backend-fossa for reference +default permissive := { + "0BSD", + "AFL-3.0", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "android-sdk", + "Apache-1.1", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "Apache-2.0", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "Artistic-1.0", # Safe if code isn’t modified and notice requirements are followed. Otherwise, you must state and disclose the source code of modifications/derivative works. + "BouncyCastle", + "BSD-1-Clause", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "BSD-2-Clause", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "BSD-3-Clause", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "BSD-3-Clause-No-Nuclear-Warranty", + "BSD-4-Clause", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "CC-BY-2.5", + "CC-BY-3.0", + "CC0-1.0", + "CDDL-1.0", # Safe if code isn’t modified and notice requirements are followed. Otherwise, you must state and disclose the source code of modifications/derivative works. + "CDDL-1.1", + "CPL-1.0", + "EPL-1.0", + "EPL-2.0", + "GPL-2.0-with-classpath-exception", # Safe to include or link in an executable provided that source availability/attribution requirements are followed. + "ICU", + "ISC", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "JSON", + "LGPL-2.0-only", # Requires you to (effectively) disclose your source code if the library is statically linked to your project. Not triggered if dynamically linked or a separate process. + "LGPL-2.0-or-later", # Requires you to (effectively) disclose your source code if the library is statically linked to your project. Not triggered if dynamically linked or a separate process. + "LGPL-2.1-only", # Requires you to (effectively) disclose your source code if the library is statically linked to your project. Not triggered if dynamically linked or a separate process. + "LGPL-2.1-or-later", # Requires you to (effectively) disclose your source code if the library is statically linked to your project. Not triggered if dynamically linked or a separate process. + "LGPL-3.0-only", # Requires you to (effectively) disclose your source code ifthe library is statically linked to your project. Not triggered if dynamically linked or a separate process. + "LGPL-3.0-or-later", # Requires you to (effectively) disclose your source code ifthe library is statically linked to your project. Not triggered if dynamically linked or a separate process. + "MIT", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "MPL-1.1", # Safe if code isn’t modified and notice requirements are followed. Otherwise, you must state and disclose the source code of modifications/derivative works. + "MPL-2.0", # Safe if code isn’t modified and notice requirements are followed. Otherwise, you must state and disclose thesource code of modifications/derivative works. + "OpenSSL", + "public-domain", + "SAX-PD", + "Unlicense", + "W3C", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "WTFPL", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + "X11", + "Zlib", # Permissive license which is perfectly safe to use provided proper attribution is given and retained. + } + +# mapping of licenses identified by cyclonedx to known license keys +default licenseMapping := { + "Bouncy Castle Licence": "BouncyCastle", + "Apache 2 License": "Apache-2.0", + "GNU General Public License, version 2 with the GNU Classpath Exception": "GPL-2.0-with-classpath-exception", + "Eclipse Public License (EPL) 2.0": "EPL-2.0", + } + +# default: allow everything defined in the list of permissive licenses +ignore { + input.Name == permissive[_] +} + +# allow licenses that are only named different due to the used tooling +ignore { + licenseMapping[input.Name] == permissive[_] +} + +# ch.qos.logback:logback-classic is dual licensed as LGPL 2.1 or Eclipse Public License v1.0 +# see https://github.com/qos-ch/logback/blob/master/LICENSE.txt +# cyclonedx identifies GNU Lesser General Public License +ignore { + input.PkgName == "ch.qos.logback:logback-classic" + input.Name == "GNU Lesser General Public License" +} + +# ch.qos.logback:logback-core is dual licensed as LGPL 2.1 or Eclipse Public License v1.0 +# see https://github.com/qos-ch/logback/blob/master/LICENSE.txt +# cyclonedx identifies GNU Lesser General Public License +ignore { + input.PkgName == "ch.qos.logback:logback-core" + input.Name == "GNU Lesser General Public License" +} + +# ch.qos.logback.contrib:logback-jackson is dual licensed as LGPL 2.1 or Eclipse Public License v1.0 +# see https://github.com/qos-ch/logback-contrib/blob/master/license-template.txt +# cyclonedx identifies GNU Lesser General Public License +ignore { + input.PkgName == "ch.qos.logback.contrib:logback-jackson" + input.Name == "GNU Lesser General Public License" +} + +# ch.qos.logback.contrib:logback-json-classic is dual licensed as LGPL 2.1 or Eclipse Public License v1.0 +# see https://github.com/qos-ch/logback-contrib/blob/master/license-template.txt +# cyclonedx identifies GNU Lesser General Public License +ignore { + input.PkgName == "ch.qos.logback.contrib:logback-json-classic" + input.Name == "GNU Lesser General Public License" +} + +# ch.qos.logback.contrib:logback-json-core is dual licensed as LGPL 2.1 or Eclipse Public License v1.0 +# see https://github.com/qos-ch/logback-contrib/blob/master/license-template.txt +# cyclonedx identifies GNU Lesser General Public License +ignore { + input.PkgName == "ch.qos.logback.contrib:logback-json-core" + input.Name == "GNU Lesser General Public License" +} diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml deleted file mode 100644 index b14a38d9..00000000 --- a/.github/workflows/fossa.yml +++ /dev/null @@ -1,87 +0,0 @@ -# This workflow scans the licenses with Fossa and waits until the license test finished -name: Fossa License Scan - -on: - workflow_run: - workflows: - - Push Workflow Trigger - types: - - completed - -jobs: - fossa-license-analyze: - name: "Fossa ${{ github.event.workflow_run.head_branch != 'master' && format('PR {0}', github.event.workflow_run.pull_requests[0].number) || 'master' }}" - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - name: Initiate check - env: - SHA: "${{ github.event.workflow_run.head_sha }}" - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - run: >- - gh api - --method POST - -H "Accept: application/vnd.github+json" - /repos/SDA-SE/mongodb-operator/statuses/${SHA} - -f state='pending' - -f target_url=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID} - -f description='Checking Licenses' - -f context='fossa-license-analyze' - continue-on-error: true - - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - with: - ref: ${{ github.event.workflow_run.head_sha }} # checkout commit that triggered this workflow - - - name: Set up JDK - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 - with: - distribution: 'temurin' - java-version: 21 - cache: 'gradle' - - - name: Install Fossa - run: "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/v3.2.8/install-latest.sh | sudo bash" - - - name: Fossa Analyze - env: - FOSSA_API_KEY: ${{ secrets.FOSSA_API_KEY }} - BRANCH: ${{ github.event.workflow_run.head_branch }} - run: fossa analyze --project "mongodb-operator" --branch "$BRANCH" - - - name: Fossa Test - env: - FOSSA_API_KEY: ${{ secrets.FOSSA_API_KEY }} - run: fossa test --project "mongodb-operator" --debug - - - name: Successful check - if: success() - env: - SHA: "${{ github.event.workflow_run.head_sha }}" - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - run: >- - gh api - --method POST - -H "Accept: application/vnd.github+json" - /repos/SDA-SE/mongodb-operator/statuses/${SHA} - -f state='success' - -f target_url=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID} - -f description='License approved' - -f context='fossa-license-analyze' - continue-on-error: true - - - name: Failed check - if: failure() - env: - SHA: "${{ github.event.workflow_run.head_sha }}" - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - run: >- - gh api - --method POST - -H "Accept: application/vnd.github+json" - /repos/SDA-SE/mongodb-operator/statuses/${SHA} - -f state='failure' - -f target_url=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID} - -f description='License check failed' - -f context='fossa-license-analyze' - continue-on-error: true diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml new file mode 100644 index 00000000..9d93d0de --- /dev/null +++ b/.github/workflows/license-check.yml @@ -0,0 +1,72 @@ +name: License Check + +# This check can be executed locally as follows: +# +# Install Trivy, see https://aquasecurity.github.io/trivy/v0.18.3/installation/ +# $ brew install aquasecurity/trivy/trivy +# +# Lock dependencies +# $ ./gradlew clean cyclonedxBom +# +# Check for licenses +# $ trivy sbom --scanners license --format table --ignore-policy .github/trivy/license-policy.rego build/reports/bom.json + +on: + pull_request: {} + release: + types: + - created + +jobs: + trivy-license-check: + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Set up JDK 21 + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + with: + distribution: 'temurin' + java-version: 21 + cache: 'gradle' + + - name: Create SBOM + run: ./gradlew clean cyclonedxBom + + - name: Attach SBOM to Release + if: github.event.release + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + gh release upload "${{ github.event.release.tag_name }}" "./build/reports/bom.json#CycloneDX generated JSON SBOM" + gh release upload "${{ github.event.release.tag_name }}" "./build/reports/bom.xml#CycloneDX generated XML SBOM" + + - name: Check for forbidden licenses + if: github.event.pull_request + run: > + docker run --rm + -v "${PWD}:/project" + aquasec/trivy:0.51.1 + sbom --scanners license + --format json + --ignore-policy /project/.github/trivy/license-policy.rego + --exit-code 1 + /project/build/reports/bom.json + >> trivy-licenses.json + - name: Add failure Job summary + if: failure() && github.event.pull_request + run: | + echo "| Dependency | License | Category | Severity |" > trivy-licenses.md + echo "|------------|---------|----------|----------|" >> trivy-licenses.md + cat trivy-licenses.json | jq --raw-output '.Results[] | select(.Licenses) | .Licenses[] | "| \(.PkgName) | \(.Name) | \(.Category) | \(.Severity) |"' >> trivy-licenses.md + echo '**License violations or unknown licenses found in dependencies:**' >> $GITHUB_STEP_SUMMARY + echo '' >> $GITHUB_STEP_SUMMARY + cat trivy-licenses.md >> $GITHUB_STEP_SUMMARY + + - name: Add success Job summary + if: success() && github.event.pull_request + run: | + echo 'All dependencies have allowed licenses.' >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/workflow-trigger.yml b/.github/workflows/workflow-trigger.yml deleted file mode 100644 index 9d129498..00000000 --- a/.github/workflows/workflow-trigger.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: Push Workflow Trigger - -on: - push - -jobs: - check-dependabot: - runs-on: ubuntu-latest - steps: - - run: echo "Push event occured, subsequently workflows will be triggered." diff --git a/build.gradle b/build.gradle index a7ea390c..ff91846f 100644 --- a/build.gradle +++ b/build.gradle @@ -5,6 +5,7 @@ plugins { id 'org.sonarqube' version '5.1.0.4882' id "com.diffplug.spotless" version "6.25.0" id "com.google.cloud.tools.jib" version "3.4.3" + id 'org.cyclonedx.bom' version '1.9.0' } repositories { @@ -46,8 +47,8 @@ jib { project.ext { mongoDbDriverVersion = "5.1.2" slf4jVersion = "2.0.13" - operatorFrameworkVersion = "4.9.1" - kubernetesServerMockVersion = "6.12.1" // align with transitive dependency of operator framework + operatorFrameworkVersion = "4.9.2" + kubernetesServerMockVersion = "6.13.1" // align with transitive dependency of operator framework mockitoVersion = "5.2.0" jacksonVersion = "2.17.2" logbackContribVersion = "0.1.5" @@ -77,9 +78,9 @@ dependencies { implementation "org.mongodb:mongodb-driver-sync:${mongoDbDriverVersion}" implementation 'org.hibernate.validator:hibernate-validator:8.0.1.Final' - implementation 'jakarta.el:jakarta.el-api:6.0.0' + implementation 'jakarta.el:jakarta.el-api:6.0.1' implementation 'org.bouncycastle:bcpkix-jdk18on:1.78.1' - implementation "io.javalin:javalin:6.1.6", { + implementation "io.javalin:javalin:6.2.0", { // self managed to avoid conflicts exclude group: "org.slf4j" // conflict with Kotlin version in Okio 3.9.0 @@ -112,7 +113,7 @@ dependencies { exclude group: "net.bytebuddy", module: "byte-buddy-agent" } // try to replace local commons-compress management on update! - testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.16.0', { + testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo:4.16.1', { exclude group: "org.slf4j", module: "slf4j-api" // CVE-2024-25710 + CVE-2024-26308 in transitive version 1.25.0 exclude group: "org.apache.commons", module: "commons-compress"