Skip to content

Arcjet Guards

Guards apply Arcjet security rules inside AI agent tool calls and anywhere else you process untrusted input. Pass inputs directly, get a decision back. No Request object needed.

They are for the places HTTP middleware can’t reach: inside tool handlers, between agent steps, in queue consumers, and across agentic pipelines that fan out across many services.

Stop hidden instructions from hijacking your agent

Section titled “Stop hidden instructions from hijacking your agent”

A webpage your agent fetched contains hidden instructions telling it to email your customer list to an attacker. Guards detects the prompt injection before that content re-enters the model’s context.

A runaway agent loop burns $8,000 in model spend overnight. Guards enforces per-user token budgets inside the loop itself, denying calls once the bucket is empty.

A background job ships support tickets to a third-party LLM for summarization. Guards blocks personally identifiable information (emails, card numbers, etc.) before the message leaves your system.

Install the add-guard-protection skill into your AI coding agent. It will detect your language, install the package, configure rules, and wire up guard() calls inline in your tool handlers.

Supported languages: JavaScript / TypeScript (@arcjet/guard >= 1.4.0) and Python (arcjet >= 0.7.0).

Terminal window
npx skills add arcjet/skills --skill add-guard-protection

Then describe what you want to protect — for example: “rate limit my tool calls per user and block prompt injection” or “secure my MCP server” or “protect my queue worker”.

import { launchArcjet, tokenBucket, detectPromptInjection } from "@arcjet/guard";
const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });
const userLimit = tokenBucket({
label: "user.tool_call_bucket",
bucket: "tool-calls",
refillRate: 100,
intervalSeconds: 60,
maxTokens: 500,
});
const piRule = detectPromptInjection();
async function searchWeb(query: string, userId: string) {
const decision = await arcjet.guard({
label: "tools.search_web",
metadata: { userId },
rules: [
userLimit({ key: userId, requested: 1 }),
piRule(query),
],
});
if (decision.conclusion === "DENY") {
throw new Error(`Blocked: ${decision.reason}`);
}
// Safe to proceed
}
import os
from arcjet.guard import launch_arcjet, TokenBucket, DetectPromptInjection
arcjet = launch_arcjet(key=os.environ["ARCJET_KEY"])
user_limit = TokenBucket(
label="user.tool_call_bucket",
bucket="tool-calls",
refill_rate=100,
interval_seconds=60,
max_tokens=500,
)
pi_rule = DetectPromptInjection()
async def search_web(query: str, user_id: str):
decision = await arcjet.guard(
label="tools.search_web",
metadata={"user_id": user_id},
rules=[
user_limit(key=user_id, requested=1),
pi_rule(query),
],
)
if decision.conclusion == "DENY":
raise RuntimeError(f"Blocked: {decision.reason}")
# Safe to proceed