diff --git a/.github/actions/analysis/codeql/action.yml b/.github/actions/analysis/codeql/action.yml new file mode 100644 index 0000000..6888a9b --- /dev/null +++ b/.github/actions/analysis/codeql/action.yml @@ -0,0 +1,25 @@ +# +# BSD 3-Clause License +# Copyright (C) 2026 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# +name: 'CodeQL Scan' +description: 'Initialize CodeQL, build dvledtx, and perform CodeQL analysis for C/C++' + +runs: + using: composite + steps: + - name: Initialize CodeQL + uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 + with: + languages: c-cpp + build-mode: manual + + # c-cpp requires a manual build so CodeQL can trace the meson/ninja compiler invocations. + - name: Build dvledtx + uses: $/.github/actions/build-dvledtx + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 + with: + category: "/language:c-cpp" diff --git a/.github/actions/analysis/gitleaks/action.yml b/.github/actions/analysis/gitleaks/action.yml index c408063..8903570 100644 --- a/.github/actions/analysis/gitleaks/action.yml +++ b/.github/actions/analysis/gitleaks/action.yml @@ -4,43 +4,78 @@ # SPDX-License-Identifier: BSD-3-Clause # name: 'Gitleaks Scan' -description: 'Scan repository for secrets and credentials using Gitleaks' +description: 'Scan git history and the working tree for secrets using the Gitleaks CLI' inputs: - github-token: - description: 'GitHub token for Gitleaks API access' - required: true + version: + description: 'Gitleaks release version to install (without the leading v)' + required: false + default: '8.30.1' runs: using: composite steps: - - name: Run Gitleaks - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9 + - name: Install Gitleaks + shell: bash env: - GITHUB_TOKEN: ${{ inputs.github-token }} + GITLEAKS_VERSION: ${{ inputs.version }} + run: | + set -euo pipefail + TMP_DIR="$(mktemp -d)" + pushd "$TMP_DIR" > /dev/null + + ARCHIVE="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" + CHECKSUMS="gitleaks_${GITLEAKS_VERSION}_checksums.txt" + BASE_URL="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}" + + echo "Downloading Gitleaks ${GITLEAKS_VERSION}" + curl -sSfL --retry 3 -o "$ARCHIVE" "${BASE_URL}/${ARCHIVE}" + curl -sSfL --retry 3 -o "$CHECKSUMS" "${BASE_URL}/${CHECKSUMS}" + + echo "Verifying checksum" + grep " ${ARCHIVE}\$" "$CHECKSUMS" | sha256sum -c - + + tar -xzf "$ARCHIVE" gitleaks + sudo install -m 0755 gitleaks /usr/local/bin/gitleaks + + popd > /dev/null + rm -rf "$TMP_DIR" + + gitleaks version - name: Gitleaks git history scan - if: always() + id: git-scan shell: bash run: | + set -uo pipefail REPORT_DIR="$GITHUB_WORKSPACE/reports" mkdir -p "$REPORT_DIR" echo "===== Gitleaks Git History Scan =====" - gitleaks git \ - --report-format sarif \ - --report-path "$REPORT_DIR/gitleaks-git-report.sarif" \ - . 2>&1 | tee "$REPORT_DIR/gitleaks-git-scan.txt" || true - echo "Gitleaks git history scan complete." - - - name: Copy report to reports directory - if: always() + gitleaks git -v 2>&1 | tee "$REPORT_DIR/gitleaks-git-scan.txt" + echo "rc=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT" + + - name: Gitleaks directory scan + id: dir-scan shell: bash run: | + set -uo pipefail REPORT_DIR="$GITHUB_WORKSPACE/reports" mkdir -p "$REPORT_DIR" - if [ -f "$GITHUB_WORKSPACE/results.sarif" ]; then - cp "$GITHUB_WORKSPACE/results.sarif" "$REPORT_DIR/gitleaks-report.sarif" - echo "Gitleaks SARIF written to $REPORT_DIR/gitleaks-report.sarif" - else - echo "No Gitleaks SARIF output found" + echo "===== Gitleaks Directory Scan =====" + gitleaks dir . -v 2>&1 | tee "$REPORT_DIR/gitleaks-dir-scan.txt" + echo "rc=${PIPESTATUS[0]}" >> "$GITHUB_OUTPUT" + + - name: Evaluate Gitleaks result + shell: bash + env: + GITLEAKS_GIT_RC: ${{ steps.git-scan.outputs.rc }} + GITLEAKS_DIR_RC: ${{ steps.dir-scan.outputs.rc }} + run: | + set -euo pipefail + echo "git history scan exit code: $GITLEAKS_GIT_RC" + echo "directory scan exit code: $GITLEAKS_DIR_RC" + if [ "$GITLEAKS_GIT_RC" -ne 0 ] || [ "$GITLEAKS_DIR_RC" -ne 0 ]; then + echo "::error::Gitleaks detected potential secrets. See reports/gitleaks-*-scan.txt" + exit 1 fi + echo "No leaks detected." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04f9e6e..b0e0300 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,13 +29,6 @@ jobs: contents: read security-events: write # Required to upload SARIF results to GitHub Security tab steps: - - name: Clean up previous run - env: - WORKSPACE: ${{ github.workspace }} - run: | - find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf {} + - rm -rf /tmp/trivy-* - - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -44,31 +37,31 @@ jobs: persist-credentials: false - name: Environment check - uses: ./.github/actions/environment-check + uses: $/.github/actions/environment-check - name: Build - uses: ./.github/actions/build-dvledtx + uses: $/.github/actions/build-dvledtx - name: Smoke test - uses: ./.github/actions/smoke-tests + uses: $/.github/actions/smoke-tests - name: Unit tests - uses: ./.github/actions/unit-tests + uses: $/.github/actions/unit-tests - name: ShellCheck - uses: ./.github/actions/analysis/shellcheck + uses: $/.github/actions/analysis/shellcheck - name: zizmor Scan - uses: ./.github/actions/analysis/zizmor + uses: $/.github/actions/analysis/zizmor - name: cppcheck - uses: ./.github/actions/analysis/cppcheck + uses: $/.github/actions/analysis/cppcheck - name: Trivy Scan - uses: ./.github/actions/analysis/trivy + uses: $/.github/actions/analysis/trivy - name: checksec Analysis - uses: ./.github/actions/analysis/checksec + uses: $/.github/actions/analysis/checksec - name: Upload all reports uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..a12505d --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,55 @@ +# +# BSD 3-Clause License +# Copyright (C) 2026 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# +# CodeQL Advanced workflow for dvledtx (C/C++ project built with meson/ninja). +# +# The repository only contains C sources, so the language matrix is reduced to +# `c-cpp` with a manual build, reusing the environment-check/build-dvledtx +# composite actions so CodeQL traces the same build the rest of CI performs. +name: CodeQL Scan + +on: + push: + branches: + - main + - dev + pull_request: + branches: + - main + - dev + schedule: + # Weekly on Wednesday at 05:00 UTC + - cron: '0 5 * * 3' + workflow_dispatch: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + codeql: + name: CodeQL Scan + runs-on: ubuntu-latest + timeout-minutes: 90 + permissions: + contents: read + security-events: write # Required to upload CodeQL results to the Security tab + actions: read # Required by CodeQL to read the workflow run on private repos + + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + fetch-depth: 0 + persist-credentials: false + + - name: Environment check + uses: $/.github/actions/environment-check + + - name: CodeQL Scan + uses: $/.github/actions/analysis/codeql diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 47ae311..ddef925 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -27,12 +27,6 @@ jobs: security-events: write # Required to upload SARIF results to GitHub Security tab steps: - - name: Clean up previous run - env: - WORKSPACE: ${{ github.workspace }} - run: | - find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf {} + - - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -45,10 +39,10 @@ jobs: run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - name: Environment check - uses: ./.github/actions/environment-check + uses: $/.github/actions/environment-check - name: Coverity Scan - uses: ./.github/actions/analysis/coverity + uses: $/.github/actions/analysis/coverity env: COVERITY_TOKEN: ${{ secrets.COVERITY_TOKEN }} COVERITY_EMAIL: ${{ secrets.COVERITY_EMAIL }} diff --git a/.github/workflows/daily_build.yml b/.github/workflows/daily_build.yml index 69def9f..96927ad 100644 --- a/.github/workflows/daily_build.yml +++ b/.github/workflows/daily_build.yml @@ -27,13 +27,6 @@ jobs: security-events: write # Required to upload SARIF results to GitHub Security tab steps: - - name: Clean up previous run - env: - WORKSPACE: ${{ github.workspace }} - run: | - echo "Cleaning up previous run artifacts" - find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf {} + - - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -42,31 +35,34 @@ jobs: persist-credentials: false - name: Environment check - uses: ./.github/actions/environment-check + uses: $/.github/actions/environment-check - name: Build - uses: ./.github/actions/build-dvledtx + uses: $/.github/actions/build-dvledtx - name: Smoke test - uses: ./.github/actions/smoke-tests + uses: $/.github/actions/smoke-tests - name: Unit tests - uses: ./.github/actions/unit-tests + uses: $/.github/actions/unit-tests - name: ShellCheck - uses: ./.github/actions/analysis/shellcheck + uses: $/.github/actions/analysis/shellcheck - name: zizmor Scan - uses: ./.github/actions/analysis/zizmor + uses: $/.github/actions/analysis/zizmor - name: cppcheck - uses: ./.github/actions/analysis/cppcheck + uses: $/.github/actions/analysis/cppcheck - name: Trivy Scan - uses: ./.github/actions/analysis/trivy + uses: $/.github/actions/analysis/trivy - name: checksec Analysis - uses: ./.github/actions/analysis/checksec + uses: $/.github/actions/analysis/checksec + + - name: Gitleaks Scan + uses: $/.github/actions/analysis/gitleaks - name: Upload daily build reports uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -93,7 +89,7 @@ jobs: persist-credentials: false - name: AFL Fuzz - uses: ./.github/actions/analysis/afl-fuzz + uses: $/.github/actions/analysis/afl-fuzz with: max-seconds: '7200' @@ -123,7 +119,7 @@ jobs: persist-credentials: false - name: libFuzzer - uses: ./.github/actions/analysis/libfuzzer + uses: $/.github/actions/analysis/libfuzzer with: max-seconds: '3600' diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e663467..2d5abad 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -30,12 +30,6 @@ jobs: security-events: write # Required to upload SARIF results to GitHub Security tab steps: - - name: Clean up previous run - env: - WORKSPACE: ${{ github.workspace }} - run: | - find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf {} + - - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -44,25 +38,28 @@ jobs: persist-credentials: false - name: Environment check - uses: ./.github/actions/environment-check + uses: $/.github/actions/environment-check - name: Build - uses: ./.github/actions/build-dvledtx + uses: $/.github/actions/build-dvledtx - name: Smoke test - uses: ./.github/actions/smoke-tests + uses: $/.github/actions/smoke-tests - name: Unit tests - uses: ./.github/actions/unit-tests + uses: $/.github/actions/unit-tests - name: ShellCheck - uses: ./.github/actions/analysis/shellcheck + uses: $/.github/actions/analysis/shellcheck - name: zizmor Scan - uses: ./.github/actions/analysis/zizmor + uses: $/.github/actions/analysis/zizmor - name: cppcheck - uses: ./.github/actions/analysis/cppcheck + uses: $/.github/actions/analysis/cppcheck + + - name: Gitleaks Scan + uses: $/.github/actions/analysis/gitleaks - name: Upload PR reports uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/.github/workflows/scan_on_demand.yml b/.github/workflows/scan_on_demand.yml deleted file mode 100644 index 0838625..0000000 --- a/.github/workflows/scan_on_demand.yml +++ /dev/null @@ -1,146 +0,0 @@ -# -# BSD 3-Clause License -# Copyright (C) 2026 Intel Corporation -# SPDX-License-Identifier: BSD-3-Clause -# -name: Scan On Demand - -on: - workflow_dispatch: - inputs: - branch: - description: 'Branch to scan' - required: true - default: 'main' - -permissions: {} - -concurrency: - group: ${{ github.workflow }}-${{ inputs.branch }} - cancel-in-progress: true - -jobs: - scan: - name: Scan On Demand - runs-on: ubuntu-latest - permissions: - contents: read - security-events: write # Required to upload SARIF results to GitHub Security tab - - steps: - - name: Clean up previous run - env: - WORKSPACE: ${{ github.workspace }} - run: | - find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf {} + - rm -rf /tmp/trivy-* - - - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ inputs.branch }} - fetch-depth: 0 - persist-credentials: false - - - name: Collect scan metadata - env: - TRIGGERED_BY: ${{ github.actor }} - RUN_ID: ${{ github.run_id }} - RUN_NUMBER: ${{ github.run_number }} - WORKFLOW: ${{ github.workflow }} - SERVER_URL: ${{ github.server_url }} - REPOSITORY: ${{ github.repository }} - INPUT_BRANCH: ${{ inputs.branch }} - run: | - mkdir -p "$GITHUB_WORKSPACE/reports" - REPORT="$GITHUB_WORKSPACE/reports/scan-metadata.txt" - { - echo "==================================================" - echo " Scan On Demand — Run Metadata" - echo "==================================================" - echo "" - echo "--- Trigger ---" - echo "Triggered by : $TRIGGERED_BY" - echo "Trigger event : workflow_dispatch" - echo "Run ID : $RUN_ID" - echo "Run number : $RUN_NUMBER" - echo "Workflow : $WORKFLOW" - echo "Run URL : $SERVER_URL/$REPOSITORY/actions/runs/$RUN_ID" - echo "Triggered at : $(date -u '+%Y-%m-%d %H:%M:%S UTC')" - echo "" - echo "--- Actor git identity (from GitHub) ---" - GIT_NAME=$(git log -1 --format="%an" 2>/dev/null || echo "n/a") - GIT_EMAIL=$(git log -1 --format="%ae" 2>/dev/null || echo "n/a") - echo "Committer name : $GIT_NAME" - echo "Committer email: $GIT_EMAIL" - echo "" - echo "--- Repository ---" - echo "Repository : $REPOSITORY" - echo "Scanned branch : $INPUT_BRANCH" - echo "" - echo "--- Git HEAD ---" - echo "Commit SHA : $(git rev-parse HEAD)" - echo "Short SHA : $(git rev-parse --short HEAD)" - echo "Branch/ref : $(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse HEAD)" - echo "Commit subject : $(git log -1 --format='%s')" - echo "Commit author : $(git log -1 --format='%an <%ae>')" - echo "Commit date : $(git log -1 --format='%cd' --date=format:'%Y-%m-%d %H:%M:%S UTC')" - echo "Commit body :" - git log -1 --format='%b' | sed 's/^/ /' - echo "" - echo "--- Recent commits (last 5) ---" - git log -5 --format=" %h %cd %an %s" --date=format:'%Y-%m-%d %H:%M' - echo "" - echo "--- Working tree status ---" - git status --short || true - echo "" - echo "--- Tags at HEAD (if any) ---" - git tag --points-at HEAD 2>/dev/null || echo " (none)" - echo "" - echo "==================================================" - } > "$REPORT" - echo "Scan metadata written to $REPORT" - cat "$REPORT" - - - name: ShellCheck - uses: ./.github/actions/analysis/shellcheck - - - name: zizmor Scan - uses: ./.github/actions/analysis/zizmor - - - name: cppcheck - uses: ./.github/actions/analysis/cppcheck - - - name: Trivy Scan - uses: ./.github/actions/analysis/trivy - - - name: Coverity Scan - uses: ./.github/actions/analysis/coverity - env: - COVERITY_TOKEN: ${{ secrets.COVERITY_TOKEN }} - COVERITY_EMAIL: ${{ secrets.COVERITY_EMAIL }} - - - name: Upload SARIF to Security tab - uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 - if: always() - with: - sarif_file: reports/coverity-results.sarif - category: coverity - - - name: AFL Fuzz - uses: ./.github/actions/analysis/afl-fuzz - with: - max-seconds: '300' - - - name: libFuzzer - uses: ./.github/actions/analysis/libfuzzer - with: - max-seconds: '300' - - - name: Upload scan reports - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: always() - with: - name: DVLED-SW-TK-ScanOnDemand-${{ inputs.branch }}-${{ github.run_id }} - path: ${{ github.workspace }}/reports/ - retention-days: 30