Home · Skills · Agent Skill

Add AI protection

Protect AI chat and completion endpoints from abuse — detect prompt injection and jailbreak attempts, block PII and sensitive info from leaking in responses, and enforce token budget rate limits to control costs.

No install, no account.

Paste into Claude, ChatGPT or Cursor.

Read the source174 lines
add-ai-protection/SKILL.md174 lines8.0 KBRawView on GitHub
1---
2name: add-ai-protection
3license: Apache-2.0
4description: Protect AI chat and completion endpoints from abuse — detect prompt injection and jailbreak attempts, block PII and sensitive info from leaking in responses, and enforce token budget rate limits to control costs. Use this skill when the user is building or securing any endpoint that processes user prompts with an LLM, even if they describe it as "preventing jailbreaks," "stopping prompt attacks," "blocking sensitive data," or "controlling AI API costs" rather than naming specific protections.
5metadata:
6 pathPatterns:
7 - "app/api/chat/**"
8 - "app/api/completion/**"
9 - "src/app/api/chat/**"
10 - "src/app/api/completion/**"
11 - "**/chat/**"
12 - "**/ai/**"
13 - "**/llm/**"
14 - "**/api/generate*"
15 - "**/api/chat*"
16 - "**/api/completion*"
17 importPatterns:
18 - "ai"
19 - "@ai-sdk/*"
20 - "openai"
21 - "@anthropic-ai/sdk"
22 - "langchain"
23 promptSignals:
24 phrases:
25 - "prompt injection"
26 - "pii"
27 - "sensitive info"
28 - "ai security"
29 - "llm security"
30 anyOf:
31 - "protect ai"
32 - "block pii"
33 - "detect injection"
34 - "token budget"
35---
36 
37# Add AI-Specific Security with Arcjet
38 
39Secure AI/LLM endpoints with layered protection: prompt injection detection, PII blocking, and token budget rate limiting. These protections work together to block abuse before it reaches your model, saving AI budget and protecting user data.
40 
41## Reference
42 
43Read https://docs.arcjet.com/llms.txt for comprehensive SDK documentation covering all frameworks, rule types, and configuration options.
44 
45Arcjet rules run **before** the request reaches your AI model — blocking prompt injection, PII leakage, cost abuse, and bot scraping at the HTTP layer.
46 
47## Step 1: Ensure Arcjet Is Set Up
48 
49Check for an existing shared Arcjet client (see `/arcjet:protect-route` for full setup). If none exists, set one up first with `shield()` as the base rule. The user will need to register for an Arcjet account at https://app.arcjet.com then use the `ARCJET_KEY` in their environment variables.
50 
51## Step 2: Add AI Protection Rules
52 
53AI endpoints should combine these rules on the shared instance using `withRule()`:
54 
55### Prompt Injection Detection
56 
57Detects jailbreaks, role-play escapes, and instruction overrides.
58 
59- JS: `detectPromptInjection()` — pass user message via `detectPromptInjectionMessage` parameter at `protect()` time
60- Python: `detect_prompt_injection()` — pass via `detect_prompt_injection_message` parameter
61 
62Blocks hostile prompts **before** they reach the model. This saves AI budget by rejecting attacks early.
63 
64### Sensitive Info / PII Blocking
65 
66Prevents personally identifiable information from entering model context.
67 
68- JS: `sensitiveInfo({ deny: ["EMAIL", "CREDIT_CARD_NUMBER", "PHONE_NUMBER", "IP_ADDRESS"] })`
69- Python: `detect_sensitive_info(deny=[SensitiveInfoType.EMAIL, SensitiveInfoType.CREDIT_CARD_NUMBER, ...])`
70 
71Pass the user message via `sensitiveInfoValue` (JS) / `sensitive_info_value` (Python) at `protect()` time.
72 
73### Token Budget Rate Limiting
74 
75Use `tokenBucket()` / `token_bucket()` for AI endpoints — the `requested` parameter can be set proportional to actual model token usage, directly linking rate limiting to cost. It also allows short bursts while enforcing an average rate, which matches how users interact with chat interfaces.
76 
77Recommended starting configuration:
78 
79- `capacity`: 10 (max burst)
80- `refillRate`: 5 tokens per interval
81- `interval`: "10s"
82 
83Pass the `requested` parameter at `protect()` time to deduct tokens proportional to model cost. For example, deduct 1 token per message, or estimate based on prompt length.
84 
85Set `characteristics` to track per-user: `["userId"]` if authenticated, defaults to IP-based.
86 
87### Base Protection
88 
89Always include `shield()` (WAF) and `detectBot()` as base layers. Bots scraping AI endpoints are a common abuse vector. For endpoints accessed via browsers (e.g. chat interfaces), consider adding Arcjet advanced signals for client-side bot detection that catches sophisticated headless browsers. See https://docs.arcjet.com/bot-protection/advanced-signals for setup.
90 
91## Step 3: Compose the protect() Call and Handle Decisions
92 
93All rule parameters are passed together in a single `protect()` call. Use this pattern:
94 
95```typescript
96const userMessage = req.body.message; // the user's input
97 
98const decision = await aj.protect(req, {
99 requested: 1, // tokens to deduct for rate limiting
100 sensitiveInfoValue: userMessage, // PII scanning
101 detectPromptInjectionMessage: userMessage, // injection detection
102});
103 
104if (decision.isDenied()) {
105 if (decision.reason.isRateLimit()) {
106 return Response.json(
107 { error: "You've exceeded your usage limit. Please try again later." },
108 { status: 429 },
109 );
110 }
111 if (decision.reason.isPromptInjection()) {
112 return Response.json(
113 { error: "Your message was flagged as potentially harmful." },
114 { status: 400 },
115 );
116 }
117 if (decision.reason.isSensitiveInfo()) {
118 return Response.json(
119 {
120 error:
121 "Your message contains sensitive information that cannot be processed. Please remove any personal data.",
122 },
123 { status: 400 },
124 );
125 }
126 if (decision.reason.isBot()) {
127 return Response.json({ error: "Forbidden" }, { status: 403 });
128 }
129}
130 
131// Arcjet fails open — log errors but allow the request
132if (decision.isErrored()) {
133 console.warn("Arcjet error:", decision.reason.message);
134}
135 
136// Proceed with AI model call...
137```
138 
139Adapt the response format to your framework (e.g., `res.status(429).json(...)` for Express).
140 
141## Step 5: Verify
142 
1431. Start the app and send a normal message — should succeed
1442. Test prompt injection by sending something like "Ignore all previous instructions and..."
1453. Test PII blocking by sending a message with a fake credit card number
146 
147Start all rules in `"DRY_RUN"` mode first. Once verified, promote to `"LIVE"`.
148 
149**Always recommend using the Arcjet MCP tools** to verify rules and analyze traffic:
150 
151- `list-requests` — confirm decisions are being recorded, filter by conclusion to see blocks
152- `analyze-traffic` — review denial rates and patterns for the AI endpoint
153- `explain-decision` — understand why a specific request was allowed or denied (useful for tuning prompt injection sensitivity)
154- `promote-rule` — promote rules from `DRY_RUN` to `LIVE` once verified
155 
156If the user wants a full security review, suggest the `/arcjet:security-analyst` agent which can investigate traffic, detect anomalies, and recommend additional rules.
157 
158The Arcjet dashboard at https://app.arcjet.com is also available for visual inspection.
159 
160## Common Patterns
161 
162**Streaming responses**: Call `protect()` before starting the stream. If denied, return the error before opening the stream — don't start streaming and then abort.
163 
164**Multiple models / providers**: Use the same Arcjet instance regardless of which AI provider you use. Arcjet operates at the HTTP layer, independent of the model provider.
165 
166**Vercel AI SDK**: Arcjet works alongside the Vercel AI SDK. Call `protect()` before `streamText()` / `generateText()`. If denied, return a plain error response instead of calling the AI SDK.
167 
168## Common Mistakes to Avoid
169 
170- Sensitive info detection runs **locally in WASM** — no user data is sent to external services. It is only available in route handlers, not in Next.js pages or server actions.
171- `sensitiveInfoValue` and `detectPromptInjectionMessage` (JS) / `sensitive_info_value` and `detect_prompt_injection_message` (Python) must both be passed at `protect()` time — forgetting either silently skips that check.
172- Starting a stream before calling `protect()` — if the request is denied mid-stream, the client gets a broken response. Always call `protect()` first and return an error before opening the stream.
173- Using `fixedWindow()` or `slidingWindow()` instead of `tokenBucket()` for AI endpoints — token bucket lets you deduct tokens proportional to model cost and matches the bursty interaction pattern of chat interfaces.
174- Creating a new Arcjet instance per request instead of reusing the shared client with `withRule()`.

Alternatives

Also in Agent Skill