feat(ci): auto-comment shareable preview links on PRs - #19031
Draft
sfanahata wants to merge 2 commits into
Draft
Conversation
Contractors need to preview PR deployments, but Vercel Deployment Protection now gates all preview URLs (to stop bots/crawlers hitting old builds and creating Sentry noise). Manually minting a shareable link per deployment is a bottleneck. This adds an automated, hardened flow: - app/api/preview-share/route.ts: a public redirect endpoint served from docs.sentry.io. It verifies an HMAC signature + 30-day expiry + host allowlist, then 302-redirects to the preview origin with Vercel's bypass params (x-vercel-protection-bypass + x-vercel-set-bypass-cookie), which sets a bypass cookie so the whole preview is browsable. The Vercel bypass secret lives only in server env vars, never in the PR comment. - .github/workflows/preview-share-link.yml: on deployment_status success for a preview (production skipped), resolves the PR from the commit SHA, signs a 30-day link, and upserts a single sticky PR comment. Runs in the base-repo context so it works for fork PRs. - Covers both docs projects (sentry-docs + develop-docs) via host-based routing to the correct project's bypass secret. Bare preview URLs stay protected; only signed, expiring links grant access. Setup/rotation steps and required secrets are documented in app/api/preview-share/README.md.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- robots.txt: Disallow /api/preview-share (belt-and-suspenders on top of the existing X-Robots-Tag: noindex on every response). - Endpoint: hard-reject the production `git-master` build alias, so even a valid signature can never redirect to the production build URL. The workflow already only signs non-production deployments and the signature binds each link to a specific host; this is defense-in-depth for the production lockdown. - Add a regression test for the master-alias guard. - README: clarify the endpoint is a redirector (no preview content on docs.sentry.io), harmless without a valid link, hidden from nav/sitemap, and cannot mint links to production URLs.
Comment on lines
+141
to
+145
| const redirectTarget = new URL('/', target.origin); | ||
| redirectTarget.searchParams.set('x-vercel-protection-bypass', bypassSecret); | ||
| redirectTarget.searchParams.set('x-vercel-set-bypass-cookie', 'true'); | ||
|
|
||
| const response = NextResponse.redirect(redirectTarget.toString(), 302); |
There was a problem hiding this comment.
Vercel bypass secret exposed in redirect Location header
Any valid public share link returns the project-wide x-vercel-protection-bypass secret in the HTTP Location header, so one curl -I against a PR comment URL recovers a durable secret that bypasses protection for all previews (not only the signed deployment) until rotation.
Evidence
- After HMAC/expiry/host checks, the handler builds
redirectTargetwithx-vercel-protection-bypassset toprocess.env.BYPASS_SECRET_USER_DOCSorBYPASS_SECRET_DEVELOP_DOCSand returnsNextResponse.redirect(...). - Those share URLs are posted publicly on PRs by
.github/workflows/preview-share-link.yml; callers do not need to follow the redirect to readLocation. - Vercel’s automation bypass secret is project-scoped, so the leaked value works on arbitrary protected deployments for that project, not only the origin bound in
u. - This undercuts the design goal of keeping the bypass secret out of public PR comments and re-enables bot/unauthenticated access once any share link is observed.
Identified by Warden · security-review · W37-SNK
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DESCRIBE YOUR PR
Preview deployments are now behind Vercel Deployment Protection (to stop bots/crawlers hitting old builds and generating Sentry noise + accidental indexing). That protection also blocks contractors who legitimately need to preview PRs, and minting a shareable link by hand per deployment is a bottleneck.
This adds an automated, hardened flow that posts a shareable preview link as a sticky PR comment — without exposing the Vercel bypass secret publicly.
What's added
app/api/preview-share/route.ts— a public redirect endpoint served fromdocs.sentry.io. It verifies an HMAC signature + 30-day expiry + host allowlist, then302-redirects to the preview origin with Vercel's bypass params (x-vercel-protection-bypass+x-vercel-set-bypass-cookie=true), which sets a bypass cookie so the whole preview is browsable. The bypass secret lives only in server env vars — never in the PR comment. Fails closed,noindex/no-store, constant-time signature check..github/workflows/preview-share-link.yml— ondeployment_statussuccess for a preview (production skipped), resolves the PR from the commit SHA, signs a 30-day link, and upserts one sticky PR comment. Runs in the base-repo context, so it works for fork PRs too.sentry-docs+develop-docs) via host-based routing to the correct project's bypass secret.app/api/preview-share/route.test.ts— 10 vitest cases (valid redirects, tampered/expired/disallowed-host rejections, fail-closed).Bare preview URLs stay protected; only signed, expiring links grant access.
Required config (not in code) — see
app/api/preview-share/README.md:sentry-docsproject (Production only):SHARE_LINK_SIGNING_KEY,BYPASS_SECRET_USER_DOCS,BYPASS_SECRET_DEVELOP_DOCS.SHARE_LINK_SIGNING_KEY(same value) + variableSHARE_BASE_URL=https://docs.sentry.io.IS YOUR CHANGE URGENT?
PRE-MERGE CHECKLIST
LEGAL BOILERPLATE
Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.
EXTRA RESOURCES