//CI & CLI
Catch it in review, not in production.
The repository scanner runs on your machine or in your pipeline. It reads your filesystem and sends us nothing, findings come back with file and line, and the exit code fails the build.
From your terminal
Scans committed credentials, env-file handling, unsafe migrations and unprotected route handlers.
npx flare-deep . # scan the current directory npx flare-deep . --fail-on high # stricter threshold npx flare-deep . --json out.json # machine-readable output npx flare-deep . --sarif flare.sarif # SARIF for GitHub Code Scanning
In GitHub Actions
name: Security
on:
pull_request:
push:
schedule:
- cron: "0 7 * * *" # daily, because risk changes without you
jobs:
flare:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx flare-deep . --fail-on critical
# exits non-zero on a critical finding → the build failsThe schedule line is the one people leave out, and it is the one that catches the class of problem you cannot cause. Your lockfile does not change, and then an advisory is published against a package you already depend on, yesterday’s clean run is wrong this morning, with no commit and no deploy to tell you. Commit-triggered scanning cannot see that by definition. A daily run re-checks the same lockfile against the advisory database and fails the moment the answer changes.
Findings on the exact line, in GitHub’s Security tab
Add --sarif and upload the result, and every finding shows up as an annotation on the exact line in the pull request and in your repo’s Security → Code scanning tab — the same place GitHub’s own tools report. Paste this in and you’re done:
name: Flare
on: [pull_request, push]
permissions:
contents: read
security-events: write # lets the results appear in the Security tab
jobs:
flare:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx flare-deep . --sarif flare.sarif --fail-on critical
- if: always() # upload even when the build fails, so you still see why
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: flare.sarifThe commit and branch are picked up automatically, so GitHub attaches each finding to the right place. Not sure what any of this means? Hand this whole page to whoever set up your project — it’s a two-minute job for them.
A summary on the pull request
The scan also posts a single comment on the PR (worst findings first, each with its file and line and the fix) and edits that same comment on every push rather than stacking a new one. It states what was found and stops: no severity theatre, no invented stakes. The blocking gate is the exit code above; this is the part a reviewer reads.
# generate the comment body npx flare-deep . --pr-comment flare-comment.md --fail-on low # then post it with actions/github-script (contents: read, pull-requests: write)
Exit codes
Suppressing a finding
Test fixtures and documentation sometimes have to contain credential-shaped text. Mark the line rather than excluding whole files, so the suppression stays visible in review:
const key = "sk_live_EXAMPLEKEYFORTESTS"; // flare-ignore: fixture
Nothing leaves your machine
The repo scanner reads your filesystem locally. No upload, no account.
Git-aware
It asks git what's tracked before calling anything committed, and skips ignored files entirely.
Or drive it from an agent
The MCP server exposes the same scan as a tool your editor can call.
Start with the external scan.
See what’s exposed from the outside first, then wire the repo scan in.
Run your free scan