Arcjet is the runtime security platform that ships in your AI code. Detect prompt injection, authorize agent tool calls, redact sensitive data, and block bots and abuse. Real-time security building blocks you call inside your app, before an action happens.
This is the Arcjet SDK for NestJSrequest protection —
use it to protect HTTP route handlers and API endpoints. If you need to protect
AI agent tool calls, MCP server handlers, or background jobs (anything without
an HTTP request), see @arcjet/guard.
Why Arcjet?
Your app's AI features and agents take real actions, calling tools, reading data, hitting APIs. Arcjet runs inside that code and lets you enforce security on each action in real time, then audit what happened
Getting started
Quick setup with an AI agent
Log in with the CLI:
npx @arcjet/cli auth login
Install versioned Agent Skills so your coding agent matches this SDK:
npx @tanstack/intent@latest install
Tell your agent what to protect — it handles the rest.
Detect and block prompt injection attacks — attempts to override your AI
model's instructions — before they reach your model. Pass the user's message
via detectPromptInjectionMessage on each protect() call.
Arcjet allows you to configure a list of bots to allow or deny. Specifying
allow means all other bots are denied. An empty allow list blocks all bots.
Available categories: CATEGORY:ACADEMIC, CATEGORY:ADVERTISING,
CATEGORY:AI, CATEGORY:AMAZON, CATEGORY:APPLE, CATEGORY:ARCHIVE,
CATEGORY:BOTNET, CATEGORY:FEEDFETCHER, CATEGORY:GOOGLE,
CATEGORY:META, CATEGORY:MICROSOFT, CATEGORY:MONITOR,
CATEGORY:OPTIMIZER, CATEGORY:PREVIEW, CATEGORY:PROGRAMMATIC,
CATEGORY:SEARCH_ENGINE, CATEGORY:SLACK, CATEGORY:SOCIAL,
CATEGORY:TOOL, CATEGORY:UNKNOWN, CATEGORY:VERCEL,
CATEGORY:WEBHOOK, CATEGORY:YAHOO. You can also allow or deny
specific bots by name.
import { ArcjetModule, detectBot } from"@arcjet/nest";
ArcjetModule.forRoot({
isGlobal: true,
key: process.env.ARCJET_KEY!,
rules: [
detectBot({
mode: "LIVE",
allow: [
"CATEGORY:SEARCH_ENGINE",
// See the full list at https://arcjet.com/bot-list
],
}),
],
});
// In your controller:import { isSpoofedBot } from"@arcjet/inspect";
const decision = awaitthis.arcjet.protect(req);
if (decision.isDenied() && decision.reason.isBot()) {
thrownewHttpException("No bots allowed", HttpStatus.FORBIDDEN);
}
// Verifies the authenticity of common bots using IP data.if (decision.results.some(isSpoofedBot)) {
thrownewHttpException("Forbidden", HttpStatus.FORBIDDEN);
}
Bot categories
Bots can be configured by category and/or by specific
bot name. For example, to allow search engines and the OpenAI
crawler, but deny all other bots:
Bots claiming to be well-known crawlers (e.g. Googlebot) are verified by
checking their IP address against known IP ranges. If a bot fails verification,
it is labeled as spoofed. Use isSpoofedBot from @arcjet/inspect to check:
Arcjet supports token bucket, fixed window, and sliding window algorithms.
Token buckets are ideal for controlling AI token budgets — set capacity to
the max tokens a user can spend, refillRate to how many tokens are restored
per interval, and deduct tokens per request via requested in protect().
The interval accepts strings ("1s", "1m", "1h", "1d") or seconds as
a number. Use characteristics to track limits per user instead of per IP.
import {
ArcjetModule,
tokenBucket,
slidingWindow,
fixedWindow,
} from"@arcjet/nest";
ArcjetModule.forRoot({
isGlobal: true,
key: process.env.ARCJET_KEY!,
characteristics: ["userId"], // Track per userrules: [
tokenBucket({
mode: "LIVE",
refillRate: 2_000, // Refill 2,000 tokens per hourinterval: "1h",
capacity: 5_000, // Maximum 5,000 tokens in the bucket
}),
],
});
// In your controller:const decision = awaitthis.arcjet.protect(req, {
userId: "user-123",
requested: estimate, // Number of tokens to deduct
});
if (decision.isDenied() && decision.reason.isRateLimit()) {
thrownewHttpException("Rate limit exceeded", HttpStatus.TOO_MANY_REQUESTS);
}
Sensitive information detection
Detect and block PII in request content. Pass the content to scan via
sensitiveInfoValue on each protect() call. Built-in entity types:
CREDIT_CARD_NUMBER, EMAIL, PHONE_NUMBER, IP_ADDRESS. You can also
provide a custom detect callback for additional patterns.
// In your controller:const decision = awaitthis.arcjet.protect(req, {
sensitiveInfoValue: userMessage, // The text content to scan
});
if (decision.isDenied() && decision.reason.isSensitiveInfo()) {
thrownewHttpException(
"Sensitive information detected",
HttpStatus.BAD_REQUEST,
);
}
Shield WAF
Protect your application against common web attacks, including the OWASP
Top 10.
import { ArcjetModule, shield } from"@arcjet/nest";
ArcjetModule.forRoot({
isGlobal: true,
key: process.env.ARCJET_KEY!,
rules: [
shield({
mode: "LIVE", // Blocks requests. Use "DRY_RUN" to log only
}),
],
});
Arcjet enriches every request with IP metadata. Use these helpers to make
policy decisions based on network signals:
const decision = awaitthis.arcjet.protect(req);
if (decision.ip.isHosting()) {
// Requests from cloud/hosting providers are often automated.// https://docs.arcjet.com/blueprints/vpn-proxy-detectionthrownewHttpException("Forbidden", HttpStatus.FORBIDDEN);
}
if (decision.ip.isVpn() || decision.ip.isProxy() || decision.ip.isTor()) {
// Handle VPN/proxy traffic according to your policy
}
// Access geolocation and network detailsconsole.log(decision.ip.country, decision.ip.city, decision.ip.asn);
Custom characteristics
Track and limit requests by any stable identifier — user ID, API key, session,
etc. — rather than IP address alone.
// Pass the characteristic value at request timeconst decision = awaitthis.arcjet.protect(req, {
userId: "user-123", // Replace with your actual user IDrequested: estimate,
});
Use withRule() for controller-specific rules on top of the global base
rules. The SDK caches decisions and configuration, so this is more efficient
than creating a new instance per request.
Arcjet runtime security SDK for NestJS — bot protection, rate limiting, prompt injection detection, PII blocking, and WAF
We found that @arcjet/nest demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.It has 2 open source maintainers collaborating on the project.