threads / patch / 66647

patchci: pin actions in the main workflow to full commit IDs

Subject: [PATCH] ci: pin actions in the main workflow to full commit IDs

## tl;dr

Taylor Blau's patch would let the main workflow run under organization policies that require full commit IDs, but Junio C Hamano doubts the project should carry that for forks. Read the story.

replies: 6people: 3as markdown or json

Taylor Blau· Oct 23, 2026, 16:38 UTC · lore

Some forks are hosted by organizations that restrict which GitHub Actions may run, including requiring actions to be pinned to full commit IDs. Our main CI workflow refers to actions by version tags or branches, which prevents it from running under such a policy.

Pin those actions to full commit IDs, retaining the version names in comments to make future updates easier to review.

Signed-off-by: Taylor Blau <ttaylorr@openai.com>
---
This is based on a merge of 'ps/ci-housekeeping-and-modernizations'
and 'jk/http-curl-strip-creds'. The latter is needed for the HTTP
auth tests to pass with the curl versions in current CI.
 .github/workflows/main.yml | 64 +++++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 32 deletions(-)
Show changes to .github/workflows/main.yml +32 −33
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index fe8155772ab..ba0b5ffb634 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -65,7 +65,7 @@ jobs:
           echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT
       - name: skip if the commit or tree was already tested
         id: skip-if-redundant
-        uses: actions/github-script@v9
+        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
         if: steps.check-ref.outputs.enabled == 'yes'
         with:
           github-token: ${{secrets.GITHUB_TOKEN}}
@@ -114,8 +114,8 @@ jobs:
       group: windows-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: Install GCC-compatible Rust target
       shell: bash
       run: |
@@ -149,7 +149,7 @@ jobs:
     - name: zip up tracked files
       run: git archive -o artifacts/tracked.tar.gz HEAD
     - name: upload tracked files and build artifacts
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: windows-artifacts
         path: artifacts
@@ -166,14 +166,14 @@ jobs:
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
     - name: download tracked files and build artifacts
-      uses: actions/download-artifact@v8
+      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
       with:
         name: windows-artifacts
         path: ${{github.workspace}}
     - name: extract tracked files and build artifacts
       shell: bash
       run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: test
       shell: bash
       run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10
@@ -183,7 +183,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-windows-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -199,20 +199,20 @@ jobs:
       group: vs-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: initialize vcpkg
-      uses: actions/checkout@v6
+      uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
       with:
         repository: 'microsoft/vcpkg'
         path: 'compat/vcbuild/vcpkg'
     - name: download vcpkg artifacts
-      uses: git-for-windows/get-azure-pipelines-artifact@v0
+      uses: git-for-windows/get-azure-pipelines-artifact@2e424b98e1251b725d6064c5f1a9f854a33e5b88 # v0
       with:
         repository: git/git
         definitionId: 9
     - name: add msbuild to PATH
-      uses: microsoft/setup-msbuild@v3
+      uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3
     - name: copy dlls to root
       shell: cmd
       run: compat\vcbuild\vcpkg_copy_dlls.bat release
@@ -234,7 +234,7 @@ jobs:
     - name: zip up tracked files
       run: git archive -o artifacts/tracked.tar.gz HEAD
     - name: upload tracked files and build artifacts
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: vs-artifacts
         path: artifacts
@@ -250,9 +250,9 @@ jobs:
       group: vs-test-${{ matrix.nr }}-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: download tracked files and build artifacts
-      uses: actions/download-artifact@v8
+      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
       with:
         name: vs-artifacts
         path: ${{github.workspace}}
@@ -270,7 +270,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-windows-vs-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -284,8 +284,8 @@ jobs:
       group: windows-meson-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: actions/setup-python@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
     - name: Set up dependencies
       shell: pwsh
       run: pip install meson ninja
@@ -296,7 +296,7 @@ jobs:
       shell: pwsh
       run: meson compile -C build
     - name: Upload build artifacts
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: windows-meson-artifacts
         path: build
@@ -312,13 +312,13 @@ jobs:
       group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: actions/setup-python@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
     - name: Set up dependencies
       shell: pwsh
       run: pip install meson ninja
     - name: Download build artifacts
-      uses: actions/download-artifact@v8
+      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
       with:
         name: windows-meson-artifacts
         path: build
@@ -331,7 +331,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-windows-meson-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -367,7 +367,7 @@ jobs:
       TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t
     runs-on: ${{matrix.vector.pool}}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-build-and-tests.sh
     - name: print test failures
@@ -375,7 +375,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -388,7 +388,7 @@ jobs:
       CI_JOB_IMAGE: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-build-and-minimal-fuzzers.sh
   dockerized:
@@ -464,7 +464,7 @@ jobs:
         else
           apt-get -q update && apt-get -q -y install git
         fi
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: useradd builder --create-home
     - run: chown -R builder .
@@ -474,7 +474,7 @@ jobs:
       run: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -489,7 +489,7 @@ jobs:
       group: static-analysis-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-static-analysis.sh
     - run: ci/check-directional-formatting.bash
@@ -505,7 +505,7 @@ jobs:
       group: rust-analysis-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-rust-checks.sh
   sparse:
@@ -519,7 +519,7 @@ jobs:
       group: sparse-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - name: Install other dependencies
       run: ci/install-dependencies.sh
     - run: make sparse
@@ -535,6 +535,6 @@ jobs:
       CI_JOB_IMAGE: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/test-documentation.sh

base-commit: d46921825429c74931372567941eaf98d4483210
--
2.56.0.187.g9e9ae442333
Ben Knoble· Oct 23, 2026, 18:05 UTC · re: Taylor Blau · lore

Re: [PATCH] ci: pin actions in the main workflow to full commit IDs

Show 6 quoted lines
> Le 23 oct. 2026 à 12:41, Taylor Blau <ttaylorr@openai.com> a écrit :
> 
> Some forks are hosted by organizations that restrict which GitHub
> Actions may run, including requiring actions to be pinned to full
> commit IDs. Our main CI workflow refers to actions by version tags or
> branches, which prevents it from running under such a policy.
Yep. This is becoming de facto security standard.

Perhaps we should say so? « Pinned commit IDs prevent attacks on CI and any secrets stored therein by compromised action suppliers » or something?

Show 258 quoted lines
> Pin those actions to full commit IDs, retaining the version names in
> comments to make future updates easier to review.
> 
> Signed-off-by: Taylor Blau <ttaylorr@openai.com>
> ---
> This is based on a merge of 'ps/ci-housekeeping-and-modernizations'
> and 'jk/http-curl-strip-creds'. The latter is needed for the HTTP
> auth tests to pass with the curl versions in current CI.
> 
> .github/workflows/main.yml | 64 +++++++++++++++++++-------------------
> 1 file changed, 32 insertions(+), 32 deletions(-)
> 
> diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
> index fe8155772ab..ba0b5ffb634 100644
> --- a/.github/workflows/main.yml
> +++ b/.github/workflows/main.yml
> @@ -65,7 +65,7 @@ jobs:
>           echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT
>       - name: skip if the commit or tree was already tested
>         id: skip-if-redundant
> -        uses: actions/github-script@v9
> +        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
>         if: steps.check-ref.outputs.enabled == 'yes'
>         with:
>           github-token: ${{secrets.GITHUB_TOKEN}}
> @@ -114,8 +114,8 @@ jobs:
>       group: windows-build-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> -    - uses: git-for-windows/setup-git-for-windows-sdk@v2
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
> +    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
>     - name: Install GCC-compatible Rust target
>       shell: bash
>       run: |
> @@ -149,7 +149,7 @@ jobs:
>     - name: zip up tracked files
>       run: git archive -o artifacts/tracked.tar.gz HEAD
>     - name: upload tracked files and build artifacts
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: windows-artifacts
>         path: artifacts
> @@ -166,14 +166,14 @@ jobs:
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
>     - name: download tracked files and build artifacts
> -      uses: actions/download-artifact@v8
> +      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
>       with:
>         name: windows-artifacts
>         path: ${{github.workspace}}
>     - name: extract tracked files and build artifacts
>       shell: bash
>       run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz
> -    - uses: git-for-windows/setup-git-for-windows-sdk@v2
> +    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
>     - name: test
>       shell: bash
>       run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10
> @@ -183,7 +183,7 @@ jobs:
>       run: ci/print-test-failures.sh
>     - name: Upload failed tests' directories
>       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: failed-tests-windows-${{ matrix.nr }}
>         path: ${{env.FAILED_TEST_ARTIFACTS}}
> @@ -199,20 +199,20 @@ jobs:
>       group: vs-build-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> -    - uses: git-for-windows/setup-git-for-windows-sdk@v2
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
> +    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
>     - name: initialize vcpkg
> -      uses: actions/checkout@v6
> +      uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>       with:
>         repository: 'microsoft/vcpkg'
>         path: 'compat/vcbuild/vcpkg'
>     - name: download vcpkg artifacts
> -      uses: git-for-windows/get-azure-pipelines-artifact@v0
> +      uses: git-for-windows/get-azure-pipelines-artifact@2e424b98e1251b725d6064c5f1a9f854a33e5b88 # v0
>       with:
>         repository: git/git
>         definitionId: 9
>     - name: add msbuild to PATH
> -      uses: microsoft/setup-msbuild@v3
> +      uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3
>     - name: copy dlls to root
>       shell: cmd
>       run: compat\vcbuild\vcpkg_copy_dlls.bat release
> @@ -234,7 +234,7 @@ jobs:
>     - name: zip up tracked files
>       run: git archive -o artifacts/tracked.tar.gz HEAD
>     - name: upload tracked files and build artifacts
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: vs-artifacts
>         path: artifacts
> @@ -250,9 +250,9 @@ jobs:
>       group: vs-test-${{ matrix.nr }}-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: git-for-windows/setup-git-for-windows-sdk@v2
> +    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
>     - name: download tracked files and build artifacts
> -      uses: actions/download-artifact@v8
> +      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
>       with:
>         name: vs-artifacts
>         path: ${{github.workspace}}
> @@ -270,7 +270,7 @@ jobs:
>       run: ci/print-test-failures.sh
>     - name: Upload failed tests' directories
>       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: failed-tests-windows-vs-${{ matrix.nr }}
>         path: ${{env.FAILED_TEST_ARTIFACTS}}
> @@ -284,8 +284,8 @@ jobs:
>       group: windows-meson-build-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> -    - uses: actions/setup-python@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
> +    - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
>     - name: Set up dependencies
>       shell: pwsh
>       run: pip install meson ninja
> @@ -296,7 +296,7 @@ jobs:
>       shell: pwsh
>       run: meson compile -C build
>     - name: Upload build artifacts
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: windows-meson-artifacts
>         path: build
> @@ -312,13 +312,13 @@ jobs:
>       group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> -    - uses: actions/setup-python@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
> +    - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
>     - name: Set up dependencies
>       shell: pwsh
>       run: pip install meson ninja
>     - name: Download build artifacts
> -      uses: actions/download-artifact@v8
> +      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
>       with:
>         name: windows-meson-artifacts
>         path: build
> @@ -331,7 +331,7 @@ jobs:
>       run: ci/print-test-failures.sh
>     - name: Upload failed tests' directories
>       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: failed-tests-windows-meson-${{ matrix.nr }}
>         path: ${{env.FAILED_TEST_ARTIFACTS}}
> @@ -367,7 +367,7 @@ jobs:
>       TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t
>     runs-on: ${{matrix.vector.pool}}
>     steps:
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - run: ci/install-dependencies.sh
>     - run: ci/run-build-and-tests.sh
>     - name: print test failures
> @@ -375,7 +375,7 @@ jobs:
>       run: ci/print-test-failures.sh
>     - name: Upload failed tests' directories
>       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: failed-tests-${{matrix.vector.jobname}}
>         path: ${{env.FAILED_TEST_ARTIFACTS}}
> @@ -388,7 +388,7 @@ jobs:
>       CI_JOB_IMAGE: ubuntu-latest
>     runs-on: ubuntu-latest
>     steps:
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - run: ci/install-dependencies.sh
>     - run: ci/run-build-and-minimal-fuzzers.sh
>   dockerized:
> @@ -464,7 +464,7 @@ jobs:
>         else
>           apt-get -q update && apt-get -q -y install git
>         fi
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - run: ci/install-dependencies.sh
>     - run: useradd builder --create-home
>     - run: chown -R builder .
> @@ -474,7 +474,7 @@ jobs:
>       run: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh
>     - name: Upload failed tests' directories
>       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
> -      uses: actions/upload-artifact@v7
> +      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
>       with:
>         name: failed-tests-${{matrix.vector.jobname}}
>         path: ${{env.FAILED_TEST_ARTIFACTS}}
> @@ -489,7 +489,7 @@ jobs:
>       group: static-analysis-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - run: ci/install-dependencies.sh
>     - run: ci/run-static-analysis.sh
>     - run: ci/check-directional-formatting.bash
> @@ -505,7 +505,7 @@ jobs:
>       group: rust-analysis-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - run: ci/install-dependencies.sh
>     - run: ci/run-rust-checks.sh
>   sparse:
> @@ -519,7 +519,7 @@ jobs:
>       group: sparse-${{ github.ref }}
>       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
>     steps:
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - name: Install other dependencies
>       run: ci/install-dependencies.sh
>     - run: make sparse
> @@ -535,6 +535,6 @@ jobs:
>       CI_JOB_IMAGE: ubuntu-latest
>     runs-on: ubuntu-latest
>     steps:
> -    - uses: actions/checkout@v6
> +    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
>     - run: ci/install-dependencies.sh
>     - run: ci/test-documentation.sh
> 
> base-commit: d46921825429c74931372567941eaf98d4483210
> --
> 2.56.0.187.g9e9ae442333
> 
Junio C Hamano· Oct 23, 2026, 21:45 UTC · re: Taylor Blau · lore

Re: [PATCH] ci: pin actions in the main workflow to full commit IDs

Taylor Blau <ttaylorr@openai.com> writes:
> Some forks are hosted by organizations that restrict which GitHub
> Actions may run, including requiring actions to be pinned to full
> commit IDs. Our main CI workflow refers to actions by version tags or
> branches, which prevents it from running under such a policy.

I do not see why the limitations of other organizations should affect our workflow here. What if another organization prefers readable and concise tag names? Would they send a patch to revert this change, leading to a "last one wins" situation?

Would it be too much trouble for organizations with this specific requirement to maintain such changes in their own forks? When we need to update a dependency (for example, when 'checkout@v6' is deprecated and we transition to 'checkout@v7'), it would result in a conflict anyway. At that point, someone has to translate the symbolic name to a full object name. It seems only fair that the organizations requiring this level of pinning handle that translation themselves, and the conflict will tell them exactly which line has the symbolic name that needs to be translated to a full object name.

Taylor Blau· Oct 24, 2026, 00:32 UTC · re: Junio C Hamano · lore

Re: [PATCH] ci: pin actions in the main workflow to full commit IDs

On Fri, Oct 23, 2026 at 02:45:01PM -0700, Junio C Hamano wrote:
Show 11 quoted lines
> Taylor Blau <ttaylorr@openai.com> writes:
>
> > Some forks are hosted by organizations that restrict which GitHub
> > Actions may run, including requiring actions to be pinned to full
> > commit IDs. Our main CI workflow refers to actions by version tags or
> > branches, which prevents it from running under such a policy.
>
> I do not see why the limitations of other organizations should
> affect our workflow here.  What if another organization prefers
> readable and concise tag names?  Would they send a patch to revert
> this change, leading to a "last one wins" situation?

I see what you're saying, but I think in this particular case there *is* a good reason to do this in your tree.

These actions are executable dependencies of our CI, so if a malicious actor points, say, checkout@v6 at something which modifies code in the tree, we are relying entirely on the permissions of CI's configured $GITHUB_TOKEN to save us from code injection.

There is maintenance involved, including deliberately picking up bug and security fixes within a major version. But using a tag does not eliminate the decision about which code to execute; it delegates that decision to whoever can update the tag. I think making those updates explicit in our repository is worth the maintenance.

Keeping a downstream patch is certainly possible. But having each fork repeat the same translation leaves the upstream workflow without that protection and duplicates the work. That is why I think this belongs upstream.

I think that we could reword the commit message to explain that benefit more clearly, but I do think this is the right policy.

> Would it be too much trouble for organizations with this specific
> requirement to maintain such changes in their own forks?

Just as a concrete example, before submitting patches out of openai/git, I apply this patch on top of my branch, then run CI, and then remove the extraneous commit before sending. This happens on every topic, and AFAICT this is not an uncommon restriction among other corporate organization accounts on GitHub.

Thanks, Taylor

Junio C Hamano· Oct 24, 2026, 01:38 UTC · re: Taylor Blau · lore

Re: [PATCH] ci: pin actions in the main workflow to full commit IDs

Taylor Blau <ttaylorr@openai.com> writes:
> I think that we could reword the commit message to explain that benefit
> more clearly, but I do think this is the right policy.

Together with Ben Knoble's comments, I very much appreciate your pushing back. I agree that a different justification would be a good way to go.

Thanks.
Taylor Blau· Oct 26, 2026, 18:08 UTC · re: Taylor Blau · lore

[PATCH v2] ci: pin actions in the main workflow to full commit IDs

Our main CI workflow refers to actions by version tags. These tags can move, changing the action code we run without any change to our repository. If an attacker gains access to an action's repository, they can move an existing tag to a malicious revision and have our workflow pick it up automatically.

Pin these actions to full commit IDs so that moving a tag cannot substitute a different action revision. Updating the actions will require an explicit change to our workflow, including when picking up bug fixes and security fixes within a major version.

Retain the version names in comments to keep the references readable and make future updates easier to review.

Signed-off-by: Taylor Blau <ttaylorr@openai.com>
---
 .github/workflows/main.yml | 64 +++++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 32 deletions(-)
Show changes to .github/workflows/main.yml +32 −32
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index fe8155772ab..ba0b5ffb634 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -65,7 +65,7 @@ jobs:
           echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT
       - name: skip if the commit or tree was already tested
         id: skip-if-redundant
-        uses: actions/github-script@v9
+        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
         if: steps.check-ref.outputs.enabled == 'yes'
         with:
           github-token: ${{secrets.GITHUB_TOKEN}}
@@ -114,8 +114,8 @@ jobs:
       group: windows-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: Install GCC-compatible Rust target
       shell: bash
       run: |
@@ -149,7 +149,7 @@ jobs:
     - name: zip up tracked files
       run: git archive -o artifacts/tracked.tar.gz HEAD
     - name: upload tracked files and build artifacts
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: windows-artifacts
         path: artifacts
@@ -166,14 +166,14 @@ jobs:
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
     - name: download tracked files and build artifacts
-      uses: actions/download-artifact@v8
+      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
       with:
         name: windows-artifacts
         path: ${{github.workspace}}
     - name: extract tracked files and build artifacts
       shell: bash
       run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: test
       shell: bash
       run: . /etc/profile && ci/run-test-slice.sh $((${{matrix.nr}} + 1)) 10
@@ -183,7 +183,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-windows-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -199,20 +199,20 @@ jobs:
       group: vs-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: initialize vcpkg
-      uses: actions/checkout@v6
+      uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
       with:
         repository: 'microsoft/vcpkg'
         path: 'compat/vcbuild/vcpkg'
     - name: download vcpkg artifacts
-      uses: git-for-windows/get-azure-pipelines-artifact@v0
+      uses: git-for-windows/get-azure-pipelines-artifact@2e424b98e1251b725d6064c5f1a9f854a33e5b88 # v0
       with:
         repository: git/git
         definitionId: 9
     - name: add msbuild to PATH
-      uses: microsoft/setup-msbuild@v3
+      uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3
     - name: copy dlls to root
       shell: cmd
       run: compat\vcbuild\vcpkg_copy_dlls.bat release
@@ -234,7 +234,7 @@ jobs:
     - name: zip up tracked files
       run: git archive -o artifacts/tracked.tar.gz HEAD
     - name: upload tracked files and build artifacts
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: vs-artifacts
         path: artifacts
@@ -250,9 +250,9 @@ jobs:
       group: vs-test-${{ matrix.nr }}-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: git-for-windows/setup-git-for-windows-sdk@v2
+    - uses: git-for-windows/setup-git-for-windows-sdk@aed153d1258c311b680b81584a72a1a4807401f0 # v2
     - name: download tracked files and build artifacts
-      uses: actions/download-artifact@v8
+      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
       with:
         name: vs-artifacts
         path: ${{github.workspace}}
@@ -270,7 +270,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-windows-vs-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -284,8 +284,8 @@ jobs:
       group: windows-meson-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: actions/setup-python@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
     - name: Set up dependencies
       shell: pwsh
       run: pip install meson ninja
@@ -296,7 +296,7 @@ jobs:
       shell: pwsh
       run: meson compile -C build
     - name: Upload build artifacts
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: windows-meson-artifacts
         path: build
@@ -312,13 +312,13 @@ jobs:
       group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
-    - uses: actions/setup-python@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
+    - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
     - name: Set up dependencies
       shell: pwsh
       run: pip install meson ninja
     - name: Download build artifacts
-      uses: actions/download-artifact@v8
+      uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
       with:
         name: windows-meson-artifacts
         path: build
@@ -331,7 +331,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-windows-meson-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -367,7 +367,7 @@ jobs:
       TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t
     runs-on: ${{matrix.vector.pool}}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-build-and-tests.sh
     - name: print test failures
@@ -375,7 +375,7 @@ jobs:
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -388,7 +388,7 @@ jobs:
       CI_JOB_IMAGE: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-build-and-minimal-fuzzers.sh
   dockerized:
@@ -464,7 +464,7 @@ jobs:
         else
           apt-get -q update && apt-get -q -y install git
         fi
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: useradd builder --create-home
     - run: chown -R builder .
@@ -474,7 +474,7 @@ jobs:
       run: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v7
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -489,7 +489,7 @@ jobs:
       group: static-analysis-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-static-analysis.sh
     - run: ci/check-directional-formatting.bash
@@ -505,7 +505,7 @@ jobs:
       group: rust-analysis-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/run-rust-checks.sh
   sparse:
@@ -519,7 +519,7 @@ jobs:
       group: sparse-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - name: Install other dependencies
       run: ci/install-dependencies.sh
     - run: make sparse
@@ -535,6 +535,6 @@ jobs:
       CI_JOB_IMAGE: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v6
+    - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
     - run: ci/install-dependencies.sh
     - run: ci/test-documentation.sh

Range-diff against v1:
1:  a178dde02a8 ! 1:  67057c2277e ci: pin actions in the main workflow to full commit IDs
    @@ Metadata
      ## Commit message ##
         ci: pin actions in the main workflow to full commit IDs
     
    -    Some forks are hosted by organizations that restrict which GitHub
    -    Actions may run, including requiring actions to be pinned to full
    -    commit IDs. Our main CI workflow refers to actions by version tags or
    -    branches, which prevents it from running under such a policy.
    +    Our main CI workflow refers to actions by version tags. These tags can
    +    move, changing the action code we run without any change to our
    +    repository. If an attacker gains access to an action's repository,
    +    they can move an existing tag to a malicious revision and have our
    +    workflow pick it up automatically.
     
    -    Pin those actions to full commit IDs, retaining the version names in
    -    comments to make future updates easier to review.
    +    Pin these actions to full commit IDs so that moving a tag cannot
    +    substitute a different action revision. Updating the actions will
    +    require an explicit change to our workflow, including when picking up
    +    bug fixes and security fixes within a major version.
    +
    +    Retain the version names in comments to keep the references readable
    +    and make future updates easier to review.
     
         Signed-off-by: Taylor Blau <ttaylorr@openai.com>
     

base-commit: d46921825429c74931372567941eaf98d4483210
-- 
2.56.0.187.g9e9ae442333
Junio C Hamano· Oct 26, 2026, 18:20 UTC · re: Taylor Blau · lore

Re: [PATCH v2] ci: pin actions in the main workflow to full commit IDs

Taylor Blau <ttaylorr@openai.com> writes:
Show 18 quoted lines
> Our main CI workflow refers to actions by version tags. These tags can
> move, changing the action code we run without any change to our
> repository. If an attacker gains access to an action's repository,
> they can move an existing tag to a malicious revision and have our
> workflow pick it up automatically.
>
> Pin these actions to full commit IDs so that moving a tag cannot
> substitute a different action revision. Updating the actions will
> require an explicit change to our workflow, including when picking up
> bug fixes and security fixes within a major version.
>
> Retain the version names in comments to keep the references readable
> and make future updates easier to review.
>
> Signed-off-by: Taylor Blau <ttaylorr@openai.com>
> ---
>  .github/workflows/main.yml | 64 +++++++++++++++++++-------------------
>  1 file changed, 32 insertions(+), 32 deletions(-)

With these changes, the proposal no longer appears to bend the public version to suit a single employee's environment. We might even want to strengthen the reasoning by adding "becoming the de facto security standard", borrowing from Ben Knoble's comment in the previous round.

Thanks.  Queued.

← back to recent threads