Skip to content

docs: add threat analysis page - #949

Open
davidmytton wants to merge 5 commits into
mainfrom
david/cursor/ip-threat-intelligence-d5b8
Open

davidmytton wants to merge 5 commits into
mainfrom
david/cursor/ip-threat-intelligence-d5b8

Conversation

@davidmytton

Copy link
Copy Markdown
Collaborator

Page describing how to use Arcjet's threat analysis data.

cursoragent and others added 3 commits September 19, 2026 16:45
Add an Advanced hub for blocking VPNs, proxies, Tor, and hosting IPs
with filter rules and decision.ip, plus framework examples and links
to the existing SDK IP analysis references.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Move the JS, Python, and Go inspect samples into the page so Astro
check does not typecheck incomplete snippet fragments.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Regenerate changed chromium-linux screenshot and llms-txt snapshots after adding the Advanced hub page.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
@arcjet-review arcjet-review Bot added the needs review Awaiting human review label Sep 20, 2026
@vercel

vercel Bot commented Sep 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
arcjet-docs Ready Ready Preview Sep 20, 2026 11:49am UTC

Request Review

@arcjet-review arcjet-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arcjet Review — 🟢 Low Risk

Decision: Approved

Rationale: Documentation-only PR: adds a new /ip-threat-intelligence guide with per-framework code snippets, wires it into the sidebar, cross-links from the filters index, vpn-proxy-detection blueprint, and shared IPAnalysis reference partial, and refreshes the affected llms-txt and screenshot snapshots. No application code, auth, infrastructure, dependencies, or migrations are touched. All example code uses environment variables for the Arcjet key (no hardcoded secrets) and models the same defensive patterns already used elsewhere in the docs. Screenshot snapshot updates for adjacent pages are expected because the cross-link paragraph was added to them.

Summary of Changes

Adds a new IP threat intelligence documentation page (src/content/docs/ip-threat-intelligence.mdx) with 12 framework-specific example snippets showing how to deny hosting/VPN/proxy/Tor IPs via filters or by inspecting decision.ip. Adds a sidebar entry, cross-links from filters/index, blueprints/vpn-proxy-detection, and the shared IPAnalysis reference partial, updates public/llms-full.txt, refreshes llms-txt snapshots, and adds the new page to the screenshot test list with baseline images.

Notes

Diff is ~750 lines of additions, well under the 1000-line threshold. Binary screenshot baselines are listed in Files Changed but cannot be visually verified — assumed regenerated by the Playwright snapshot update commit.

Review: a0029e04 | Model: anthropic/claude-opus-4-7 | Powered by Arcjet Review

const decision = await aj.protect(properties.event);

if (decision.isDenied()) {
return error(403, "Forbidden");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SvelteKit's error() helper throws internally, so return error(403, "Forbidden") never actually returns — the throw happens first. More importantly, inside a handle hook you generally want to return a Response rather than rely on the error boundary; throwing from handle won't be rendered by your +error.svelte the way a load/action error would. Consider:

Suggested change
return error(403, "Forbidden");
if (decision.isDenied()) {
return new Response("Forbidden", { status: 403 });
}

app = FastAPI()

aj = arcjet(
key=os.environ["ARCJET_KEY"], # Get your site key from https://console.arcjet.com

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JS/TS snippets throw a friendly Cannot find \ARCJET_KEY` environment variableerror, butos.environ["ARCJET_KEY"]raises a bareKeyError: 'ARCJET_KEY'at import time. Consider matching the pattern used elsewhere, e.g.os.environ.get("ARCJET_KEY")` with an explicit check that raises a clearer message — same suggestion for the Flask snippet on line 10.

`ip.src.relay` unless you intend to block those clients.

When threat intelligence is available, the JavaScript SDK exposes it as
`decision.ip.threat`, the Python SDK as `decision.ip_details.threat`, and the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frameworks frontmatter list doesn't include nuxt, but this paragraph links to the Nuxt SDK reference alongside the other frameworks. Is that intentional (i.e. Nuxt users are expected to read this page for reference even though no Nuxt snippet is shown)? If so, worth a one-line note; if not, either add a Nuxt example or drop the Nuxt link to avoid the mismatch.

In Go, the same signals are fields on `decision.IP`: `IsVPN`, `IsProxy`,
`IsTor`, `IsHosting`, `IsRelay`, `IsAbuser`, `Service`, and `ASNType`.

`asnType` is one of `isp`, `hosting`, `business`, or `education`. Real users

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Start the rule in \DRY_RUN` if you want to log matches before you enforce them.— the example snippets all hardcodemode: "LIVE". Consider mentioning that readers need to change modein the snippet, or link to a docs section onDRY_RUN`, so this instruction isn't left as a dangling hint.

Show Next.js as an App Router route handler, add Nuxt and Go snippets, and document deny patterns on ip.threat fields.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Update the chromium-linux snapshots after the App Router, Nuxt, Go, and ip.threat example changes.

Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants