No signup · under 60 seconds

Run a real PR through VeriFlow

Paste a public GitHub PR URL and get a line-anchored second-pass security review back in under a minute. No account, email, or demo call required. Then keep reading the static sample below to see the full shape of the output.

The sample review covers veriflow/veriflow#142 — a real PR running the second-pass PR security review before a human opens the diff.

The sample below is one of dozens — every linkable review was minted from a real public pull request.

Synthetic review walkthrough

Synthetic example · illustrative only

A fictional code change and one illustrative review finding

src/access/roles.ts
21−return canAccess(user, parseRole(payload.role));21+return canAccess(user, payload.role ?? 'viewer');

Unvalidated role fallback reaches the access decision

Illustratively, defaulting an absent role to viewer handles missing input but does not validate arbitrary values before they reach canAccess.

Suggested fix

const parsedRole = RoleSchema.safeParse(payload.role);
const role = parsedRole.success ? parsedRole.data : 'viewer';
return canAccess(user, role);

Try it now

Paste a PR. Get the review back.

Choose a curated public PR or paste your own. VeriFlow streams the review stages and anchors every finding to the file and line that needs attention.

Curated PR presets

Example output

src/lib/auth.ts:L14

Session cookie decoded without TTL guard

Sample review

A VeriFlow review on a real PR, top to bottom

The diff, three inline review comments, and the security-pass findings panel — synthesized from a real run, statically rendered so you can move at your own pace.

veriflow/veriflowa1b2c3dveriflow-bot
SAMPLE REVIEW · VERIFLOW-INTERNAL
“Wire the v2 PR-review pipeline into the GitHub webhook handler”
A static demo of what a VeriFlow review looks like on a real PR — the diff below is the textbook second-pass exercise: auth boundary leak, secrets hygiene, unsafe YAML loader, and a floating dependency pin.
Severity legend
Critical
Advisory
None
Unavailable
src/app/api/webhooks/github/route.ts
38− if (!verifyWebhookSignature(rawBody, headers)) {
39− return new Response("invalid signature", { status: 401 });
40− }
41− const payload = JSON.parse(rawBody);
42− const installationId = payload.installation.id;
38 if (!verifyWebhookSignature(rawBody, headers)) {
39 return new Response("invalid signature", { status: 401 });
40 }
41 const payload = JSON.parse(rawBody);
42+ const installationId = payload.installation?.id ?? null;
43+ if (installationId === null) {
44+ return new Response("missing installation", { status: 400 });
45 }
46+ await dispatchToPipeline({ installationId, payload });
src/lib/auth.ts
12−export function requireUser(req: Request) {
13− const session = readSessionCookie(req);
14− if (!session) throw new Error("unauthenticated");
15− return session.user;
16−}
12+export async function requireUser(req: Request) {
13+ const session = await readSessionCookie(req);
14 if (!session) throw new Error("unauthenticated");
15+ const fresh = await refreshSessionIfStale(session);
16+ if (!fresh) throw new Error("session expired");
17+ return fresh.user;
18 }
package.json
21− "dependencies": {
22− "next": "16.0.0",
23− "react": "19.0.0"
24− }
21 "dependencies": {
22 "next": "16.0.0",
23+ "react": "19.0.0",
24+ "yaml": "^2.4.0"
25 }

Security pass

Findings surfaced on this PR

Auth, secrets, injection, dependency risk — the four surfaces the second pass audits. Top-level severity aggregates to critical so the security team reads the same vocabulary here as on /security.

Security review

Critical

The PR aggregates to Critical — one reachable auth-path finding and one injection finding on a public-facing loader. Two advisory findings round out secrets hygiene and dependency risk.

src/app/api/webhooks/github/route.tsL49
Criticalauth

Forged webhook payload reaches the review pipeline

After signature verification, the handler forwards the full payload to the review pipeline with no shape validation. A request that passes the HMAC but drops `pull_request.number` runs a review job against an undefined diff and surfaces an error in the audit log instead of a 400.

src/lib/auth.tsL14
Advisorysecrets

Session cookie decoded without TTL guard

`readSessionCookie` returns a session whose `iat` is tracked but never enforced against `exp`. A cookie minted under the previous rotation window still validates; pin the cookie secret to per-tenant HMAC keys so a leaked cookie does not survive rotation.

src/lib/yaml.tsL9
Criticalinjection

YAML loader accepts merge keys on reviewer content

`YAML.parse(reviewerConfig, { merge: true })` is invoked on content the LLM emits. A merge-key payload evaluates anchors against the host process — the gadget chain is small but well-known and the run target is the agent.

package.jsonL24
Advisorydependency risk

Added `yaml@^2.4.0` floats across the minor range

The caret allows any 2.x.y, which silently upgrades into a release that reintroduces a CVE closed earlier this quarter. Pin to a 2.4.x commit or switch to JSON / `YAML.parse` with explicit schema validation.

package.jsonL25
Advisorydependency risk

Transitive dep upgrade dropped, lockfile drift not flagged

The diff updates `next` and `react` together; if the `package-lock.json` regen landed but the review runner cached the prior lockfile hash, CI may resolve against stale versions on the next cold start. The CI preview step verifies the lockfile but the prod runner does not — propagate the check to the deploy gate.

Inline review

Three inline comments the reviewer left

Each comment is anchored to a path:line, ships a suggested fix, and reads with the same severity vocabulary surfaced in the security-pass panel above.

src/app/api/webhooks/github/route.tsL49
general review
Critical

Webhook payload accepted without shape guard

`payload.installation?.id` now defends against a missing key, but the rest of the payload still lands at `dispatchToPipeline` with no schema check. A forged webhook that passes the HMAC but lacks `repository`, `pull_request`, or `sender` will silently reach the review runner and surface confusing failures downstream.

Suggested fix

const parsed = WebhookPayloadSchema.safeParse(payload);
if (!parsed.success) {
  return new Response("invalid payload shape", { status: 400 });
}
await dispatchToPipeline({ installationId, payload: parsed.data });
src/lib/auth.tsL17
general review
Advisory

`readSessionCookie` awaited at the wrong layer

Switching to `await readSessionCookie(req)` was the right call, but the deeper fix is to drop the helper from the per-request path entirely — every webhook route imports `@/lib/auth` and now blocks on the session store even when there is no session to read. Hoist the cookie check or move the lookup behind the `X-GitHub-Event` branch so anonymous webhooks do not pay the cost.

Suggested fix

if (req.headers.get("x-github-event")) {
  // webhook path — session lookup is unnecessary work here
  return handleWebhook(req);
}
const user = await requireUser(req);
package.jsonL24
general review
Advisory

`yaml` added without an explicit SafeLoader constraint

`yaml@^2.4.0` is fine in isolation but the review surface below imports `yaml.load` into a path that parses reviewer-supplied content. v2 deprecated unsafe load by default, but a transitive bump could regress. Pin the version to a known-safe range and document the loader choice in `src/lib/yaml.ts`.

Suggested fix

"yaml": "2.4.5"
// and at the call site: YAML.parse(str, { merge: false })

Review summary

What the reviewer decides

Request changes. Two critical findings (auth boundary leak, YAML merge-key gadget) block the merge until the author ships the suggested fix; the two advisory findings can land in a follow-up PR.

Estimated review time: ~45 seconds across the full diff. The second pass ran asynchronously and posted within 6 seconds of the webhook signature verifying.

More samples

From real public PRs

The walkthrough below is one of dozens — every linkable review was minted from a real public pull request. Same shape, same severity vocabulary, different code.

From the gallery

Reviewed against real PRs, not canned samples

The walkthrough above is one of dozens — every linkable review was minted from a real public pull request. Browse recent runs, filter by language or stack, and click through to the full review.

Recent gallery

Every language VeriFlow sees
Reviews pinned to public repos in TypeScript, Python, Go, Rust, Ruby, and more — pulled from real PRs the team shipped or the community sent through.

Stack-filtered

Just the runs the dogfood caught
The gallery’s chips read which language and which stack a review came from. Try the TS preset below to see the chip bar light up on the next page.

Get on the early access list

Run the second-pass review on your own PRs

Two ways in. Drop your email and we’ll send the security-review rollout cadence. Or start free — run a review on a public repo and see the second pass in action.

Early access

Get early access to the security review
Drop a work email; we’ll send the rollout cadence and a short write-up of what the second pass flags on a real PR.

Submissions land in the waitlist tagged source=‘demo’.

Self-serve

Start free — run a review today
Connect GitHub, pick a public repo, see the second pass surface a finding on its own PR. No email gate, no demo call.

Already running reviews? Open the public gallery for live evidence.