Introducing Arcjet Guards: security inside the agent loop
Arcjet Guards runs security rules inside agent tool handlers, queue consumers, and workflow steps - where proxies and WAFs can't see.
Arcjet Signals are evaluated without a CAPTCHA and enforced when the request passes through a critical flow. The browser gives us signals. The application gives us intent.
Modern abusive automation no longer looks like the simple bots many web security controls were originally built to stop. Attackers use real browsers with a full JS engine, submit forms, hit login endpoints, scrape content, and consume expensive resources while looking enough like normal users to pass basic checks.
Today we're announcing Arcjet Advanced Bot Signals: browser-based bot detection that collects client-side telemetry and evaluates that result server-side as part of our existing bot detection functionality. Signals are evaluated without a CAPTCHA and enforced when the request passes through a critical flow. This is designed for tight integration into your application logic for highly customizable protection.
That combination matters because a request to /subscribe, /signup, /login, or /checkout is not just another HTTP event. Your code knows what that route means, who the user is, whether the action is expensive, whether the email matters, and what should happen when a decision is denied. The browser gives us signals. The application gives us intent.
The web is shifting from human-operated browsers to software-operated browsers.
Anthropic introduced computer use in Claude, letting developers direct a model to look at a screen, move a cursor, click buttons, and type text. OpenAI introduced Operator as an agent that uses its own browser, and later integrated those capabilities into ChatGPT agent, which can complete tasks using its own computer.
That is the product version of the shift. The abuse version is the same capability pointed at forms, account creation, checkout, content, and APIs.
The numbers are moving quickly:
This is why the old test of "does it execute JavaScript?" is no longer enough. AI agents and browser automation frameworks can load pages, follow flows, store cookies, and submit forms. The new test is more specific: did this request come through a browser environment that behaves consistently enough to trust for this route, and does the application context agree?
That is what Advanced Signals is built to answer.
I run console.dev, a weekly developer tools newsletter with a simple subscribe form backed by Mailchimp. A few weeks ago the form started getting spammed.
The requests did not look dramatic. They were not SQL injection payloads or obvious curl or known bot user agents. They were Gmail addresses submitted with a realistic-looking Chrome browser with all the right request headers. They never confirmed the Mailchimp opt-in, so they did not create a permanent list problem, but every attempted signup still triggered email from the domain. A couple hundred unconfirmed submissions per day is enough to become an email reputation problem.
This is an annoying class of abuse: not loud, but real. It sits exactly at the edge of product behavior and security behavior. A proxy can see a request, but has no context. The application knows it is a newsletter subscription, that a normal person should submit once, that the email address should be validated, and that the browser should have loaded the site before posting to Mailchimp.
So I added Arcjet where the decision had enough context:
When I looked at the live traffic, the spammer was still trying. The difference was that the requests were no longer reaching Mailchimp. Arcjet was catching most of them with a simple rate limit, then the ones that got through triggered the Signals analysis. The ones missing the cookie were easy to block, but the more sophisticated attempts still failed the advanced signals analysis. Real users were still able to subscribe.
This demonstrates multiple layers of protections working together - different protections for different types of attacks, with increasing sophistication. That is the shape Advanced Signals is built for - gradually escalating the protections on critical routes.
It’s also different from a CAPTCHA-style challenge where the security product interrupts the user and asks them to prove something. That’s bad for user experience, branding, and often causes unintended consequences for people using accessibility features. It is also different from treating every page view as equally sensitive. Most applications do not need the same enforcement on a marketing page as they do on a signup form, checkout, login endpoint, invite flow, or expensive AI action.
Advanced Signals lets you passively collect browser context early, then enforce it at the point of risk.
Network-level bot detection is useful because it sees a lot of traffic. It can score requests, identify known automated clients, inject browser checks into HTML pages, and apply WAF rules before traffic reaches the origin.
That is a good model when the edge is the right control point, but the edge has a reduced picture of the application. It can see the request. It does not naturally know the business rule that makes a route sensitive, the authenticated account state, the downstream cost of the action, the form semantics, or how the decision should combine with email validation and rate limiting.
This becomes more important as automation becomes more legitimate and more ambiguous. A search crawler, an AI training bot, a user-authorized agent, a fraud script, and a spammer with a headless browser can all be "bots", but the right decision depends on what they are doing.
The subscribe form on console.dev did not need a generic bot score on every request. The homepage should be generally accessible to all, the RSS feeds should allow automated feed readers, but the subscribe handler needs real protection. That is application security, not only perimeter security.
There are two pieces: a browser collector and a server-side bot rule.
First, load the Signals script on pages that can lead to a sensitive action - this can be on every page of your site because the collection only happens once every-so-often:
<script
id="arcjet-signals"
src="https://signals-cdn.arcjet.com/aj-sig.js"
defer
></script>The collector runs a WebAssembly module in the browser, collects telemetry about the environment, sends it to Arcjet, and receives a continue token. That token is stored in the aj_signals cookie so it can be reused on later requests instead of collecting signals on every page load.
Then configure bot detection using the Arcjet SDK on the sensitive route. For example, in a Next.js application (the same principle applies for our other SDKs):
import arcjet, { detectBot } from "@arcjet/next";
import { NextResponse } from "next/server";
const aj = arcjet({
key: process.env.ARCJET_KEY!,
rules: [
detectBot({
mode: "LIVE",
allow: [], // deny all bots by default, including signals failures
}),
],
});
export async function POST(req: Request) {
const decision = await aj.protect(req);
if (decision.isDenied()) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
return NextResponse.json({ message: "success" });
}If Signals suggests automation Arcjet denies the request and includes ARCJET_SIGNALS as the bot reason. That makes it visible in the same decision model as other bot entities. You can start in dry-run mode to evaluate deny decisions before they affect traffic, then add a filter rule to reject POST requests without the cookie.
CAPTCHAs are a tax on legitimate users. They are also less useful than they used to be - modern AI models can basically solve them all, and normal users get interrupted at exactly the point they are trying to complete an action. Advanced Signals is passive. It does not ask the user to click traffic lights or solve a puzzle. It runs before the sensitive request, then lets the server-side rule decide what to do.
Add the Signals script to pages that lead into the route you want to protect, then configure detectBot on the sensitive handler. The Advanced Signals docs include examples for Next.js, Python, Deno, Bun, NestJS, FastAPI, Flask, and other frameworks.
Arcjet Guards runs security rules inside agent tool handlers, queue consumers, and workflow steps - where proxies and WAFs can't see.
Introducing Arcjet prompt injection detection. Catch hostile instructions before inference. Works with Next.js, Node.js, Flask, FastAPI, and any JavaScript / TypeScript or Python application.
We’ve just released v1.0 of the Arcjet JavaScript SDK. After more than two years of building, testing, and iterating in public, the
Get the full posts by email every week.