Skip to content

fix(ci): tie Vercel CLI policy gates to what they protect, not a hand-edited pin - #304

Draft
amanthanvi wants to merge 4 commits into
mainfrom
cursor/vercel-policy-gates-8717
Draft

amanthanvi wants to merge 4 commits into
mainfrom
cursor/vercel-policy-gates-8717

Conversation

@amanthanvi

@amanthanvi amanthanvi commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

What

These are the version-independent policy fixes from #299 (the vercel 58.4.4 → 62.2.0 Dependabot bump), split out so they can land on main while the CLI stays on attested 58.4.4. #299 itself stays blocked by the SLSA provenance gate, and Dependabot will probably close it when it opens a 63.x PR.

  • scripts/check-osv-exceptions.mjs: the old check failed unless package.json pinned vercel 58.4.4 and the lockfile had sandbox@3.4.0. It now checks the condition that actually justifies the two sandbox exceptions:
    • every sandbox in the lockfile is a stable release ≥1.0.0, which is outside both advisories' GitHub-bounded <1.0.0 range (legacy gf3/sandbox is 0.x; Vercel took over the name at 1.0.0);
    • sandbox is only reachable through the root vercel devDependency;
    • it fails if sandbox disappears (the exception is stale) or if any other exception ID is added;
    • each exception must expire between 30 days and one year out. The one-year cap is new and replaces the "every CLI bump forces a review" side effect with a guaranteed yearly review.
    • The core logic is now an exported function with 8 node:test regression tests in scripts/check-osv-exceptions.test.mjs, added to ops:test.
  • deploy.yml: the production guard compared vercel --version with a literal "58.4.4". It now compares against devDependencies.vercel in the trusted tooling package.json. That's the same manifest pnpm deps:provenance verifies earlier in the same job, before any secret is exposed. The contract test asserts this.
  • scripts/check-vercel-provenance.mjs: the verification logic is unchanged. Only the error message now points to docs/runbooks/vercel-ops.md#cli-provenance.
  • Runbook and CHANGELOG updated, including the October 10 recheck.

Why

Two different things blocked #299:

  1. Real: no vercel release since 58.4.4 has an npm provenance attestation. Vercel moved CLI development and publishing to the private vercel/vercel-internal repo (vercel/vercel#17408), and npm doesn't generate provenance for private-repo publishes. I checked 58.5.1 through 63.1.2: every registry.npmjs.org/-/npm/v1/attestations/vercel@<v> returns 404. The provenance gate is correct and stays as is.
  2. Hand-edited pins: the OSV script and deploy.yml hard-coded 58.4.4 / sandbox@3.4.0. They would block even a correctly attested bump until someone edited code. CI never even reached the deploy.yml one (ops:test) because the OSV step failed first.

This PR removes only the second kind. The security properties are unchanged or stronger:

  • SLSA provenance verification of the vercel CLI is byte-for-byte unchanged: the Sigstore certificate identity, the vercel/vercel release.yml@refs/heads/main workflow, and the subject digest.
  • The deployed binary must still be exactly the version the provenance gate verified in the same job.
  • The OSV exceptions are still limited to two IDs and one package on one dependency path. Each still needs a reason with package identity and advisory link, and each now has an expiry ceiling as well as the existing floor.

The same commits pass unchanged on main (vercel 58.4.4 / sandbox@3.4.0) and on #299 (62.2.0 / sandbox@4.4.0). Once an attested release exists, a Dependabot bump will need no manual edits.

Checklist

  • pnpm next:lint, pnpm next:grammar, pnpm next:test, pnpm convex:test, pnpm convex:typecheck
  • pnpm ops:test (45 tests, including 8 new OSV tests), node scripts/check-osv-exceptions.mjs, pnpm deps:provenance (verified vercel@58.4.4 from vercel/vercel@6331571)
  • Real-lockfile negative checks: adding legacy sandbox@0.8.6 fails ("reachable outside the root Vercel CLI dependency"); removing vercel fails ("remove the stale OSV exceptions"). A local run of the new deploy guard passes when the manifest matches the installed CLI and fails closed when it doesn't.
  • pnpm ingest:lint, pnpm ingest:test: not affected (both still pass)
  • CHANGELOG.md updated under Unreleased
Open in Web Open in Cursor 

Summary by Sourcery

Make Vercel and OSV policy gates follow the dependencies and security conditions they protect instead of hand-edited version pins.

Bug Fixes:

  • Remove hard-coded Vercel CLI and sandbox dependency versions from CI policy checks so valid CLI upgrades are not blocked by stale pins.

Enhancements:

  • Tie the production deploy version guard to the trusted tooling manifest verified by the provenance gate.
  • Validate OSV sandbox exceptions against dependency scope, stable version range, exception identity, and bounded review expiry.
  • Add regression coverage for the OSV exception contract and update operational guidance and changelog details.

Documentation:

  • Update the Vercel operations runbook to document manifest-based CLI validation and the revised sandbox exception policy.

Tests:

  • Add eight regression tests covering valid and invalid OSV exception scenarios and CI contract integration.

cursoragent and others added 4 commits October 10, 2026 21:11
Replace the pinned Vercel CLI 58.4.4 / sandbox@3.4.0 tripwire with the
condition that justifies the exceptions: every sandbox in the lockfile is a
stable release at or above 1.0.0 (outside both advisories' affected range),
reached only through the root Vercel CLI dependency. Stale exceptions fail
once sandbox disappears, and expiry must now fall between 30 days and one
year out so exceptions still get periodic review. Add regression tests and
run them in ops:test.

Co-authored-by: Aman Thanvi <amanthanvi@users.noreply.github.com>
…fest

The production guard compared vercel --version with a literal that had to
match package.json. Compare it with the trusted tooling package.json that
deps:provenance verifies earlier in the same job instead, so the deployed
binary is still exactly the attested pin without a second copy to edit.

Co-authored-by: Aman Thanvi <amanthanvi@users.noreply.github.com>
Co-authored-by: Aman Thanvi <amanthanvi@users.noreply.github.com>
Co-authored-by: Aman Thanvi <amanthanvi@users.noreply.github.com>
@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
betterman Ready Ready Preview Oct 10, 2026 9:18pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 10, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@sourcery-ai

sourcery-ai Bot commented Oct 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR removes brittle Vercel CLI and sandbox version pins from CI policy checks while preserving the SLSA provenance gate: OSV exceptions are now validated against package identity, dependency reachability, stable version range, and bounded review expiry, and deployment compares the installed CLI with the trusted manifest verified earlier in the job. Tests, runbooks, error guidance, and changelog entries document and enforce the new contracts.

Sequence diagram for trusted Vercel CLI deployment validation

sequenceDiagram
    participant CI
    participant Provenance as deps:provenance
    participant Manifest as tooling/package.json
    participant CLI as Vercel CLI
    participant Deploy as deploy-vercel.sh

    CI->>Provenance: check-vercel-provenance.mjs
    Provenance->>Manifest: verify devDependencies.vercel
    Provenance-->>CI: provenance verified
    CI->>Manifest: read devDependencies.vercel
    Manifest-->>CI: trusted_vercel
    CI->>CLI: vercel --version
    CLI-->>CI: installed version
    alt versions match
        CI->>Deploy: run scripts/deploy-vercel.sh
    else versions differ
        CI-->>CI: exit 1
    end
Loading

Flow diagram for OSV exception contract validation

flowchart TD
    A[Read osv-scanner exceptions] --> B[Read lockfile dependency tree]
    B --> C{Exactly two allowed advisory IDs?}
    C -- No --> F[Fail CI]
    C -- Yes --> D{Exceptions expire 30 days to one year out?}
    D -- No --> F
    D -- Yes --> E{Every sandbox is stable >= 1.0.0 and reachable only via root vercel?}
    E -- No --> F
    E -- Yes --> G{sandbox still exists?}
    G -- No --> F
    G -- Yes --> H[OSV exception contract passes]
Loading

File-Level Changes

Change Details Files
Replace hand-edited Vercel and sandbox version pins with checks tied to the dependency and security conditions they protect.
  • Validate exactly the two approved OSV exceptions, their advisory evidence, dependency reachability, stable sandbox versions at or above 1.0.0, and 30-day-to-one-year expiry windows.
  • Export the OSV validation logic and add regression coverage for valid dependency trees, stale or out-of-range packages, unauthorized paths, exception-set changes, and expiry boundaries.
  • Run the new OSV tests through the operational test script.
scripts/check-osv-exceptions.mjs
scripts/check-osv-exceptions.test.mjs
package.json
osv-scanner.toml
Make production deployment verify that the installed Vercel CLI matches the manifest whose dependency provenance was already verified.
  • Read the expected CLI version from the trusted tooling package.json instead of comparing against a literal version.
  • Extend the deployment contract test to ensure the manifest-based guard runs before deployment.
  • Document the updated provenance-to-deployment relationship.
.github/workflows/deploy.yml
scripts/check-vercel-provenance.test.mjs
docs/runbooks/vercel-ops.md
Improve operational documentation and provenance failure guidance without changing provenance verification policy.
  • Add the runbook anchor to missing-attestation errors.
  • Record the bounded OSV exception and manifest-driven deploy guard behavior in the changelog.
  • Clarify the current attestation status and recheck details for later Vercel releases.
scripts/check-vercel-provenance.mjs
CHANGELOG.md
docs/runbooks/vercel-ops.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

This branch was successfully deployed

1 active deployment
Preview — 0fc5a5e3 Deployed Oct 10, 2026 by vercel[bot]
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.

2 participants