From 4f9abdbf6e8da111872fe8ec77af7fda497a4326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:39:21 +0100 Subject: [PATCH 1/3] ci: add zizmor workflow audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Runs zizmor over this repository's workflows and Dependabot config on every pull request, on pushes to the default branch and weekly, through owncloud/reusable-workflows' zizmor.yml. Any finding fails the check. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- .github/workflows/zizmor.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 00000000000..ae9fff68443 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,30 @@ +name: Zizmor + +on: + push: + branches: + - master + pull_request: + types: + - opened + - synchronize + - reopened + schedule: + # Weekly: online audits (known-vulnerable actions, impostor commits) can + # start failing without a code change. + - cron: '0 4 * * 1' + workflow_dispatch: + +permissions: + contents: read + +# Grouped per event, so a push to the default branch can never cancel or +# displace the weekly run; only pull request runs cancel superseded ones. +concurrency: + group: zizmor-${{ github.event_name }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + zizmor: + name: Zizmor + uses: owncloud/reusable-workflows/.github/workflows/zizmor.yml@main From ffd5f93424a8488d12c7330e7c62a268eb4dfeb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:39:22 +0100 Subject: [PATCH 2/3] fix(ci): resolve zizmor findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - template-injection: build-apk passes the build_variant input to its scripts through env: instead of expanding it into the script text. - github-app: the SBOM App token requests only contents and pull-requests write, which peter-evans/create-pull-request needs to push the signed branch and open the PR, instead of inheriting every permission of the installation. - artipacked: checkouts do not persist credentials. No job runs an authenticated git operation after checkout; the SBOM PR is pushed by create-pull-request with the App token. - dependabot-cooldown: gradle updates wait 7 days, as github-actions already does. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- .github/dependabot.yml | 2 ++ .../android-instrumented-data-tests.yml | 2 ++ .github/workflows/android-unit-tests.yml | 2 ++ .github/workflows/build-apk.yml | 17 ++++++++++++----- .github/workflows/detekt.yml | 2 ++ .github/workflows/gradle-wrapper-validation.yml | 2 ++ .github/workflows/sbom.yml | 2 ++ .github/workflows/validate-source-strings.yml | 2 ++ 8 files changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e60ebf95b1d..48db275864f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -23,6 +23,8 @@ updates: day: wednesday time: '22:00' timezone: Etc/UTC + cooldown: + default-days: 7 open-pull-requests-limit: 5 groups: minor-and-patch: diff --git a/.github/workflows/android-instrumented-data-tests.yml b/.github/workflows/android-instrumented-data-tests.yml index 37ccf75039f..be775168316 100644 --- a/.github/workflows/android-instrumented-data-tests.yml +++ b/.github/workflows/android-instrumented-data-tests.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1 + with: + persist-credentials: false - name: Set up JDK 17 uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad #v6.1.0 diff --git a/.github/workflows/android-unit-tests.yml b/.github/workflows/android-unit-tests.yml index 577fc7f4016..7528209f414 100644 --- a/.github/workflows/android-unit-tests.yml +++ b/.github/workflows/android-unit-tests.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1 + with: + persist-credentials: false - name: Set up JDK 17 uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad #v6.1.0 diff --git a/.github/workflows/build-apk.yml b/.github/workflows/build-apk.yml index 52d927de2b9..38d6dc61a3f 100644 --- a/.github/workflows/build-apk.yml +++ b/.github/workflows/build-apk.yml @@ -61,10 +61,12 @@ jobs: # Validate build variant (mainly for workflow_call usage) - name: Validate build variant run: | - case "${{ inputs.build_variant }}" in + case "${INPUTS_BUILD_VARIANT}" in originalDebug|originalRelease|mdmDebug|mdmRelease|qaDebug|qaRelease) ;; - *) echo "Invalid build_variant: ${{ inputs.build_variant }}" && exit 1 ;; + *) echo "Invalid build_variant: ${INPUTS_BUILD_VARIANT}" && exit 1 ;; esac + env: + INPUTS_BUILD_VARIANT: ${{ inputs.build_variant }} # Checkout the repo - name: Checkout current repo @@ -72,6 +74,7 @@ jobs: with: repository: owncloud/android ref: ${{ inputs.version }} + persist-credentials: false # Retrieve and expose the app commit hash as a workflow output - name: Get commit hash @@ -101,7 +104,9 @@ jobs: # Build the apk with the given variant - name: Build APK - run: ./gradlew clean assemble${{ inputs.build_variant }} + run: ./gradlew clean assemble${INPUTS_BUILD_VARIANT} + env: + INPUTS_BUILD_VARIANT: ${{ inputs.build_variant }} # Name the output artifact with date, commit, and variant - name: Set artifact name @@ -109,12 +114,12 @@ jobs: run: | DATE=$(date +%Y%m%d_%H%M) COMMIT=$(git rev-parse --short HEAD) - VARIANT="${{ inputs.build_variant }}" + VARIANT="${INPUTS_BUILD_VARIANT}" # Extract flavor and build type from variant (e.g. qaRelease -> qa / release) FLAVOR=$(echo "$VARIANT" | sed -E 's/(Release|Debug)//' | tr '[:upper:]' '[:lower:]') BUILD_TYPE=$(echo "$VARIANT" | grep -qi debug && echo debug || echo release) - NAME="ownCloud-${{ inputs.build_variant }}-${COMMIT}-${DATE}.apk" + NAME="ownCloud-${INPUTS_BUILD_VARIANT}-${COMMIT}-${DATE}.apk" APK_PATH=$(find ./owncloudApp/build/outputs/apk/$FLAVOR/$BUILD_TYPE/ -name "*.apk") @@ -131,6 +136,8 @@ jobs: # Publish as output echo "artifact_name=$NAME" >> $GITHUB_OUTPUT + env: + INPUTS_BUILD_VARIANT: ${{ inputs.build_variant }} # Publish the artifact - name: Upload artifact diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml index dc5e9b2ea73..1b9ce18c4e1 100644 --- a/.github/workflows/detekt.yml +++ b/.github/workflows/detekt.yml @@ -23,6 +23,8 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1 + with: + persist-credentials: false - name: Set up JDK 17 uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad #v6.1.0 with: diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index ec0878d556e..d58ac9eadba 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -10,6 +10,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1 + with: + persist-credentials: false - uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 #v6.4.0 with: validate-wrappers: true diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index 7dc92124afe..09fa64fc841 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -120,6 +120,8 @@ jobs: with: app-id: ${{ secrets.SBOM_APP_ID }} private-key: ${{ secrets.SBOM_APP_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write # Create a branch with latest SBOM changes only if there are changes - name: Create or update SBOM PR diff --git a/.github/workflows/validate-source-strings.yml b/.github/workflows/validate-source-strings.yml index bd20a04ff67..ddadaee8071 100644 --- a/.github/workflows/validate-source-strings.yml +++ b/.github/workflows/validate-source-strings.yml @@ -14,6 +14,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1 + with: + persist-credentials: false - name: Install xmlstarlet run: sudo apt-get update && sudo apt-get install -y xmlstarlet From 181a53d12c3c9ebee3cd65466794338072ecd790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <323649642+oc-tmueller@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:40:47 +0100 Subject: [PATCH 3/3] fix(ci): drop the unused contents write grant from the SBOM workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SBOM branch and PR are pushed and opened with the App token, and the remaining git calls are anonymous reads of this public repository, so the GITHUB_TOKEN no longer needs write access. The job runs third-party Gradle plugins, which could otherwise use it to push. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com> --- .github/workflows/sbom.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index 09fa64fc841..24e45521cc9 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -15,8 +15,9 @@ concurrency: group: sbom-update cancel-in-progress: false +# Everything that writes (the SBOM branch and PR) uses the App token below. permissions: - contents: write + contents: read jobs: sbom: