Skip to content

Ci: Add zizmor static analysis#34905

Merged
Sidnioulz merged 12 commits into
nextfrom
ci/zizmor
May 28, 2026
Merged

Ci: Add zizmor static analysis#34905
Sidnioulz merged 12 commits into
nextfrom
ci/zizmor

Conversation

@huang-julien
Copy link
Copy Markdown
Contributor

@huang-julien huang-julien commented May 26, 2026

Closes #

What I did

Following recent supply chain attacks in the ecosystem, this PR implements zizmor static analysis to strengthen our CI workflows

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing


Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • New Features

    • Added automated security scanning (zizmor) that runs on PRs and key branches and uploads SARIF vulnerability reports.
  • Chores

    • Tightened GitHub token permissions across many workflows for improved security.
    • Pinned third-party actions to fixed SHAs for more reliable runs.
    • Improved credential handling (no persisted credentials), branch/release scripting, and sandbox publishing robustness.

Review Change Stack

@huang-julien huang-julien added build Internal-facing build tooling & test updates ci:normal labels May 26, 2026
@huang-julien huang-julien changed the title ci: add zizmor static analysis Ci: Add zizmor static analysis May 26, 2026
@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.

Comment thread .github/workflows/agent-scan.yml Fixed
Comment thread .github/workflows/zizmor.yml Outdated
@huang-julien huang-julien enabled auto-merge May 26, 2026 08:38
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR hardens GitHub Actions workflows by adding explicit workflow/job permissions, disabling credential persistence in checkouts, pinning actions to commit SHAs, introducing a zizmor scanning workflow (SARIF upload), adding zizmor ignore comments for dangerous triggers, and refactoring release/CI job scripts and output wiring.

Changes

Workflow Security Hardening

Layer / File(s) Summary
Zizmor Security Scanning Infrastructure
.github/workflows/zizmor.yml
New workflow runs zizmor, generates SARIF output, and uploads results for GitHub Actions security scanning across multiple branches and pull requests.
Dangerous Trigger Hardening with Zizmor Ignores
.github/workflows/agent-scan.yml, .github/workflows/danger-js.yml, .github/workflows/trigger-circle-ci-workflow.yml
Adds zizmor ignore comments to workflows using pull_request_target triggers to suppress scanner false positives.
Basic Permission and Credential Hardening
.github/workflows/copilot-setup-steps.yml, .github/workflows/stale.yml, .github/workflows/triage.yml, .github/workflows/publish.yml
Adds persist-credentials: false to checkout steps and updates YAML quoting in simple workflows without functional changes.
Fork Checks Workflow Permission Scoping
.github/workflows/fork-checks.yml
Adds explicit workflow-level empty permissions and scoped job-level contents: read permissions for check, formatting, and test jobs.
Danger JS Workflow Hardening
.github/workflows/danger-js.yml
Moves to workflow-level empty permissions and job-level scoped permissions for the dangerJS job; reorders name/on and adds zizmor ignore.
Sandbox Generation Workflow Hardening
.github/workflows/generate-sandboxes.yml
Tightens permissions, pins checkout/setup-node to commit SHAs, disables credential persistence, and refactors secret handling for sandbox publishing.
Publish Workflow Hardening
.github/workflows/publish.yml
Sets workflow-level empty permissions and explicit job permissions for publish-normal and publish-canary; disables credential persistence for canary checkout and updates quoting.
Nx Workflow Action Pinning and Refactoring
.github/workflows/nx.yml
Pins several third-party actions to commit SHAs, disables credential persistence, and refactors tag selection and Nx invocation to use env vars and bash logic.
Release Branch Handling Workflow Refactoring
.github/workflows/handle-release-branches.yml
Adds scoped permissions, strips refs/heads/ for branch extraction, pins checkout with fetch-depth: 0, and refactors branch push/frontpage dispatch to use env vars and jq payloads.
Non-Patch Release Workflow Output and Variable Refactoring
.github/workflows/prepare-non-patch-release.yml
Adds workflow-level empty permissions with scoped job write access; refactors cancel steps, version bump, changelog, commit, and PR generation to use env vars and bash arg arrays.
Patch Release Workflow Output and Variable Refactoring
.github/workflows/prepare-patch-release.yml
Adds workflow-level empty permissions with scoped job write access; standardizes version/changelog/PR outputs and refactors cancel/watch steps to use quoted run-id env vars.
CircleCI Trigger Workflow Permissions and Payload Refactoring
.github/workflows/trigger-circle-ci-workflow.yml
Adds workflow/job empty permissions, emits branch/parameter outputs via GITHUB_OUTPUT, and replaces HTTP action with inline jq/curl payload builder to trigger CircleCI.
Manager globals export update
code/core/src/manager/globals/exports.ts
Inserts 'SupportedFramework' into the storybook/internal/types exported symbol list.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
.github/workflows/zizmor.yml (2)

26-35: ⚡ Quick win

Make sure findings still reach SARIF upload.

Please verify the CLI exit behavior here. If uvx zizmor returns non-zero when it reports findings, this job stops before upload-sarif runs, so the scan never lands in code scanning. The usual fix is to keep the scan step from short-circuiting the job and mark the upload step with if: always().

♻️ Suggested workflow hardening
       - name: Run zizmor 🌈
+        continue-on-error: true
         run: uvx zizmor --format=sarif . > results.sarif 
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 

       - name: Upload SARIF file
+        if: always()
         uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
         with:
           sarif_file: results.sarif
           category: zizmor
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zizmor.yml around lines 26 - 35, The "Run zizmor 🌈" step
runs the CLI `uvx zizmor --format=sarif .` which may exit non‑zero when it finds
issues and thus prevents the subsequent "Upload SARIF file" step from running;
change the scan step so it doesn't short‑circuit the job (either add
`continue-on-error: true` to the "Run zizmor 🌈" step or append `|| true` to the
`run: uvx zizmor ... > results.sarif` command) and add `if: always()` to the
"Upload SARIF file" step so the SARIF upload (sarif_file: results.sarif,
category: zizmor) runs regardless of the scanner exit code.

23-27: ⚡ Quick win

Pin the zizmor package version instead of installing latest.

Running the analyzer as uvx zizmor pulls whatever PyPI publishes next, which weakens the reproducibility and supply-chain hardening this workflow is trying to add. Please lock zizmor to an explicit version and update it intentionally.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/zizmor.yml around lines 23 - 27, Replace the dynamic
invocation "uvx zizmor --format=sarif . > results.sarif" with a pinned-version
invocation or explicit install so the workflow uses a fixed zizmor release; e.g.
either run "uvx install zizmor==<X.Y.Z>" before executing or invoke the tool
with a version specifier like "uvx zizmor==<X.Y.Z> --format=sarif . >
results.sarif", and update the version token "<X.Y.Z>" to the chosen explicit
release.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/handle-release-branches.yml:
- Around line 53-56: The workflow step with id "next-version" currently uses the
floating action notiz-dev/github-action-json-property@release; replace that
uses: line with a run step that reads the JSON version via jq (e.g. jq -r
.version <path/to/json>) and writes it to the step output named "prop" using the
GitHub Actions recommended mechanism (append "prop=<version>" to
$GITHUB_OUTPUT). Ensure the step keeps id "next-version" and that downstream
uses of next-version.outputs.prop (and any assignment to NEXT_VERSION) continue
to work.

In @.github/workflows/nx.yml:
- Around line 68-70: Replace the mutable "npx nx-cloud@latest start-ci-run
--distribute-on="$DIST_CONFIG" --stop-agents-after="$ALL_TASKS"" invocation with
a pinned, immutable invocation: either reference the exact released nx-cloud
version (e.g., "npx nx-cloud@X.Y.Z start-ci-run ...") or call the
repo-locked/local binary via your package manager (e.g., use the
workspace-installed nx-cloud binary instead of `@latest`). Update the command in
the workflow so "npx nx-cloud@latest" is replaced with a fixed version string or
the local package invocation to ensure reproducible CI runs.

In @.github/workflows/publish.yml:
- Around line 44-47: The publish workflow's permissions block is missing
actions: write which causes 403s when the publish-normal job runs yarn
release:cancel-preparation-runs using GH_TOKEN to call POST
/repos/{owner}/{repo}/actions/runs/{run_id}/cancel; update the permissions
section used by the publish-normal job to include actions: write so the GH_TOKEN
has the required scope for workflow-run cancellation (ensure the permissions
block that currently lists contents, pull-requests, id-token also includes
actions: write and keep the existing entries intact).

In @.github/workflows/trigger-circle-ci-workflow.yml:
- Around line 4-5: The workflow currently calls CircleCI for fork PRs without
gating on the computed trust flag; update the trigger-step in the
trigger-circle-ci-workflow to require
needs.get-parameters.outputs.ghTrustedAuthor == 'true' (i.e., add an if:
condition referencing the get-parameters job output) so the curl/API trigger
only runs for trusted authors, or alternatively include and pass an explicit
trust flag (e.g., trust=true/false) to the CircleCI payload and ensure CircleCI
enforces it; locate the get-parameters job and the step that performs the
curl/API call (the trigger-circle-ci-workflow step that posts
pull/${PR_NUMBER}/head) and modify it to use the trust gate described.

---

Nitpick comments:
In @.github/workflows/zizmor.yml:
- Around line 26-35: The "Run zizmor 🌈" step runs the CLI `uvx zizmor
--format=sarif .` which may exit non‑zero when it finds issues and thus prevents
the subsequent "Upload SARIF file" step from running; change the scan step so it
doesn't short‑circuit the job (either add `continue-on-error: true` to the "Run
zizmor 🌈" step or append `|| true` to the `run: uvx zizmor ... > results.sarif`
command) and add `if: always()` to the "Upload SARIF file" step so the SARIF
upload (sarif_file: results.sarif, category: zizmor) runs regardless of the
scanner exit code.
- Around line 23-27: Replace the dynamic invocation "uvx zizmor --format=sarif .
> results.sarif" with a pinned-version invocation or explicit install so the
workflow uses a fixed zizmor release; e.g. either run "uvx install
zizmor==<X.Y.Z>" before executing or invoke the tool with a version specifier
like "uvx zizmor==<X.Y.Z> --format=sarif . > results.sarif", and update the
version token "<X.Y.Z>" to the chosen explicit release.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 99f2fed3-5219-4aaf-a895-4b58d001b56c

📥 Commits

Reviewing files that changed from the base of the PR and between 11e2a8c and 75432ea.

📒 Files selected for processing (16)
  • .github/workflows/agent-scan.yml
  • .github/workflows/copilot-setup-steps.yml
  • .github/workflows/cron-weekly.yml
  • .github/workflows/danger-js.yml
  • .github/workflows/fork-checks.yml
  • .github/workflows/generate-sandboxes.yml
  • .github/workflows/handle-release-branches.yml
  • .github/workflows/nx.yml
  • .github/workflows/prepare-non-patch-release.yml
  • .github/workflows/prepare-patch-release.yml
  • .github/workflows/publish.yml
  • .github/workflows/stale.yml
  • .github/workflows/triage.yml
  • .github/workflows/trigger-circle-ci-workflow.yml
  • .github/workflows/zizmor.yml
  • .github/zizmor.yml

Comment thread .github/workflows/handle-release-branches.yml Outdated
Comment thread .github/workflows/nx.yml Outdated
Comment thread .github/workflows/publish.yml Outdated
Comment thread .github/workflows/trigger-circle-ci-workflow.yml
@huang-julien huang-julien disabled auto-merge May 26, 2026 08:44
@huang-julien huang-julien marked this pull request as draft May 26, 2026 08:47
@Sidnioulz Sidnioulz self-assigned this May 28, 2026
Comment thread .github/workflows/handle-release-branches.yml Outdated
Comment thread .github/workflows/zizmor.yml Outdated
Comment thread .github/zizmor.yml Outdated
Comment thread .github/workflows/zizmor.yml Outdated
Comment thread .github/workflows/publish.yml Outdated
Comment thread .github/workflows/nx.yml Outdated
Copilot AI and others added 2 commits May 28, 2026 10:21
Co-authored-by: Sidnioulz <5108577+Sidnioulz@users.noreply.github.com>
Co-authored-by: Sidnioulz <5108577+Sidnioulz@users.noreply.github.com>
Copilot AI requested a review from Sidnioulz May 28, 2026 10:33
Comment thread .github/workflows/zizmor.yml Fixed
Comment thread code/core/src/manager/globals/exports.ts Outdated
@Sidnioulz Sidnioulz marked this pull request as ready for review May 28, 2026 11:16
Copilot AI review requested due to automatic review settings May 28, 2026 11:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new GitHub Actions workflow to run zizmor for CI workflow security analysis and adjusts several existing workflows to follow least-privilege token permissions, reduce credential persistence, and harden shell payload construction.

Changes:

  • Added a zizmor workflow that generates SARIF output for GitHub’s code scanning ingestion.
  • Tightened/standardized GitHub Actions permissions across multiple workflows (default permissions: {} + per-job grants), and reduced credential persistence in checkouts.
  • Refactored several workflow shell steps to avoid expression/template injection patterns (move expressions into env, build JSON with jq, pin or hash-pin actions).

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.github/workflows/zizmor.yml New zizmor scanning workflow that runs on push/PR and uploads SARIF.
.github/workflows/trigger-circle-ci-workflow.yml Adds zizmor ignore annotation and hardens branch/parameter handling + replaces HTTP action with curl/jq.
.github/workflows/triage.yml YAML quoting adjustments for zizmor/style compliance.
.github/workflows/stale.yml YAML quoting adjustments for zizmor/style compliance.
.github/workflows/publish.yml Moves to empty default permissions + adds explicit job permissions; reduces credential persistence for canary checkout; minor quoting tweaks.
.github/workflows/prepare-patch-release.yml Adds empty default permissions + explicit job permissions; hardens shell interpolation/quoting in steps.
.github/workflows/prepare-non-patch-release.yml Adds empty default permissions + explicit job permissions; hardens shell interpolation/quoting in steps.
.github/workflows/nx.yml Hardens shell usage, disables persisted credentials, pins nx-cloud invocation, adds zizmor ignore annotations where needed.
.github/workflows/handle-release-branches.yml Adds empty default permissions + explicit job permissions; hardens branch parsing and JSON payload construction.
.github/workflows/generate-sandboxes.yml Adds empty default permissions + explicit job permissions; disables persisted credentials; hardens secret usage in remote URL.
.github/workflows/fork-checks.yml Adds empty default permissions + explicit job permissions per job.
.github/workflows/danger-js.yml Moves to empty default permissions + explicit job permissions; adds zizmor ignore for pull_request_target.
.github/workflows/copilot-setup-steps.yml Disables persisted credentials on checkout.
.github/workflows/agent-scan.yml Adds zizmor ignore for pull_request_target trigger rationale.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/zizmor.yml
Comment thread .github/workflows/zizmor.yml
Comment thread .github/workflows/publish.yml
Comment on lines +121 to +126
DISPATCH_PAYLOAD=$(jq -n --arg branch "$BRANCH" \
'{event_type: "request-create-frontpage-branch", client_payload: {branch: $branch}}')
curl -X POST https://api.github.com/repos/storybookjs/frontpage/dispatches \
-H 'Accept: application/vnd.github.v3+json' \
-u ${{ secrets.FRONTPAGE_ACCESS_TOKEN }} \
--data '{"event_type": "request-create-frontpage-branch", "client_payload": { "branch": "${{ needs.create-next-release-branch.outputs.branch || needs.branch-checks.outputs.branch }}" }}'
-H 'Accept: application/vnd.github.v3+json' \
-u "$FRONTPAGE_TOKEN" \
--data "$DISPATCH_PAYLOAD"
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/handle-release-branches.yml:
- Around line 123-126: The curl call currently uses -u "$FRONTPAGE_TOKEN" (basic
auth) which is wrong for PATs; update the command that posts DISPATCH_PAYLOAD to
use an Authorization header instead by adding a header like "Authorization:
token $FRONTPAGE_TOKEN" (keep the existing Accept header and --data
"$DISPATCH_PAYLOAD"), and remove the -u "$FRONTPAGE_TOKEN" flag so the request
authenticates via the Authorization header.

In @.github/workflows/trigger-circle-ci-workflow.yml:
- Around line 126-144: The CircleCI payload omits the ghTrustedAuthor parameter
causing cache-poisoning protection to fail; update the jq construction so the
PARAMETERS JSON includes ghTrustedAuthor (use the existing output value computed
earlier, e.g. add --arg ghTrustedAuthor "$GH_TRUSTED_AUTHOR" or equivalent
reference to the PARAMETERS creation step) and ensure PAYLOAD still nests
PARAMETERS into parameters as before so the final POST body contains parameters.
Locate the PARAMETERS and PAYLOAD assembly (symbols PARAMETERS and PAYLOAD in
the run block) and include ghTrustedAuthor in PARAMETERS so CircleCI receives
it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4eafd673-9321-4095-95d1-6319b9745e78

📥 Commits

Reviewing files that changed from the base of the PR and between 8149a59 and e96f4ea.

📒 Files selected for processing (14)
  • .github/workflows/agent-scan.yml
  • .github/workflows/copilot-setup-steps.yml
  • .github/workflows/danger-js.yml
  • .github/workflows/fork-checks.yml
  • .github/workflows/generate-sandboxes.yml
  • .github/workflows/handle-release-branches.yml
  • .github/workflows/nx.yml
  • .github/workflows/prepare-non-patch-release.yml
  • .github/workflows/prepare-patch-release.yml
  • .github/workflows/publish.yml
  • .github/workflows/stale.yml
  • .github/workflows/triage.yml
  • .github/workflows/trigger-circle-ci-workflow.yml
  • .github/workflows/zizmor.yml
✅ Files skipped from review due to trivial changes (2)
  • .github/workflows/copilot-setup-steps.yml
  • .github/workflows/triage.yml
🚧 Files skipped from review as they are similar to previous changes (7)
  • .github/workflows/zizmor.yml
  • .github/workflows/generate-sandboxes.yml
  • .github/workflows/danger-js.yml
  • .github/workflows/prepare-patch-release.yml
  • .github/workflows/publish.yml
  • .github/workflows/nx.yml
  • .github/workflows/prepare-non-patch-release.yml

Comment on lines 123 to +126
curl -X POST https://api.github.com/repos/storybookjs/frontpage/dispatches \
-H 'Accept: application/vnd.github.v3+json' \
-u ${{ secrets.FRONTPAGE_ACCESS_TOKEN }} \
--data '{"event_type": "request-create-frontpage-branch", "client_payload": { "branch": "${{ needs.create-next-release-branch.outputs.branch || needs.branch-checks.outputs.branch }}" }}'
-H 'Accept: application/vnd.github.v3+json' \
-u "$FRONTPAGE_TOKEN" \
--data "$DISPATCH_PAYLOAD"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

GitHub API authentication curl PAT token format 2025

💡 Result:

For GitHub REST API authentication with curl using a Personal Access Token (PAT), the PAT value is sent in the HTTP Authorization header, typically as either: 1) Authorization: Bearer Example (GitHub docs): curl --request GET --url "https://api.github.com/octocat" --header "Authorization: Bearer YOUR-TOKEN" [1] 2) Authorization: token GitHub docs note that in most cases you can use Authorization: Bearer or Authorization: token to pass a token (but for JWT you must use Bearer). [1] PAT token “format” (the characters/prefix you’ll see) - GitHub personal access tokens use prefixes: ghp_, gho_, ghu_, ghs_, or ghr_ (case-sensitive prefix). [2] - Those prefixes are followed by the token body characters; a Microsoft security definition describes the overall entity as a prefix plus 36 characters composed of a-z/a-z (case-insensitive) and 0-9. [3] Common curl pattern (concise) curl -H "Authorization: Bearer $GITHUB_TOKEN_OR_PAT" \ -H "X-GitHub-Api-Version: " \ "https://api.github.com/" [1] Important related note (avoid quoting token syntax in curl) GitHub’s docs show the token is supplied via the Authorization header; you typically should not put it in the URL path/query. [1] Answering your “2025” point The token mechanism described in GitHub’s REST authentication docs (Authorization header with Bearer/token) is the current supported method, and the docs show an example using Authorization: Bearer. [1] The token prefixes (ghp_/gho_/ghu_/ghs_/ghr_) and added underscore separator are described in GitHub’s engineering blog. [2]

Citations:


Fix GitHub API curl authentication to use an Authorization header.

-u "$FRONTPAGE_TOKEN" passes the PAT as the basic-auth username (with empty password). For GitHub REST API PAT authentication, the token should be sent via the Authorization header (e.g., Authorization: token $FRONTPAGE_TOKEN).

🔧 Proposed fix using Authorization header
          curl -X POST https://api.github.com/repos/storybookjs/frontpage/dispatches \
            -H 'Accept: application/vnd.github.v3+json' \
-           -u "$FRONTPAGE_TOKEN" \
+           -H "Authorization: token $FRONTPAGE_TOKEN" \
            --data "$DISPATCH_PAYLOAD"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -X POST https://api.github.com/repos/storybookjs/frontpage/dispatches \
-H 'Accept: application/vnd.github.v3+json' \
-u ${{ secrets.FRONTPAGE_ACCESS_TOKEN }} \
--data '{"event_type": "request-create-frontpage-branch", "client_payload": { "branch": "${{ needs.create-next-release-branch.outputs.branch || needs.branch-checks.outputs.branch }}" }}'
-H 'Accept: application/vnd.github.v3+json' \
-u "$FRONTPAGE_TOKEN" \
--data "$DISPATCH_PAYLOAD"
curl -X POST https://api.github.com/repos/storybookjs/frontpage/dispatches \
-H 'Accept: application/vnd.github.v3+json' \
-H "Authorization: token $FRONTPAGE_TOKEN" \
--data "$DISPATCH_PAYLOAD"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/handle-release-branches.yml around lines 123 - 126, The
curl call currently uses -u "$FRONTPAGE_TOKEN" (basic auth) which is wrong for
PATs; update the command that posts DISPATCH_PAYLOAD to use an Authorization
header instead by adding a header like "Authorization: token $FRONTPAGE_TOKEN"
(keep the existing Accept header and --data "$DISPATCH_PAYLOAD"), and remove the
-u "$FRONTPAGE_TOKEN" flag so the request authenticates via the Authorization
header.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@copilot fix this

Comment on lines +126 to +144
env:
CIRCLE_CI_TOKEN: ${{ secrets.CIRCLE_CI_TOKEN }}
BRANCH: ${{ needs.get-branch.outputs.branch }}
WORKFLOW: ${{ needs.get-parameters.outputs.workflow }}
GH_BASE_BRANCH: ${{ needs.get-parameters.outputs.ghBaseBranch }}
GH_PR_NUMBER: ${{ needs.get-parameters.outputs.ghPrNumber }}
run: |
PARAMETERS=$(jq -nc \
--arg workflow "$WORKFLOW" \
--arg ghBaseBranch "$GH_BASE_BRANCH" \
--arg ghPrNumber "$GH_PR_NUMBER" \
'{workflow: $workflow, ghBaseBranch: $ghBaseBranch, ghPrNumber: $ghPrNumber}')
PAYLOAD=$(jq -nc --arg branch "$BRANCH" --argjson parameters "$PARAMETERS" \
'{branch: $branch, parameters: $parameters}')
curl -sS --fail-with-body -X POST \
-H "Content-Type: application/json" \
-H "Circle-Token: $CIRCLE_CI_TOKEN" \
-d "$PAYLOAD" \
"https://circleci.com/api/v2/project/gh/storybookjs/storybook/pipeline"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing ghTrustedAuthor parameter breaks CircleCI cache-poisoning protection.

The ghTrustedAuthor output is computed (line 117) but not included in the CircleCI payload. Per the past review discussion, CircleCI relies on this parameter to skip cache writes for untrusted fork PRs. The refactored jq command omits it.

🐛 Proposed fix to include ghTrustedAuthor
       - name: Trigger CircleCI pipeline
         env:
           CIRCLE_CI_TOKEN: ${{ secrets.CIRCLE_CI_TOKEN }}
           BRANCH: ${{ needs.get-branch.outputs.branch }}
           WORKFLOW: ${{ needs.get-parameters.outputs.workflow }}
           GH_BASE_BRANCH: ${{ needs.get-parameters.outputs.ghBaseBranch }}
           GH_PR_NUMBER: ${{ needs.get-parameters.outputs.ghPrNumber }}
+          GH_TRUSTED_AUTHOR: ${{ needs.get-parameters.outputs.ghTrustedAuthor }}
         run: |
           PARAMETERS=$(jq -nc \
             --arg workflow "$WORKFLOW" \
             --arg ghBaseBranch "$GH_BASE_BRANCH" \
             --arg ghPrNumber "$GH_PR_NUMBER" \
-            '{workflow: $workflow, ghBaseBranch: $ghBaseBranch, ghPrNumber: $ghPrNumber}')
+            --arg ghTrustedAuthor "$GH_TRUSTED_AUTHOR" \
+            '{workflow: $workflow, ghBaseBranch: $ghBaseBranch, ghPrNumber: $ghPrNumber, ghTrustedAuthor: $ghTrustedAuthor}')
           PAYLOAD=$(jq -nc --arg branch "$BRANCH" --argjson parameters "$PARAMETERS" \
             '{branch: $branch, parameters: $parameters}')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
env:
CIRCLE_CI_TOKEN: ${{ secrets.CIRCLE_CI_TOKEN }}
BRANCH: ${{ needs.get-branch.outputs.branch }}
WORKFLOW: ${{ needs.get-parameters.outputs.workflow }}
GH_BASE_BRANCH: ${{ needs.get-parameters.outputs.ghBaseBranch }}
GH_PR_NUMBER: ${{ needs.get-parameters.outputs.ghPrNumber }}
run: |
PARAMETERS=$(jq -nc \
--arg workflow "$WORKFLOW" \
--arg ghBaseBranch "$GH_BASE_BRANCH" \
--arg ghPrNumber "$GH_PR_NUMBER" \
'{workflow: $workflow, ghBaseBranch: $ghBaseBranch, ghPrNumber: $ghPrNumber}')
PAYLOAD=$(jq -nc --arg branch "$BRANCH" --argjson parameters "$PARAMETERS" \
'{branch: $branch, parameters: $parameters}')
curl -sS --fail-with-body -X POST \
-H "Content-Type: application/json" \
-H "Circle-Token: $CIRCLE_CI_TOKEN" \
-d "$PAYLOAD" \
"https://circleci.com/api/v2/project/gh/storybookjs/storybook/pipeline"
env:
CIRCLE_CI_TOKEN: ${{ secrets.CIRCLE_CI_TOKEN }}
BRANCH: ${{ needs.get-branch.outputs.branch }}
WORKFLOW: ${{ needs.get-parameters.outputs.workflow }}
GH_BASE_BRANCH: ${{ needs.get-parameters.outputs.ghBaseBranch }}
GH_PR_NUMBER: ${{ needs.get-parameters.outputs.ghPrNumber }}
GH_TRUSTED_AUTHOR: ${{ needs.get-parameters.outputs.ghTrustedAuthor }}
run: |
PARAMETERS=$(jq -nc \
--arg workflow "$WORKFLOW" \
--arg ghBaseBranch "$GH_BASE_BRANCH" \
--arg ghPrNumber "$GH_PR_NUMBER" \
--arg ghTrustedAuthor "$GH_TRUSTED_AUTHOR" \
'{workflow: $workflow, ghBaseBranch: $ghBaseBranch, ghPrNumber: $ghPrNumber, ghTrustedAuthor: $ghTrustedAuthor}')
PAYLOAD=$(jq -nc --arg branch "$BRANCH" --argjson parameters "$PARAMETERS" \
'{branch: $branch, parameters: $parameters}')
curl -sS --fail-with-body -X POST \
-H "Content-Type: application/json" \
-H "Circle-Token: $CIRCLE_CI_TOKEN" \
-d "$PAYLOAD" \
"https://circleci.com/api/v2/project/gh/storybookjs/storybook/pipeline"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/trigger-circle-ci-workflow.yml around lines 126 - 144, The
CircleCI payload omits the ghTrustedAuthor parameter causing cache-poisoning
protection to fail; update the jq construction so the PARAMETERS JSON includes
ghTrustedAuthor (use the existing output value computed earlier, e.g. add --arg
ghTrustedAuthor "$GH_TRUSTED_AUTHOR" or equivalent reference to the PARAMETERS
creation step) and ensure PAYLOAD still nests PARAMETERS into parameters as
before so the final POST body contains parameters. Locate the PARAMETERS and
PAYLOAD assembly (symbols PARAMETERS and PAYLOAD in the run block) and include
ghTrustedAuthor in PARAMETERS so CircleCI receives it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@copilot reinstate the trusted author flag!

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Co-authored-by: Sidnioulz <5108577+Sidnioulz@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Co-authored-by: Sidnioulz <5108577+Sidnioulz@users.noreply.github.com>
@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented May 28, 2026

Package Benchmarks

Commit: 165e308, ran on 28 May 2026 at 12:50:35 UTC

No significant changes detected, all good. 👏

@Sidnioulz Sidnioulz merged commit aac5da9 into next May 28, 2026
140 of 142 checks passed
@Sidnioulz Sidnioulz deleted the ci/zizmor branch May 28, 2026 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Internal-facing build tooling & test updates ci:normal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants