From a6a8f6b6d6775caa031e5016b79db28c6aaadfcb Mon Sep 17 00:00:00 2001 From: bashonly <88596187+bashonly@users.noreply.github.com> Date: Fri, 19 Dec 2025 13:22:23 -0600 Subject: [PATCH] [ci] Explicitly declare permissions and limit credentials (#15324) Authored by: bashonly --- .github/workflows/build.yml | 28 ++++++++++++++++++-------- .github/workflows/cache-warmer.yml | 6 ++++-- .github/workflows/challenge-tests.yml | 8 ++++++-- .github/workflows/codeql.yml | 4 ++++ .github/workflows/core.yml | 7 +++++-- .github/workflows/download.yml | 12 +++++++++-- .github/workflows/issue-lockdown.yml | 5 +++-- .github/workflows/quick-test.yml | 12 +++++++++-- .github/workflows/release-master.yml | 12 +++++------ .github/workflows/release-nightly.yml | 15 ++++++++------ .github/workflows/release.yml | 16 ++++++++------- .github/workflows/sanitize-comment.yml | 5 +++-- .github/workflows/test-workflows.yml | 9 +++++++-- 13 files changed, 96 insertions(+), 43 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 818280d00e..b5033341ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,8 +74,7 @@ on: default: true type: boolean -permissions: - contents: read +permissions: {} jobs: process: @@ -186,8 +185,10 @@ jobs: f.write(f'matrix={json.dumps(matrix)}') unix: - needs: process + needs: [process] if: inputs.unix + permissions: + contents: read runs-on: ubuntu-latest env: CHANNEL: ${{ inputs.channel }} @@ -199,6 +200,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 # Needed for changelog + persist-credentials: false - uses: actions/setup-python@v6 with: @@ -239,8 +241,10 @@ jobs: linux: name: ${{ matrix.os }} (${{ matrix.arch }}) + needs: [process] if: inputs.linux || inputs.linux_armv7l || inputs.musllinux - needs: process + permissions: + contents: read runs-on: ${{ matrix.runner }} strategy: fail-fast: false @@ -258,6 +262,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Cache requirements if: matrix.cache_requirements @@ -308,7 +314,7 @@ jobs: compression-level: 0 macos: - needs: process + needs: [process] if: inputs.macos permissions: contents: read @@ -321,6 +327,9 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + # NB: Building universal2 does not work with python from actions/setup-python - name: Cache requirements @@ -409,7 +418,7 @@ jobs: windows: name: windows (${{ matrix.arch }}) - needs: process + needs: [process] if: inputs.windows permissions: contents: read @@ -451,6 +460,9 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python_version }} @@ -528,13 +540,13 @@ jobs: compression-level: 0 meta_files: - if: always() && !cancelled() needs: - process - unix - linux - macos - windows + if: always() && !failure() && !cancelled() runs-on: ubuntu-latest steps: - name: Download artifacts @@ -600,7 +612,7 @@ jobs: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} if: env.GPG_SIGNING_KEY run: | - gpg --batch --import <<< "${{ secrets.GPG_SIGNING_KEY }}" + gpg --batch --import <<< "${GPG_SIGNING_KEY}" for signfile in ./SHA*SUMS; do gpg --batch --detach-sign "$signfile" done diff --git a/.github/workflows/cache-warmer.yml b/.github/workflows/cache-warmer.yml index 00ec1e1f96..4a5589c7a2 100644 --- a/.github/workflows/cache-warmer.yml +++ b/.github/workflows/cache-warmer.yml @@ -4,10 +4,14 @@ on: schedule: - cron: '0 22 1,6,11,16,21,27 * *' +permissions: {} + jobs: build: if: | vars.KEEP_CACHE_WARM || github.event_name == 'workflow_dispatch' + permissions: + contents: read uses: ./.github/workflows/build.yml with: version: '999999' @@ -19,5 +23,3 @@ jobs: musllinux: false macos: true windows: true - permissions: - contents: read diff --git a/.github/workflows/challenge-tests.yml b/.github/workflows/challenge-tests.yml index 68fe117191..fa684e6644 100644 --- a/.github/workflows/challenge-tests.yml +++ b/.github/workflows/challenge-tests.yml @@ -16,8 +16,8 @@ on: - yt_dlp/extractor/youtube/jsc/**.py - yt_dlp/extractor/youtube/pot/**.py - yt_dlp/utils/_jsruntime.py -permissions: - contents: read + +permissions: {} concurrency: group: challenge-tests-${{ github.event.pull_request.number || github.ref }} @@ -26,6 +26,8 @@ concurrency: jobs: tests: name: Challenge Tests + permissions: + contents: read runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -36,6 +38,8 @@ jobs: QJS_VERSION: '2025-04-26' # Earliest version with rope strings steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fda5351c08..5d0d06e095 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -9,6 +9,8 @@ on: schedule: - cron: '59 11 * * 5' +permissions: {} + jobs: analyze: name: Analyze (${{ matrix.language }}) @@ -26,6 +28,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 + with: + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@v4 diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 16c2b92b40..3ac9495cea 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -22,8 +22,8 @@ on: - yt_dlp/extractor/__init__.py - yt_dlp/extractor/common.py - yt_dlp/extractor/extractors.py -permissions: - contents: read + +permissions: {} concurrency: group: core-${{ github.event.pull_request.number || github.ref }} @@ -33,6 +33,8 @@ jobs: tests: name: Core Tests if: "!contains(github.event.head_commit.message, 'ci skip')" + permissions: + contents: read runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -58,6 +60,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: diff --git a/.github/workflows/download.yml b/.github/workflows/download.yml index 62a2cf9ba0..e9c4d75a71 100644 --- a/.github/workflows/download.yml +++ b/.github/workflows/download.yml @@ -1,15 +1,19 @@ name: Download Tests on: [push, pull_request] -permissions: - contents: read + +permissions: {} jobs: quick: name: Quick Download Tests if: "contains(github.event.head_commit.message, 'ci run dl')" + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v6 with: @@ -23,6 +27,8 @@ jobs: full: name: Full Download Tests if: "contains(github.event.head_commit.message, 'ci run dl all')" + permissions: + contents: read runs-on: ${{ matrix.os }} strategy: fail-fast: true @@ -37,6 +43,8 @@ jobs: python-version: pypy-3.11 steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: diff --git a/.github/workflows/issue-lockdown.yml b/.github/workflows/issue-lockdown.yml index 4b973e2e61..100b9f93f2 100644 --- a/.github/workflows/issue-lockdown.yml +++ b/.github/workflows/issue-lockdown.yml @@ -3,13 +3,14 @@ on: issues: types: [opened] -permissions: - issues: write +permissions: {} jobs: lockdown: name: Issue Lockdown if: vars.ISSUE_LOCKDOWN + permissions: + issues: write runs-on: ubuntu-latest steps: - name: "Lock new issue" diff --git a/.github/workflows/quick-test.yml b/.github/workflows/quick-test.yml index f72f6a5651..410bf3520f 100644 --- a/.github/workflows/quick-test.yml +++ b/.github/workflows/quick-test.yml @@ -1,15 +1,19 @@ name: Quick Test on: [push, pull_request] -permissions: - contents: read + +permissions: {} jobs: tests: name: Core Test if: "!contains(github.event.head_commit.message, 'ci skip all')" + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python 3.10 uses: actions/setup-python@v6 with: @@ -24,9 +28,13 @@ jobs: check: name: Code check if: "!contains(github.event.head_commit.message, 'ci skip all')" + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-python@v6 with: python-version: '3.10' diff --git a/.github/workflows/release-master.yml b/.github/workflows/release-master.yml index d13a6d2da1..0e7478e452 100644 --- a/.github/workflows/release-master.yml +++ b/.github/workflows/release-master.yml @@ -14,28 +14,28 @@ on: - ".github/workflows/release-master.yml" concurrency: group: release-master -permissions: - contents: read + +permissions: {} jobs: release: if: vars.BUILD_MASTER + permissions: + contents: write + id-token: write # mandatory for trusted publishing uses: ./.github/workflows/release.yml with: prerelease: true source: ${{ (github.repository != 'yt-dlp/yt-dlp' && vars.MASTER_ARCHIVE_REPO) || 'master' }} target: 'master' - permissions: - contents: write - id-token: write # mandatory for trusted publishing secrets: inherit publish_pypi: needs: [release] if: vars.MASTER_PYPI_PROJECT - runs-on: ubuntu-latest permissions: id-token: write # mandatory for trusted publishing + runs-on: ubuntu-latest steps: - name: Download artifacts uses: actions/download-artifact@v7 diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index f4e806a219..e0b7a3729c 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -2,12 +2,14 @@ name: Release (nightly) on: schedule: - cron: '23 23 * * *' -permissions: - contents: read + +permissions: {} jobs: check_nightly: if: vars.BUILD_NIGHTLY + permissions: + contents: read runs-on: ubuntu-latest outputs: commit: ${{ steps.check_for_new_commits.outputs.commit }} @@ -15,6 +17,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - name: Check for new commits id: check_for_new_commits run: | @@ -35,22 +38,22 @@ jobs: release: needs: [check_nightly] if: ${{ needs.check_nightly.outputs.commit }} + permissions: + contents: write + id-token: write # mandatory for trusted publishing uses: ./.github/workflows/release.yml with: prerelease: true source: ${{ (github.repository != 'yt-dlp/yt-dlp' && vars.NIGHTLY_ARCHIVE_REPO) || 'nightly' }} target: 'nightly' - permissions: - contents: write - id-token: write # mandatory for trusted publishing secrets: inherit publish_pypi: needs: [release] if: vars.NIGHTLY_PYPI_PROJECT - runs-on: ubuntu-latest permissions: id-token: write # mandatory for trusted publishing + runs-on: ubuntu-latest steps: - name: Download artifacts uses: actions/download-artifact@v7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b99ff4bfd0..e06bd09f0d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,8 +56,7 @@ on: default: false type: boolean -permissions: - contents: read +permissions: {} jobs: prepare: @@ -150,29 +149,31 @@ jobs: run: git push origin "${GITHUB_EVENT_REF}" build: - needs: prepare + needs: [prepare] + permissions: + contents: read uses: ./.github/workflows/build.yml with: version: ${{ needs.prepare.outputs.version }} channel: ${{ needs.prepare.outputs.channel }} origin: ${{ needs.prepare.outputs.target_repo }} linux_armv7l: ${{ inputs.linux_armv7l }} - permissions: - contents: read secrets: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} publish_pypi: needs: [prepare, build] if: ${{ needs.prepare.outputs.pypi_project }} - runs-on: ubuntu-latest permissions: + contents: read id-token: write # mandatory for trusted publishing + runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: - fetch-depth: 0 + fetch-depth: 0 # Needed for changelog + persist-credentials: false - uses: actions/setup-python@v6 with: python-version: "3.10" @@ -236,6 +237,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - uses: actions/download-artifact@v7 with: path: artifact diff --git a/.github/workflows/sanitize-comment.yml b/.github/workflows/sanitize-comment.yml index 45c87cdd47..a14c5a8eb0 100644 --- a/.github/workflows/sanitize-comment.yml +++ b/.github/workflows/sanitize-comment.yml @@ -4,13 +4,14 @@ on: issue_comment: types: [created, edited] -permissions: - issues: write +permissions: {} jobs: sanitize-comment: name: Sanitize comment if: vars.SANITIZE_COMMENT && !github.event.issue.pull_request + permissions: + issues: write runs-on: ubuntu-latest steps: - name: Sanitize comment diff --git a/.github/workflows/test-workflows.yml b/.github/workflows/test-workflows.yml index e1a125461a..f82ce5b91a 100644 --- a/.github/workflows/test-workflows.yml +++ b/.github/workflows/test-workflows.yml @@ -14,8 +14,9 @@ on: - devscripts/setup_variables.py - devscripts/setup_variables_tests.py - devscripts/utils.py -permissions: - contents: read + +permissions: {} + env: ACTIONLINT_VERSION: "1.7.9" ACTIONLINT_SHA256SUM: 233b280d05e100837f4af1433c7b40a5dcb306e3aa68fb4f17f8a7f45a7df7b4 @@ -24,9 +25,13 @@ env: jobs: check: name: Check workflows + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-python@v6 with: python-version: "3.10" # Keep this in sync with release.yml's prepare job