ci(infra): add top-level permissions and SHA-pin third-party actions [INF-0000] (#35588)

## Summary

- Adds top-level `permissions: contents: read` to 5 workflows that only
had job-level permissions: `pr_labeler_file`, `pr_labeler_title`,
`tag-external-contributions`, `v03_api_doc_build`,
`auto-label-by-package`
- SHA-pins all 14 third-party actions to full commit SHAs to prevent
supply chain attacks via tag hijacking

## Why

**Missing top-level permissions:** Without an explicit top-level
`permissions` block, workflows inherit the repository/org default token
permissions, which may be overly broad. Adding `contents: read` as the
default restricts the blast radius if a dependency or action step is
compromised.

**SHA pinning:** Mutable tags (`@v1`, `@master`) can be force-pushed by
the action maintainer or an attacker who compromises their account.
Pinning to a full 40-character SHA ensures the exact reviewed code
always runs. Tag comments are preserved for readability.

### Actions pinned

| Action | File(s) |
|--------|---------|
| `pypa/gh-action-pypi-publish` | `_release.yml` (2 uses) |
| `ncipollo/release-action` | `_release.yml` |
| `Ana06/get-changed-files` | `check_diffs.yml` |
| `astral-sh/setup-uv` | `check_diffs.yml`, `uv_setup/action.yml` |
| `CodSpeedHQ/action` | `check_diffs.yml` |
| `google-github-actions/auth` | `integration_tests.yml` |
| `aws-actions/configure-aws-credentials` | `integration_tests.yml` |
| `amannn/action-semantic-pull-request` | `pr_lint.yml` |
| `bcoe/conventional-release-labels` | `pr_labeler_title.yml` |
| `mikefarah/yq` | `v03_api_doc_build.yml` |
| `EndBug/add-and-commit` | `v03_api_doc_build.yml` |
| `peter-evans/create-pull-request` | `refresh_model_profiles.yml` |

## Test plan

- [x] CI passes — all workflows still resolve their actions correctly
- [x] Verify no functional change: SHA refs point to the same code as
the previous tags

---

> This PR was generated with assistance from an AI coding agent as part
of a repository posture check.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
John Kennedy
2026-03-05 23:20:05 -08:00
committed by GitHub
parent 53e9ca3bb1
commit bb8b057ac3
11 changed files with 29 additions and 14 deletions

View File

@@ -218,7 +218,7 @@ jobs:
path: ${{ inputs.working-directory }}/dist/
- name: Publish to test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
with:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
@@ -576,7 +576,7 @@ jobs:
path: ${{ inputs.working-directory }}/dist/
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
with:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
@@ -618,7 +618,7 @@ jobs:
path: ${{ inputs.working-directory }}/dist/
- name: Create Tag
uses: ncipollo/release-action@v1
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1
with:
artifacts: "dist/*"
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -4,6 +4,9 @@ on:
issues:
types: [opened, edited]
permissions:
contents: read
jobs:
label-by-package:
permissions:

View File

@@ -54,7 +54,7 @@ jobs:
python-version: "3.11"
- name: "📂 Get Changed Files"
id: files
uses: Ana06/get-changed-files@v2.3.0
uses: Ana06/get-changed-files@25f79e676e7ea1868813e21465014798211fad8c # v2.3.0
- name: "🔍 Analyze Changed Files & Generate Build Matrix"
id: set-matrix
run: |
@@ -185,7 +185,7 @@ jobs:
- uses: actions/checkout@v6
- name: "📦 Install UV Package Manager"
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@0ca8f610542aa7f4acaf39e65cf4eb3c35091883 # v7
with:
# Pinned to 3.13.11 to work around CodSpeed walltime segfault on 3.13.12+
# See: https://github.com/CodSpeedHQ/pytest-codspeed/issues/106
@@ -202,7 +202,7 @@ jobs:
working-directory: ${{ matrix.job-configs.working-directory }}
- name: "⚡ Run Benchmarks: ${{ matrix.job-configs.working-directory }}"
uses: CodSpeedHQ/action@v4
uses: CodSpeedHQ/action@a50965600eafa04edcd6717761f55b77e52aafbd # v4
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
ANTHROPIC_FILES_API_IMAGE_ID: ${{ secrets.ANTHROPIC_FILES_API_IMAGE_ID }}

View File

@@ -103,7 +103,7 @@ jobs:
path: langchain-google
- name: "🔐 Authenticate to Google Cloud"
id: "auth"
uses: google-github-actions/auth@v3
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3
with:
credentials_json: "${{ secrets.GOOGLE_CREDENTIALS }}"
- uses: actions/checkout@v6
@@ -111,7 +111,7 @@ jobs:
repository: langchain-ai/langchain-aws
path: langchain-aws
- name: "🔐 Configure AWS Credentials"
uses: aws-actions/configure-aws-credentials@v6
uses: aws-actions/configure-aws-credentials@fb7eb401298e393da51cdcb2feb1ed0183619014 # v6
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

View File

@@ -10,6 +10,9 @@ on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
contents: read
jobs:
labeler:
name: "label"

View File

@@ -11,6 +11,9 @@ on:
pull_request_target:
types: [opened, edited]
permissions:
contents: read
jobs:
pr-title-labeler:
name: "label"
@@ -22,7 +25,7 @@ jobs:
steps:
- name: Label PR based on title
uses: bcoe/conventional-release-labels@v1
uses: bcoe/conventional-release-labels@b503ca473654e07521c051628c5f1f969e7436da # v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
type_labels: >-

View File

@@ -66,7 +66,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "✅ Validate Conventional Commits Format"
uses: amannn/action-semantic-pull-request@v6
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

View File

@@ -68,7 +68,7 @@ jobs:
- name: "🔀 Create pull request"
id: create-pr
uses: peter-evans/create-pull-request@v8
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
with:
token: ${{ steps.app-token.outputs.token }}
branch: bot/refresh-model-profiles

View File

@@ -22,6 +22,9 @@ on:
pull_request_target:
types: [opened]
permissions:
contents: read
jobs:
tag-external:
runs-on: ubuntu-latest

View File

@@ -13,6 +13,9 @@ run-name: "Build & Deploy API Reference (v0.3)"
on:
workflow_dispatch:
permissions:
contents: read
env:
PYTHON_VERSION: "3.11"
@@ -36,7 +39,7 @@ jobs:
- name: "📋 Extract Repository List with yq"
id: get-unsorted-repos
uses: mikefarah/yq@master
uses: mikefarah/yq@88a31ae8c6b34aad77d2efdecc146113cb3315d0 # master
with:
cmd: |
# Extract repos from packages.yml that are in the langchain-ai org
@@ -158,7 +161,7 @@ jobs:
rm -rf ../langchain-api-docs-html/_build/
# Commit and push changes to langchain-api-docs-html repo
- uses: EndBug/add-and-commit@v9
- uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9
with:
cwd: langchain-api-docs-html
message: "Update API docs build from v0.3 branch"