To detect vulnerabilities in your repo for free, stack three layers: a dependency scanner (npm audit, pip-audit or OSV-Scanner), a secret scanner (Gitleaks) and a code scanner (Semgrep Community Edition). Run them on every pull request. None of them will find a missing authorization check, so add a runtime test for that.
npm audit --audit-level=high
pip-audit -r requirements.txt
gitleaks git . --no-banner
semgrep scan --config p/default --metrics=off --error
What Vercel Security Review changes
Vercel Security Review is a Vercel Agent capability, in public beta since November 2, 2026. It scans each push to a connected GitHub repo, reads the diff and the code around it, traces how the change is reachable, and rechecks each finding before reporting it.
Vercel’s example is the reason this post exists. A change to an invoice endpoint looked up invoices by ID without checking the organization, so any signed-in user could download another organization’s invoice. That’s a logic flaw, and pattern scanners struggle with logic flaws.
Here’s who can use it:
| Question | Answer |
|---|---|
| Plans | Pro and Enterprise teams only |
| Cost | Free until November 10, 2026, then provider token rates plus $0.25 per million tokens |
| Repos | Connected GitHub repos; repos that don’t deploy on Vercel aren’t supported yet |
| Scope | The diff against a base, or the full source on a first review |
| Findings | Vulnerabilities dashboard, a GitHub check, and PR comments on private and internal repos |
Vercel’s docs also state the limit: it analyzes code, not your running application, and it isn’t a penetration test. If you don’t qualify, or you’re reading this after the free window, the rest of this guide costs nothing.
What a repo vulnerability scan should cover
A complete repo vulnerability scan checks four things: known flaws in your dependencies, credentials committed to Git, unsafe code patterns such as injection, and authorization logic. The first three have free, mature scanners. The fourth depends on what your code means, so it needs a test against a running API.

A deleted key stays in Git history, so scan history and rotate anything real. For keys in API traffic and test collections, see our API key leak check guide.
Free vulnerability scanners compared
Prices and licenses were checked on November 5, 2026. None of the command-line tools needs an account or a card for the commands in this guide.
| Tool | Finds | Cost and license | Watch out for |
|---|---|---|---|
npm audit |
npm dependency flaws | Free, ships with npm | Needs a lockfile |
| pip-audit | Python dependency flaws | Free, Apache-2.0 | Python only |
| OSV-Scanner | Dependency flaws across ecosystems | Free, Apache-2.0 | Reports more, so expect triage |
| Trivy | Dependencies, secrets, misconfigurations | Free, Apache-2.0 | Pin versions (see below) |
| Gitleaks | Secrets in Git history | Free, MIT | Its GitHub Action needs a free license key for organizations |
| Semgrep Community Edition | Code patterns, some secrets | Free, LGPL-2.1 engine | Can’t track data beyond a single function or file |
| Dependabot alerts | Dependency flaws | Free on public and private repos | GitHub only |
| GitHub secret scanning | Secrets | Free on public repos; $19 per active committer a month on private | Private repos need Secret Protection |
| CodeQL | Code patterns | Free on public repos; $30 per active committer a month on private | Private repos need Code Security |
Two licensing notes. Semgrep’s community rules use the Semgrep Rules License, which allows internal business use but not redistributing them or offering them as a service. And if you adopt Trivy, read CVE-2026-33634: attackers briefly compromised parts of the Trivy ecosystem in March 2026. Run a current release and pin any action to a commit SHA.
Scan a repo in a few commands: what we found
We built a small Express invoice API and committed it to a local repo. It had four npm dependencies and three Python dependencies on old versions, two fake keys (one Stripe-style, one AWS-style), a SQL injection, a command injection, and a route that returns any organization’s invoice to any signed-in user.
Then we ran each tool on macOS on November 5, 2026:
npm audit
pip-audit -r requirements.txt --no-deps --disable-pip
osv-scanner scan source -r .
trivy fs --scanners vuln,secret .
gitleaks git . --no-banner
semgrep scan --config p/default --metrics=off
semgrep scan --config p/nodejsscan --metrics=off
| Tool (version) | Caught | Missed |
|---|---|---|
npm audit (npm 11.12.1) |
9 vulnerable packages: 6 high, 3 low | Everything that isn’t an npm package |
| pip-audit 2.10.1 | 16 advisories across the 3 pinned packages | Transitive packages, because we passed --no-deps |
| OSV-Scanner 2.7.0 | 66 unique advisories across 15 packages, including transitive Python ones | Secrets and code bugs |
| Trivy 0.76.1 | 33 dependency findings and the Stripe-style key | The AWS-style key |
| Gitleaks 8.30.1 | The Stripe-style key | The AWS-style key |
Semgrep 1.183.0, p/default |
Stripe-style key, command injection, a missing CSRF middleware note | SQL injection, AWS-style key |
Semgrep 1.183.0, p/nodejsscan |
SQL injection, command injection, AWS-style key | Stripe-style key |
Three things stand out:
- Counts aren’t comparable. A package, an advisory and a finding are different units, and each tool reads different data. Compare what got caught, not the totals.
- One secret scanner isn’t enough. Gitleaks and Trivy both skipped the AWS-style key.
- Rulesets matter. The default Semgrep pack missed a plain string-built SQL query.
p/javascript,p/nodejs,p/owasp-top-tenandp/sql-injectionreturned nothing on this repo, whilep/nodejsscanfound it.
No tool flagged the invoice route. This is one small repo, so treat it as a demonstration, not a benchmark. We didn’t run CodeQL.
Scan your GitHub repo on every pull request
Standard GitHub-hosted runners are free on public repos. On private repos, GitHub Free includes a $12 monthly allowance, about 2,000 minutes on a 2-core Linux runner at the listed rate. This workflow uses plain commands, so organizations skip the Gitleaks Action license key:
name: repo-scan
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7 # pin to a commit SHA
with:
fetch-depth: 0
- name: Dependencies (npm)
run: npm audit --audit-level=high
- name: Dependencies (Python)
run: pipx run pip-audit -r requirements.txt
- name: Secrets
run: |
curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz | tar xz gitleaks
./gitleaks git . --no-banner
- name: Code patterns
run: pipx run semgrep scan --config p/default --config p/nodejsscan --metrics=off --error
All four scanners exited with code 1 on our test repo, and a non-zero exit is what fails the job. Drop the steps your stack doesn’t need. For API tests in the same pipeline, see Apidog CLI with GitHub Actions.
Turn on Dependabot alerts too. They’re free on every plan and don’t wait for a pull request.
The gap: authorization bugs scanners miss
Authorization bugs are hard for pattern scanners because the code looks correct: a valid query, a valid parameter, an auth middleware in front. The flaw is a missing condition, and only your data model says it should exist.
// Every scanner passed this
db.query("SELECT * FROM invoices WHERE id = $1", [req.params.id]);
// The fix: scope the lookup to the caller's organization
db.query("SELECT * FROM invoices WHERE id = $1 AND org_id = $2",
[req.params.id, req.user.orgId]);
This is Broken Object Level Authorization, ranked first in the OWASP API Security Top 10 2023. OWASP recommends checking access on every request that uses a client-supplied ID, and writing tests that catch authorization failures before deployment.
Asking a coding agent helps. We removed the comments from the test repo and asked Claude Code to review it, with and without a hint about organizations. It flagged the invoice route both times. That isn’t a $0 route on its own, since it uses your agent’s plan, and results can vary between runs.
A test gives you a yes or no on every pull request. For API-side coverage, see automated API vulnerability detection, our API security scanning tools roundup and the API security testing checklist.
Let your coding agent test authorization with Apidog CLI
Don’t write this test by hand for every route. Let your coding agent do it with Apidog CLI: it reads your routes, creates a test per protected resource, and leaves you a suite that runs in CI. Apidog Free covers up to 4 users.
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
apidog skill install
You’ll need a test environment with two seeded organizations and one user in each. Then give your agent one prompt:
Read the routes in src/. For each route that returns data owned by an
organization, create an Apidog test scenario in project <id>: log in as
the Org A test user, request an Org B resource by ID, and assert the
status is 403 or 404. Add an Org A request for its own resource and
assert 200, so a broken login can't pass. Group the scenarios in a test
suite, run it against the staging environment, and summarize failures.
The agent checks the payload shape, creates the scenarios and runs the suite:
apidog cli-schema get test-scenario-create
apidog cli-schema validate test-scenario-create --file scenario.json
apidog test-scenario create --project <id> --file scenario.json
apidog test-scenario import-steps <scenarioId> --project <id> --source endpoint --ids <endpointIds>
apidog test-suite create --project <id> --file suite.json
apidog run --test-suite <suiteId> --project <id> -e <envId> -r cli,junit

The positive check matters. Without it, a wrong base URL also returns a 404, and the test passes for the wrong reason.
Add the same apidog run line to the workflow above, against a preview or staging deployment with seeded test organizations, never production data. The apidog run reference covers the other flags, and Apidog CLI in Claude Code walks through agent setup.
FAQ
What’s the best free way to detect vulnerabilities in a repo? Combine a dependency scanner, Gitleaks and Semgrep Community Edition, then add a runtime test for authorization. No single tool covered everything in our test repo.
Is Vercel Security Review free? Only until November 10, 2026, and only for Pro and Enterprise teams. After that, you pay provider token rates plus $0.25 per million tokens. Repos that don’t deploy on Vercel aren’t supported yet.
Is GitHub secret scanning free on private repos? No. Secret scanning and CodeQL are free on public repos, but private repos need GitHub Secret Protection ($19) or GitHub Code Security ($30) per active committer a month. Dependabot alerts are free on both.
Can Semgrep find authorization bugs? It didn’t flag our invoice route with the rulesets we ran. Community Edition can’t track data beyond a single function or file, though you can write custom rules for patterns specific to your codebase.
Do scanners replace a penetration test? No. Scanners and tests cover known patterns and the cases you wrote down. A penetration test looks for what you didn’t think of, and Vercel’s docs say its own review isn’t one either.



