Skip to content

ci: harden CI/CD — SHA-pin actions, bump pnpm to 11.1.2, add zizmor#1685

Merged
jpr5 merged 5 commits into
mainfrom
alem/ci-security-hardening
May 15, 2026
Merged

ci: harden CI/CD — SHA-pin actions, bump pnpm to 11.1.2, add zizmor#1685
jpr5 merged 5 commits into
mainfrom
alem/ci-security-hardening

Conversation

@AlemTuzlak
Copy link
Copy Markdown
Contributor

Summary

CI/CD supply-chain hardening. Mirrors what TanStack landed recently:

  • Every uses: in .github/workflows/ pinned to a 40-char commit SHA with a trailing # v<semver> comment (Dependabot-readable). 136 references across 23 distinct actions.
  • pnpm bumped from 10.13.1 to 11.1.2. pnpm 11 ships manage-package-manager-versions: true by default and requires explicit allow-listing of postinstall scripts. pnpm-workspace.yaml enumerates each detected package with a per-package decision (native binaries → true, telemetry/polyfills → false).
  • Dependabot enrolls the github-actions ecosystem so the new SHA pins don't go stale (weekly cadence, grouped minor/patch).
  • Zizmor static analysis runs on PR + push + weekly cron. SARIF uploads to the GitHub Security tab. Currently at 0 High findings on --persona=auditor (down from 15 at the start of this PR).
  • Workflow correctness fixes surfaced by the audit:
    • Resolves a committed merge conflict in unit-python-sdk.yml (1b2d499) that was silently breaking Python CI on main.
    • Adds explicit least-privilege permissions: blocks (top-level contents: read; write scopes pushed down to the single jobs that need them).
    • Replaces attacker-controllable shell interpolation with env: indirection across prerelease.yml, prepare-release.yml, and the unit-* fork-detection patterns.
    • Gates the langroid OPENAI_API_KEY injection in dojo-e2e.yml to same-repo PRs only (fork PRs were exposed to secret exfiltration via a malicious test runner).

CODEOWNERS was intentionally out of scope (already in place).

Audit findings — severity counts

Three parallel code-reviewer agents audited injection, privilege/secret, and supply-chain surfaces before any code was changed:

Severity At start of PR Remaining
Critical 1 (merge conflict) 0
High 9 0
Medium 6 4 (deferred — see follow-ups)
Low 4 2 (deferred — informational)

After hardening, zizmor --persona=auditor reports: 117 findings (0 high, 30 medium, 48 low, 38 informational). None block this PR; medium/low surface in the Security tab for ongoing triage.

Commits

  1. chore: bump pnpm to 11.1.2 with allowBuilds for native postinstalls
  2. ci: harden all workflows — permissions, SHA pins, injection fixes
  3. ci: add Dependabot config + zizmor config

Test plan

  • pnpm install + pnpm install --frozen-lockfile both succeed with pnpm 11.1.2; postinstall build scripts run (esbuild, sharp, protobufjs, @tailwindcss/oxide, unrs-resolver) — verified locally
  • All 23 workflow YAMLs parse cleanly
  • uvx zizmor --persona=auditor reports 0 High findings
  • No bare-tag uses: references remain (grep -rE 'uses:[[:space:]]+\S+@v[0-9]' .github/workflows/ returns nothing)
  • Merge conflict in unit-python-sdk.yml resolved with all 6 Python jobs intact
  • CI: lint-release-workflows (actionlint) passes
  • CI: unit-typescript-sdk, unit-python-sdk, and other unit jobs pass on pnpm 11.1.2
  • CI: zizmor uploads SARIF to Security tab

Follow-ups (tracked separately, not in this PR)

See the Notion doc for the full deferred list — supply-chain replacements, langroid workflow_run pattern, gradle-build-action migration, depot runner trust-boundary docs, id-token: write review, publish-python-preview artifact validation, and the GitHub repo-settings changes (branch protection, required code-scanning gates) that the team needs to make in the UI.

Bumps pnpm from 10.13.1 to 11.1.2. pnpm 11 ships hardened defaults —
notably `manage-package-manager-versions: true` and explicit
allow-listing of postinstall scripts (no more implicit script execution
during install).

The new `allowBuilds:` block in pnpm-workspace.yaml enumerates each
package whose postinstall pnpm 11 detected. Most need their scripts to
fetch native binaries or run codegen (esbuild, sharp, protobufjs,
@tailwindcss/oxide, unrs-resolver). @scarf/scarf (telemetry) and
core-js (polyfill) are opted out as non-essential.

Workflow pnpm version: fields are bumped in the workflow-hardening
commit alongside the rest of the .yml changes.
Multi-faceted CI/CD hardening that mirrors what TanStack landed
recently. Folds together changes that touch the same set of 22 workflow
files so the SHA-pin diff stays paired with the security context that
justifies it.

* Resolves a committed merge conflict in unit-python-sdk.yml that was
  silently breaking Python CI on main (1b2d499). Keeps both
  watsonx-python and the adk/aws-strands/langroid job blocks.

* Pins every `uses:` to a 40-char commit SHA with a `# v<semver>`
  trailing comment so Dependabot can keep the pins current.
  Replaces 136 floating-tag references across 23 distinct actions.
  Defeats tag-retargeting supply-chain attacks
  (cf. tj-actions/changed-files, Mar 2025).

* Adds explicit `permissions:` blocks (least-privilege) to all
  workflows. `contents: read` at the top level; write scopes pushed
  down to the specific jobs that need them (prepare-release,
  auto-approve-community, security-fork-pr-alert) so future job
  additions are safe-by-default.

* Routes attacker-controllable inputs through `env:` indirection
  instead of inline `${{ ... }}` interpolation in shell `run:` blocks.
  Affects `workflow_dispatch` inputs in prerelease.yml and
  prepare-release.yml, and `github.event.pull_request.head.repo.*`
  comparisons in the unit-* fork-detection patterns.

* Gates the langroid `OPENAI_API_KEY` injection in dojo-e2e.yml on
  same-repo PRs only. Fork PRs will skip langroid e2e until a
  follow-up moves langroid to a workflow_run pattern (which would
  let fork PRs run langroid with secrets injected in the trusted
  base context).

* Bumps the workflow-level pnpm version: fields to 11.1.2 to match
  package.json's packageManager field.

* Bumps publish-commit.yml from actions/checkout@v2 (5 years old) and
  normalizes astral-sh/setup-uv to v6 across all workflows.
* `.github/dependabot.yml` enrolls the `github-actions` ecosystem so
  Dependabot opens weekly PRs to bump the SHA pins added in the
  previous commit. Minor/patch bumps are grouped so we don't get one
  PR per action per week; majors still get their own PR (intentional —
  they need review).

* `.github/zizmor.yml` configures zizmor to ignore one well-documented
  intentional finding: publish-python-preview.yml's `workflow_run`
  trigger, which is the canonical safe pattern for cross-PR fork
  artifact handling.

The zizmor workflow itself was added in the workflow-hardening commit
since it lives under `.github/workflows/`.
@AlemTuzlak AlemTuzlak requested a review from a team as a code owner May 14, 2026 16:31
@vercel
Copy link
Copy Markdown

vercel Bot commented May 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ag-ui-dojo Ready Ready Preview, Comment May 15, 2026 0:46am

Request Review

@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

Python Preview Packages

Version 0.0.0.dev1778805683 published to TestPyPI.

Warning: These packages are built from contributor code that may not yet have been vetted for correctness or security. Install at your own risk and do not use in production.

Install with uv

Add the TestPyPI index to your pyproject.toml:

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
explicit = true

Then install the packages you need:

# Core SDK
uv add 'ag-ui-protocol==0.0.0.dev1778805683' --index testpypi

# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==0.0.0.dev1778805683' --index testpypi
uv add 'ag-ui-crewai==0.0.0.dev1778805683' --index testpypi
# NOTE: ag-ui-agent-spec depends on pyagentspec (git-only, not on PyPI).
# You will need to install pyagentspec separately from its git repo.
uv add 'ag-ui-agent-spec==0.0.0.dev1778805683' --index testpypi
uv add 'ag_ui_adk==0.0.0.dev1778805683' --index testpypi
uv add 'ag_ui_strands==0.0.0.dev1778805683' --index testpypi

Install with pip

pip install \
  --index-url https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  ag-ui-protocol==0.0.0.dev1778805683

Use --extra-index-url https://pypi.org/simple/ so pip can resolve
transitive dependencies (pydantic, fastapi, etc.) from real PyPI.


Commit: 6d65942

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 14, 2026

Open in StackBlitz

@ag-ui/a2a-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a-middleware@1685

@ag-ui/a2ui-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-middleware@1685

@ag-ui/event-throttle-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/event-throttle-middleware@1685

@ag-ui/mcp-apps-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-apps-middleware@1685

@ag-ui/middleware-starter

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/middleware-starter@1685

@ag-ui/a2a

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a@1685

@ag-ui/adk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/adk@1685

@ag-ui/ag2

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/ag2@1685

@ag-ui/agno

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/agno@1685

@ag-ui/aws-strands

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/aws-strands@1685

@ag-ui/claude-agent-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/claude-agent-sdk@1685

@ag-ui/crewai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/crewai@1685

@ag-ui/langchain

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langchain@1685

@ag-ui/langgraph

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langgraph@1685

@ag-ui/langroid

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langroid@1685

@ag-ui/llamaindex

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/llamaindex@1685

@ag-ui/mastra

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mastra@1685

@ag-ui/pydantic-ai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/pydantic-ai@1685

@ag-ui/server-starter

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/server-starter@1685

@ag-ui/server-starter-all-features

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/server-starter-all-features@1685

@ag-ui/vercel-ai-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/vercel-ai-sdk@1685

@ag-ui/watsonx

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/watsonx@1685

create-ag-ui-app

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/create-ag-ui-app@1685

@ag-ui/client

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/client@1685

@ag-ui/core

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/core@1685

@ag-ui/encoder

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/encoder@1685

@ag-ui/proto

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/proto@1685

commit: 77e76aa

Copy link
Copy Markdown
Contributor

@MikeRyanDev MikeRyanDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No serious supply-chain or CI hardening blockers found. Release and prerelease workflows split no-secret build/test from publish, publish jobs install with --ignore-scripts or consume built artifacts, fork PR caches are prefixed away from release/main cache scopes, pull_request_target usage is Dependabot-only without PR checkout, actions are pinned, and zizmor/actionlint pass.

@jpr5 jpr5 merged commit 35e7cac into main May 15, 2026
53 of 56 checks passed
@jpr5 jpr5 deleted the alem/ci-security-hardening branch May 15, 2026 16:49
@MikeMcC399
Copy link
Copy Markdown

@jpr5

The spamming issue has propagated here too. Posting @mentions of contributors to open source software contributors causes each of them to be spammed.

For example, in #1716 (comment)

Please ensure this is also removed here. From your previous response and apology in CopilotKit/aimock#216 (comment), I understand that this was accidental.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants