//Docs
Documentation
Everything Flare.ai does and how to use it: the external scan of your live URL, the flare-deep scan of your repo, and the connected read-only audit of your database. Start with a URL scan, no account needed.
Quickstart
The fastest path is the external scan: paste your app’s deployed URL on the homepage and press Scan. Flare.ai fetches what any visitor gets, probes reachable endpoints, checks DNS, and returns a graded report in under a minute. No login, no repo access, nothing installed.
When you want to go deeper, the same engine runs two more ways, over your source code and over your live database:
# 1 · scan your repo for committed secrets and unsafe code (published on npm) npx flare-deep . # 2 · scan your live URL from the site or the API (see the /api page) # paste the URL at flare.ai, or POST it to the scan endpoint # 3 · connect a read-only database for a live RLS + policy audit # Dashboard → Integrations → Connect a database
The three scans
Each scan sees something the others can’t. The external scan sees what an attacker sees; the repo scan sees what shipped in your code before it’s even deployed; the connected audit sees what’s true inside your database, which no black-box probe can prove.
| Scan | What it reads | Where it runs | Sends us |
|---|---|---|---|
| External | Your live URL, headers, DNS, reachable endpoints and files | Our servers / API | The URL only |
| Repo (flare-deep) | Your filesystem: source, env files, migrations, dependencies | Your machine / CI | Nothing |
| Connected DB | Your live schema: RLS state, policies, functions | Our servers, read-only | A read-only connection string, encrypted |
The external scan
A black-box audit across your whole deploy surface: everything reachable without a login. It’s the scan you run first, because it’s exactly what an attacker can see too.
Secrets in the shipped bundle
Flare downloads your JavaScript bundles and HTML and searches them for credentials that were never meant to reach the browser: API keys, tokens, and connection strings. Every credential it finds is then verified against the provider that issued it (see below), so a live key and one you rotated last year aren’t graded the same.
Open databases
It detects a Supabase or Firebase project from your bundle and probes whether the anon/public key can read tables it shouldn’t, the signature of Row Level Security left off. This is an inference from the outside; the connected audit proves it from inside.
Routes, headers and exposed files
- Unauthenticated & shadow API routes:endpoints that touch data with no visible auth, and forgotten
/api/debug-style routes. - Security headers & CORS:missing
Content-Security-Policy,HSTS, frame options, and over-permissive cross-origin rules. - Exposed files:
.env,.git, source maps and backups served in production. - Email spoofing: missing or weak
SPFandDMARCrecords that let anyone send mail as your domain.
The mistakes AI code generators make
A dedicated layer for the failure modes specific to AI-written apps, which generic scanners miss:
- A secret handed from a Server Component to a Client Component. It lands in the HTML payload and in no
.jsfile at all, so file-only scanners never see it. - A server secret renamed to
NEXT_PUBLIC_to silence a build error, which inlines it into the public bundle. - Tokens passed in URL query strings, where they end up in logs and referrers.
- Debug and seed endpoints left wired up in production.
The full, current list of every check lives on the coverage page.
Live-key verification
Pattern-matching alone can’t tell a live key from one you rotated six months ago, and calling both “critical” is how a scanner gets ignored. When Flare.ai finds a credential it makes one read-only identity request to the provider that issued it, and to nobody else, then grades the finding on the answer:
- Live: the provider accepted it. Critical, high confidence. Rotate it now.
- Revoked: the provider rejected it. Downgraded to medium: still shouldn’t be in your bundle, but it isn’t an emergency.
- Unverified: no safe endpoint exists for that credential type, or the check was inconclusive. Graded on format alone and labelled as such.
Covered: OpenAI, Anthropic, Stripe, GitHub, Slack, Google, and Supabase service_role keys. AWS access key IDs stay unverified on purpose, since verifying one needs the paired secret, which we don’t have and don’t want. No probe is billable and none of them write anything. Set FLARE_DISABLE_SECRET_VERIFICATION=1 to disable the whole layer.
The repo scan (flare-deep)
flare-deep is a zero-dependency command-line scanner, published on npm. It reads your filesystem locally and sends us nothing: no upload, no account, no API key. Run it with npx, no install step:
npx flare-deep . # scan the current directory npx flare-deep . --fail-on high # stricter threshold (default: critical) npx flare-deep . --json out.json # machine-readable output npx flare-deep . --pr-comment c.md # render a PR-ready Markdown summary
Because it can read the source directly, it finds things the external scan can’t:
- Committed secrets: API keys, tokens and database connection strings anywhere in tracked files, not just what shipped to the browser.
- Secrets in git history:credentials that were committed and later removed but are still recoverable from the object store, and aren’t in the current tree.
- Env-file handling:secrets in
.envfiles that aren’t git-ignored, andNEXT_PUBLIC_variables that leak server values into the client build. - Unsafe SQL migrations:migrations that disable RLS, grant broad access, or create permissive policies.
- Unprotected route handlers:API routes that read or write data with no auth guard. The check recognises real auth flows, webhook-signature checks and entitlement gates, so public-by-design routes aren’t flagged.
- Dependency CVEs: known vulnerabilities in your declared dependencies.
It’s git-aware: it asks git what’s tracked before reading anything committed, and skips ignored files. When a line legitimately has to contain credential-shaped text (a test fixture, a docs example), mark that line rather than excluding the whole file, so the suppression stays visible in review:
const key = "sk_live_EXAMPLEKEYFORTESTS"; // flare-ignore: fixture
Connected database audit
The external scan can only infer your database posture from what the anon key happens to return. Connect a read-only database and Flare reads the policy definitions directly, the difference between “this table looked readable” and “RLS is disabled on this table, here’s the row that proves it.” It’s live today for Postgres and Supabase, from Dashboard → Integrations.
What it audits
- RLS disabled on a table the API can serve: anyone with the anon key reads every row. Critical when
anoncan read it, high when only authenticated users can. - Unrestricted write policies:policies using a bare
trueforINSERT/UPDATE/DELETE, which effectively bypass RLS for writes. - SECURITY DEFINER functions:functions callable as RPC that run with their owner’s privileges; flagged higher when
anoncan invoke them without signing in. - RLS on with no policy: a table that silently returns nothing, which is often an app bug rather than a risk; reported at low severity, and stays silent when the table is intentionally service-role only.
How it stays safe
Asking for a database connection is a serious thing, so the guarantees are structural, not promises:
- Use a role with
SELECTonly, least privilege on your side. - Flare forces it anyway: every query runs inside a
BEGIN READ ONLYtransaction withdefault_transaction_read_onlyon, so even a bug can’t write. - Only three introspection
SELECTs ever run, each with an 8-second statement timeout; connections are bounded and closed after. - The connection string is encrypted at rest (AES-256-GCM) with a key that lives only in the server environment, never in the database. It’s write-only from the browser: sent once, never returned, and revocable at any time.
Toxic combinations
Findings that make each other worse are connected into toxic combinations and lead the report. An open table plus an unauthenticated admin route is one compound risk, not two unrelated lines, and it leads because fixing either leg breaks the chain. This is the part that turns a list of findings into a picture of what an attacker could actually do.
Reading your report
Every report has the same shape, worst-first:
- Verdict: one plain-English sentence on what an attacker could do right now.
- Grade & scope: an A–F grade, severity tally, and what was scanned.
- Category breakdown: every area marked pass or flagged, so you can see at a glance what was checked.
- Toxic combinations: findings that compound each other lead the report.
- Findings: each with proof you can verify, a copy-pasteable fix, mapped standards, and, for credentials, whether the key is live, revoked or unverified.
Severity & standards
Findings are ranked Critical → Low and mapped to the frameworks security teams use, so nothing is jargon you can’t look up:
- CWE: the standard catalogue of weakness types. Hover any CWE tag in a report for a plain-English explanation, or click through to MITRE.
- OWASP Top 10: the industry list of the most critical web risks.
- CVSS: a 0–10 score for how severe a weakness is.
Severity is evidence-led. A credential proven live is critical; the same credential proven revoked is medium. A table proven to have RLS off with anon read is critical; a table that merely looked readable from outside is graded lower, and labelled as an inference.
Run it in CI, the terminal, or via API
The repo scan blocks merges on findings straight from your pipeline. Its exit code is the gate:
name: Security
on: [pull_request, push]
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 failsOn a pull request it also posts a single comment (worst findings first, each with its file and line) and edits that same comment on every push rather than stacking new ones. The full walkthrough is on the CI & CLI page. The external scan is also available as an HTTP endpoint that returns JSON on every plan, with Markdown export as a Pro option; its request and response shape is on the API page.
Use it from your AI editor (MCP)
Flare.ai ships a Model Context Protocol server, so Cursor, Claude Code and Windsurf can run scans themselves. It works against localhost, which is the point: the agent starts your dev server, scans it, fixes what it finds, and rescans, all before anything is committed.
flare_scan_urlscans a running app, localhost included.flare_scan_reposcans your source and returnsfile:lineso findings can be fixed directly.flare_verify_credentialanswers whether a key you found is still live or already rotated.
Add it to ~/.cursor/mcp.json (or your Claude Desktop config):
{
"mcpServers": {
"flare": {
"command": "npx",
"args": ["tsx", "/path/to/flare/src/mcp/server.ts"]
}
}
}Every scan opens with an explicit VERDICT: BLOCKING or CLEAN line, so the agent has an unambiguous stop condition. Pass failOn to move that threshold. The full setup is on the MCP page.
Limits & plans
Every external check runs on the free tier: one free scan per website, with your worst finding shown in full. You can unlock a single report’s full detail as a one-off, or go Pro for unlimited scans and rescans across every site. The flare-deep repo scan is free and open to run anywhere, locally or in CI, including its git-history secret scan. Connected database auditing for Postgres and Supabase is live in the dashboard. See pricing.
Is it safe to run?
Yes, and it’s designed so that safety doesn’t depend on trust:
- The external scan is read-only. It never logs in, modifies data, or sends attack payloads. It fetches what a visitor would and reasons about the response.
- The repo scan runs entirely on your machine and uploads nothing.
- The connected audit runs inside a forced read-only transaction and stores your connection string encrypted. It only ever runs three introspection queries.
Full details on the security page.