Whole-repo security scans and automated PR code review. No per-seat pricing, no subscriptions, pay only for what you use.

20 runs or $2 of usage free · no card

  • 2-click install
  • Never trained on your code
  1. criticalCWE-89

    Search filter concatenates q directly into SQL

    src/api/users.ts:214

  2. highCWE-798

    Live database password committed in plaintext

    scripts/seed-db.ts:19

  3. mediumCWE-918

    Issuer URL is fetched without host allow-listing

    src/auth/oidc-discovery.ts:88

  4. + 4 more in the dashboard
0files walked0candidates sent0findings

Everything it does while you ship

Security monitorNightly or on demand

The whole repository, not just the diff

On a schedule or on demand it walks every file, and reports only what it can point at: severity, CWE, file and line.

Scanner findings

5 open
1critical
2high
1medium
1low
VulnerabilityFound

Admin routes are registered before the session middleware, so every /admin handler runs without a user. A request with no cookie can delete workspaces.

Suggested fix

Replaces line 42 · src/server/app.ts

1+app.register(requireSession);
2+app.register(registerAdminRoutes, { prefix: "/admin" });

CWE-306Raised by the codebase cron scan that ran 2h ago · security

ensureCheckout joins the client-supplied checkoutPath onto the workspace root unnormalised, so ../ segments write outside the sandbox.

Suggested fix

Replaces line 118 · src/git/checkout.ts

1+const target = path.resolve(root, checkoutPath);
2+if (!target.startsWith(root + path.sep)) throw badRequest();

CWE-22Raised by the codebase cron scan that ran 2h ago · security

clientName from the device request goes through dangerouslySetInnerHTML, so a script in a client's name runs in the approver's session.

Suggested fix

Replaces line 31 · app/device/page.tsx

1+<p className="device-name">{clientName}</p>

CWE-79Raised by the codebase cron scan that ran 2h ago · security

The HMAC is compared as a string, which exits on the first differing byte and leaks how much of a forged signature was right.

Suggested fix

Replaces line 17 · src/webhooks/verify.ts

1+return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

CWE-208Raised by the codebase cron scan that ran 2h ago · security

The session cookie falls back to the browser default, so older browsers send it on cross-site POSTs.

Suggested fix

Replaces line 9 · lib/auth/cookies.ts

1+sameSite: "lax",

CWE-1275Raised by the codebase cron scan that ran 2h ago · security

PR reviewOn every pull request

A senior reviewer on every pull request

Fixes arrive as inline GitHub suggestions you commit in one click. Everything else lands in one summary.

src/api/users.ts+12 −4
16export async function getUser(ctx, id) {
17 const user = await db.users.find(id);
17 const user = await requireOwner(ctx, id);
18 return serialize(user);
patchlightbotcommented on this line

🟠HIGH · security: Any caller can read any user by id

db.users.find(id) is not scoped to the requester, so a guessed id returns another tenant's record. Go through the ownership guard.

Suggested change

− const user = await db.users.find(id);
+ const user = await requireOwner(ctx, id);
Commit suggestionAdd to batch

Task checkAfter every merge

Did the PR do what the ticket asked?

After a merge it reads the Linear issue and the diff side by side, and posts back what doesn't match.

APP-214 · Rate-limit password resetsmerged · 12s ago
Discrepancies foundposted on the issue

The endpoint is limited, but not the way the issue describes, and the notification half of the ticket never shipped.

  • constant differs·implemented as 10 attempts / 15 min; the issue says 5 per hour
  • scope missing·no email is sent when the limit trips

Testing notes

scope: auth service · reset-password endpoint · redis limiter

Verify the limit trips at attempt 11, not 6

Confirm the window resets after 15 minutes

Flag the missing email to the PM before release

TriggersWhenever you say

Run it only where it matters

PRs into main, skip wip/*, skip bots. You set the rules.

When
PR reopened
Enabled
Only if
Target branch
Include branches
main
Exclude
wip/*
Then
Run task check

What it builds from your findings

Contributor activity4last 30 days
AuthorPRsResolution
mamaya3486%
dmdmytro2871%
sasasha1958%
rerenovate[bot]4693%

Findings by severity

Findings by category

  • Security41
  • Bugs33
  • Maintainability18
  • Convention8

Where the findings come from

Findings, resolution rate and turnaround by severity, repository and contributor.

Review rules3workspace
  • Never use lodash. Prefer native array methods.
  • All API routes must validate input with zod.
  • New endpoints need a rate limit and an auth check.

21const emails = _.uniq(users.map((u) => u.email));

Conventionpatchlight[bot]

Team rule violated: “Never use lodash. Prefer native array methods.” Use [...new Set(users.map((u) => u.email))] instead.

Your standards, in plain English

Write rules the way you'd tell a teammate. Violations come back quoting the rule.

Weekly reportMar 3–9

Review volume held steady while critical findings fell for the third week.

Reviews

63

+9%

Findings

148

−12%

Resolved

74%

+6 pts

Security posture: improving

Suggested rule: “Every new API route must check ownership before returning a record.”Adopt

A weekly read on the codebase

What moved, where findings cluster, and rules worth adopting.

Ask AIyour data only

What kinds of problems do we keep repeating?

Three patterns account for most of the last 90 days, all of them in request handlers:

  • Missing ownership / auth checks31 findings
  • Unvalidated input reaching a query24 findings
  • Unhandled promise rejections17 findings

Two of them are already covered by a rule; the third is not.

Ask about your findings…

Chat about your findings

Answers from your own workspace data, with the numbers attached.

Run it everywhere

Same reviewer, same rules, wherever you trigger it.

GitHub App

Install it once, then forget it

PR reviews and security scans run on the triggers you set.

acme/payments-apiapp installed · 6 repos
  • pull_request.opened · #48212:04

    feat/rate-limit → main

  • Trigger matched12:04

    into main · not a draft · not a bot → start review

  • patchlight[bot] reviewed12:05

    2 inline suggestions · 1 finding in the summary

Any CI

One line in the pipeline

$npx @patchlight/sdk review --fail-on high

✓ 4 findings · highest: medium

exit 0 · pipeline continues

GitLab · Bitbucket · Azure · GitHub Actions · any shell

Terminal

Scan it before you push

▌ patchlight scan
✓walk4,336 files
✓triage38 flagged
⠙scansrc/auth/oidc.ts…
❯ ◆q concatenated into SQL
◆Password committed in plaintext

Your code isn’t stored

We read the diff, post the review, drop the code. We keep the finding: file, line, explanation, and the lines the fix changes.

Read

export async function searchCustomers(req) {
- const rows = await db.query(safe(q));
+ const rows = await db.raw(
+ `SELECT * FROM customers WHERE name LIKE '%${q}%'`
+ );

released when the review ends

Kept

auth.ts:214

SQL injection via interpolated query

+ db.query(sql, [q])

Dropped

  • the diff
  • the file contents
  • the prompt
  • the model's transcript

No training

Never used to train a model, ours or a provider's.

Zero retention

Model providers run under zero-retention terms.

EU-operated

GDPR-ready, DPA on request.

Prepaid. No seats.

Free

$0

Your first 20 runs or $2 of usage, on us

  • PR review
  • Security scan, in the app or the CLI
  • Findings dashboard
  • Analytics

Pay as you go

from $10

Prepaid balance, no subscription

$10 covers about 660 PR reviews or 50 security scans, at our median prices.

  • Everything from the Free tier
  • Scheduled and after-merge scans
  • New findings filed as GitHub issues
  • Weekly reports
  • Ask AI chat on your findings
  • Linear task check
  • Team rules & flexible triggers

What a month of reviews costs

Seats bill every developer whether they open a PR or not. Patchlight bills the reviews.

developers
Typical: 16 per developer
PRs

Your monthly bill

10 devs · 160 PRs

  • Patchlight

    160 reviews × $0.015

    $2.40

  • CodeRabbit

    10 seats × $24

    $240

  • cubic

    10 seats × $30

    $300

$2,851 a year stays in your budget, against the cheaper seat plan.

A seat only pays off past 1,600 PRs per developer a month.

Patchlight at our median of $0.015 per PR review; larger PRs cost more. CodeRabbit and cubic at their cheapest paid plan, billed yearly ($24 and $30 per developer a month), October 2026. The typical 16 PRs per developer a month comes from DX’s engineering benchmarks: a median of 3.8 merged PRs per developer a week at tech companies under 100 engineers.

How Patchlight stacks up

Review, scheduled security scans, issues filed for you, and task checks. Billed for usage, not seats.

PatchlightCodeRabbitcubic

PR reviews with inline comments

Full-repo security scans

PartialPartial

Full security scan from the CLI

PartialPartial

Findings filed as GitHub issues

Automatic fix PRs

Partial

Findings analytics & reports

Partial

Ask AI on your findings

Linear task check

Partial

Team rules in plain English

Pricing model

Patchlight
Pay as you go, from $10
CodeRabbit
From $24/dev/mo, billed yearly
cubic
From $30/dev/mo, billed yearly

Usage caps

Patchlight
None, pay per use
CodeRabbit
5–12 reviews/dev/hour by plan
cubic
40k lines/dev/mo, then $20 per 10k

Free to start

Patchlight
20 runs or $2 of usage free, no card
CodeRabbit
14-day trial, free for open source
cubic
20 PRs/mo, free for open source

✓ included · Partial: partial or add-on · not offered. Based on public docs and pricing pages, October 2026. Spotted something off? Tell us and we’ll fix it.

Two clicks to install. Your first review lands on your next pull request.

Install the GitHub App

20 runs or $2 of usage free · no card