diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 6d48f394c..21c88334d 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -52,7 +52,7 @@ postUpdateOptions: ["gomodTidy", "gomodUpdateImportPaths"], packageRules: [ - // Enable pinning for container images + // Enable pinning for container images (main and supported release branches) // https://docs.renovatebot.com/presets-docker/#dockerpindigests { enabled: true, @@ -63,7 +63,7 @@ schedule: ["* * * * 0"], // weekly }, - // Base images from dev_tools/builder_images + // Base images from dev_tools/builder_images (main branch) // are upgraded separately as it requires two steps { enabled: true, @@ -73,6 +73,16 @@ groupSlug: "pin-builders", schedule: ["* * 1 * *"], // every month matchPaths: ["dev_tools/builder_images/**"], + matchBaseBranches: ["main"], + }, + + // Disable dev_tools/builder_images images upgrades + // for non-main branch + { + enabled: false, + matchDatasources: ["docker"], + matchPaths: ["dev_tools/builder_images/**"], + matchBaseBranches: ["!main"], }, // Disable non-security upgrades for go and npm. @@ -155,7 +165,7 @@ matchUpdateTypes: ["major", "minor", "patch"], }, - // Group GitHub Actions updates + // Group GitHub Actions updates for main branch { enabled: true, separateMajorMinor: false, @@ -163,6 +173,14 @@ matchManagers: ["github-actions"], matchPackagePatterns: ["*"], schedule: ["* * 1,15 * *"], // twice a month + matchBaseBranches: ["main"], + }, + + // Disable upgrades for non-main branches + { + enabled: false, + matchManagers: ["github-actions"], + matchBaseBranches: ["!main"], }, // Go version used in GitHub Actions is updated manually @@ -190,7 +208,7 @@ matchUpdateTypes: ["major", "minor", "patch"], }, - // Group Go version upgrades + // Group Go version upgrades for main branch { enabled: true, matchPackageNames: ["golang", "go"], @@ -198,6 +216,19 @@ groupName: "Go version", groupSlug: "go-version", schedule: ["* * * * 0"], // weekly + matchBaseBranches: ["main"], + }, + + // Group Go version upgrades for supported release branch + // with necessary restrictions + { + enabled: true, + matchPackageNames: ["golang", "go"], + allowedVersions: "<1.24", + groupName: "Go version", + groupSlug: "go-version", + schedule: ["* * * * 0"], // weekly + matchBaseBranches: ["release-2.13"], }, // Restrict uv version used in workflows, it will be updated manually diff --git a/.github/workflows/cleanup-old-packages.yml b/.github/workflows/cleanup-old-packages.yml index 6866d1f2e..4ab6fa5ce 100644 --- a/.github/workflows/cleanup-old-packages.yml +++ b/.github/workflows/cleanup-old-packages.yml @@ -1,12 +1,12 @@ # GHCR cleanup workflow # # This workflow deletes untagged and old package daily builds from GHCR registry. -# +# # Key Features: # - Deletes untagged and old package daily builds from GHCR registry # - Can be triggered manually or by other workflows # - Supports dry run mode to preview changes -# +# # Process Stages: # 1. Prepare list of package versions to delete # 2. Delete old package versions @@ -59,17 +59,17 @@ on: type: boolean default: true -permissions: - contents: read - packages: write +permissions: {} # No permissions by default on workflow level jobs: prepare-vars: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Prepare list of package ids to delete id: prepare-versions - env: + env: MIN_VERSIONS_TO_KEEP: ${{ github.event.inputs.min_versions_to_keep }} PACKAGE_NAME: ${{ github.event.inputs.package_name }} GH_TOKEN: ${{ secrets.GHCR_CLEANUP_TOKEN }} @@ -112,18 +112,18 @@ jobs: - name: Cleanup old packages if: ${{ github.event.inputs.dry_run != 'true' && steps.prepare-versions.outputs.package_version_ids != '' }} - uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 + uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 with: - package-name: '${{ github.event.inputs.package_name }}' - package-type: 'container' - package-version-ids: '${{ steps.prepare-versions.outputs.package_version_ids }}' + package-name: "${{ github.event.inputs.package_name }}" + package-type: "container" + package-version-ids: "${{ steps.prepare-versions.outputs.package_version_ids }}" token: ${{ secrets.GHCR_CLEANUP_TOKEN }} - name: Cleanup untagged packages if: ${{ github.event.inputs.dry_run != 'true' }} - uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 + uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 with: - package-name: '${{ github.event.inputs.package_name }}' - package-type: 'container' + package-name: "${{ github.event.inputs.package_name }}" + package-type: "container" token: ${{ secrets.GHCR_CLEANUP_TOKEN }} delete-only-untagged-versions: true diff --git a/.github/workflows/collect-source.yml b/.github/workflows/collect-source.yml index d5a4cc371..bf522f33a 100644 --- a/.github/workflows/collect-source.yml +++ b/.github/workflows/collect-source.yml @@ -65,7 +65,22 @@ jobs: TARGET: ${{ matrix.target }} run: | # install Syft - curl -sSfL https://get.anchore.io/syft | sudo sh -s -- -b /usr/local/bin + + VERSION=1.38.2 + OS=linux + ARCH=amd64 + BASE_URL="https://github.com/anchore/syft/releases/download/v${VERSION}" + curl -sL "${BASE_URL}/syft_${VERSION}_${OS}_${ARCH}.tar.gz" > syft_${VERSION}_${OS}_${ARCH}.tar.gz + curl -sL "${BASE_URL}/syft_${VERSION}_checksums.txt" | grep -E "syft_${VERSION}_${OS}_${ARCH}\\.tar\\.gz$" > checkSum.txt + if [ -s checkSum.txt ]; then + sha256sum -c checkSum.txt + else + echo "Checksum file not found or empty" + exit 1 + fi + tar -zxvf syft_${VERSION}_${OS}_${ARCH}.tar.gz -C /usr/local/bin/ syft + echo "Syft $(syft --version) installed successfully" + NAME=$(echo "$TARGET" | cut -d'/' -f 4 | cut -d':' -f 1) echo "name=$NAME" >> $GITHUB_ENV @@ -118,43 +133,43 @@ jobs: container: image: debian:bookworm-slim@sha256:b4aa902587c2e61ce789849cb54c332b0400fe27b1ee33af4669e1f7e7c3e22f steps: - - name: Add apt sources for deb-src - shell: bash - run: | - sed -Ei "s/^Types: deb$/Types: deb deb-src/" /etc/apt/sources.list.d/debian.sources - apt-get update - - - name: Find GPL/MPL licensed packages - shell: bash - env: - PACKAGES: ${{ needs.get-unique-names.outputs.unique_package_names_oneline }} - run: | - OUTPUT_DIR="output" - ARCHIVE_NAME="source_code.tar.gz" - mkdir -p "$OUTPUT_DIR" - cd "$OUTPUT_DIR" - # Split comma-separated list into an array - IFS=',' read -r -a PACKAGES_ARR <<< "$PACKAGES" - # Collect missing packages - # Install GNU Parallel for faster downloads - apt-get update && apt-get install -y parallel - - # Download sources for GPL/MPL packages in parallel with error handling - if [ ${#PACKAGES_ARR[@]} -gt 0 ]; then - export OUTPUT_DIR - printf "%s\n" "${PACKAGES_ARR[@]}" | parallel --jobs 4 ' - echo "Downloading source for {}" - if ! apt-get source -q --download-only "{}"; then - echo "Warning: Source not available for {}" >&2 - fi - ' - fi - cd .. - tar -czf "$ARCHIVE_NAME" -C "$OUTPUT_DIR" . - - - name: Upload source code archive - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: source-code-archive - path: source_code.tar.gz - retention-days: 3 + - name: Add apt sources for deb-src + shell: bash + run: | + sed -Ei "s/^Types: deb$/Types: deb deb-src/" /etc/apt/sources.list.d/debian.sources + apt-get update + + - name: Find GPL/MPL licensed packages + shell: bash + env: + PACKAGES: ${{ needs.get-unique-names.outputs.unique_package_names_oneline }} + run: | + OUTPUT_DIR="output" + ARCHIVE_NAME="source_code.tar.gz" + mkdir -p "$OUTPUT_DIR" + cd "$OUTPUT_DIR" + # Split comma-separated list into an array + IFS=',' read -r -a PACKAGES_ARR <<< "$PACKAGES" + # Collect missing packages + # Install GNU Parallel for faster downloads + apt-get update && apt-get install -y parallel + + # Download sources for GPL/MPL packages in parallel with error handling + if [ ${#PACKAGES_ARR[@]} -gt 0 ]; then + export OUTPUT_DIR + printf "%s\n" "${PACKAGES_ARR[@]}" | parallel --jobs 4 ' + echo "Downloading source for {}" + if ! apt-get source -q --download-only "{}"; then + echo "Warning: Source not available for {}" >&2 + fi + ' + fi + cd .. + tar -czf "$ARCHIVE_NAME" -C "$OUTPUT_DIR" . + + - name: Upload source code archive + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: source-code-archive + path: source_code.tar.gz + retention-days: 3 diff --git a/.github/workflows/component.yml b/.github/workflows/component.yml index e8446a568..92ee72ef6 100644 --- a/.github/workflows/component.yml +++ b/.github/workflows/component.yml @@ -71,7 +71,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: read - packages: write + packages: write # to publish packages timeout-minutes: 30 env: TAG: ${{ inputs.build_version || github.sha }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2d790d013..b75900d89 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -204,7 +204,7 @@ jobs: needs: get-vars permissions: contents: read - packages: write + packages: write # to publish packages uses: ./.github/workflows/component.yml if: ${{ !contains(needs.get-vars.outputs.filtered-components-list, '[]') }} strategy: @@ -224,7 +224,7 @@ jobs: needs: get-vars permissions: contents: read - packages: write + packages: write # to publish packages uses: ./.github/workflows/web-ui.yml if: ${{ contains(needs.get-vars.outputs.components-list, 'web_ui') }} with: @@ -240,7 +240,7 @@ jobs: - web-ui-workflow permissions: contents: read - packages: write + packages: write # to publish packages uses: ./.github/workflows/package-distribution.yaml with: build_all: ${{ fromJSON(needs.get-vars.outputs.build_all) }} # fromJSON is required to cast string to boolean @@ -257,7 +257,7 @@ jobs: - web-ui-workflow - package-distribution-workflow permissions: - discussions: write + discussions: write # to publish discussion/daily build runs-on: ubuntu-latest if: ${{ always() && !cancelled() }} env: diff --git a/.github/workflows/package-distribution.yaml b/.github/workflows/package-distribution.yaml index c06530aca..cd1dd273d 100644 --- a/.github/workflows/package-distribution.yaml +++ b/.github/workflows/package-distribution.yaml @@ -60,7 +60,7 @@ jobs: if: ${{ inputs.build_all }} permissions: contents: read - packages: write + packages: write # to publish packages env: TAG: ${{ inputs.build_version }} PLATFORM_VERSION: ${{ inputs.platform_version }} diff --git a/.github/workflows/pr-security-scan.yaml b/.github/workflows/pr-security-scan.yaml index c7df2f7be..44c8ec63f 100644 --- a/.github/workflows/pr-security-scan.yaml +++ b/.github/workflows/pr-security-scan.yaml @@ -47,7 +47,7 @@ jobs: uses: open-edge-platform/geti-ci/actions/bandit@3cdaaaa0fc400b63f52f4dbb007fa0b69939e0ab with: scan-scope: "changed" - severity-level: "HIGH" - confidence-level: "HIGH" + severity-level: "LOW" + confidence-level: "LOW" config_file: ".github/bandit_config.yml" fail-on-findings: true diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 97245067d..7da6f1abe 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -59,7 +59,7 @@ jobs: fail-on-findings: false # reports only # TODO: unify approach and migrate to reusable workflows/composite actions - trivy-scan: + trivy-scan-config: runs-on: ubuntu-latest permissions: contents: read @@ -85,3 +85,27 @@ jobs: uses: github/codeql-action/upload-sarif@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 with: sarif_file: "trivy-results.sarif" + + trivy-scan-lock: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Harden the runner (audit all outbound calls) + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + persist-credentials: false + - name: Run Trivy vulnerability scanner in vuln/secret modes + uses: open-edge-platform/geti-ci/actions/trivy@3cdaaaa0fc400b63f52f4dbb007fa0b69939e0ab + with: + scan_type: "fs" + scan-scope: all + severity: "LOW" + scanners: "vuln,secret" + format: "table" # Use plain text output format to omit uploading code scanning results to Security tab + timeout: "15m" + ignore_unfixed: "true" diff --git a/.github/workflows/web-ui.yml b/.github/workflows/web-ui.yml index 419645dde..37bc4d606 100644 --- a/.github/workflows/web-ui.yml +++ b/.github/workflows/web-ui.yml @@ -270,7 +270,7 @@ jobs: needs: [lint, unit-tests, merge-playwright-reports] permissions: contents: read # to checkout code - packages: write + packages: write # to publish packages uses: ./.github/workflows/component.yml with: build_version: ${{ inputs.build_version }} diff --git a/README.md b/README.md index 184394561..ed9695875 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ LIMITED EDGE SOFTWARE DISTRIBUTION LICENSE [![python](https://img.shields.io/badge/python-3.10%2B-green)]() [![pytorch](https://img.shields.io/badge/pytorch-2.5%2B-orange)]() [![openvino](https://img.shields.io/badge/openvino-2025.1.0-purple)]() +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/open-edge-platform/geti/badge)](https://securityscorecards.dev/viewer/?uri=github.com/open-edge-platform/geti) diff --git a/interactive_ai/services/resource/app/code_deployment/example_code/requirements-notebook.txt b/interactive_ai/services/resource/app/code_deployment/example_code/requirements-notebook.txt index 796b45cf3..a99553495 100644 --- a/interactive_ai/services/resource/app/code_deployment/example_code/requirements-notebook.txt +++ b/interactive_ai/services/resource/app/code_deployment/example_code/requirements-notebook.txt @@ -1,7 +1,7 @@ # Requirements for running the `demo_notebook.ipynb` Jupyter notebook geti-sdk~=2.13 -jupyterlab>=3.6 +jupyterlab>=4.4.8 opencv-python>=4.10 -Pillow>=9.4.0 +Pillow>=10.3.0 ipython>=8.10.0 ipywidgets~=8.1 \ No newline at end of file diff --git a/platform/services/account/Dockerfile.protoc b/platform/services/account/Dockerfile.protoc index e193b1e5f..4e5d38e82 100644 --- a/platform/services/account/Dockerfile.protoc +++ b/platform/services/account/Dockerfile.protoc @@ -1,4 +1,4 @@ -FROM golang:1.20.5 +FROM golang:1.20.5@sha256:fd9306e1c664bd49a11d4a4a04e41303430e069e437d137876e9290a555e06fb RUN apt-get update && \ apt-get install --no-install-recommends -y \