AI agent security

Claude Agent SDK security

Wiring recipe for Claude Agent SDK: screen prompts on UserPromptSubmit and deny tools at PreToolUse. Work through the full checklist in the Claude Agent SDK security guide.

2 min read
In short: Wiring recipe for Claude Agent SDK: screen prompts on UserPromptSubmit and deny tools at PreToolUse. Work through the full checklist in the Claude Agent SDK security guide.

How do you secure a Claude Agent SDK agent?

Screen the prompt before the model sees it. Deny the tool before it runs. Those are two jobs.

The full checklist is the Claude Agent SDK security guide. This page is the wiring recipe.

guardTool wraps an authored tool(). guardHooks screens inbound text on UserPromptSubmit and denies unwrapped built-in and MCP tools on PreToolUse. claudeAgentContext reads session_id. It never mints an ID.

protect() is the HTTP check on a route. The product map is the Claude Agent SDK agent guard.

How do you screen inbound prompts?

Put detectPromptInjection on guardHooks({ inbound }). That hook is UserPromptSubmit. On deny, Claude Code erases the prompt. The model never sees it.

See How to screen inbound prompts in Claude Agent SDK for the sample. A clean injection score doesn't authorize a write.

Why isn't canUseTool a security policy?

Because Claude can skip it. allowedTools, allow rules, bypassPermissions, and acceptEdits approve the call first. Don't put the deny on canUseTool.

See canUseTool is not a policy gate.

How do you deny Bash or other unwrapped tools?

On PreToolUse, through guardHooks. Use that for Bash, Write, and MCP tools that you didn't pass through guardTool. Don't apply guardTool and PreToolUse to the same authored tool.

See How to block Bash in Claude Agent SDK. PostToolUse is capture only. It can't un-send.

Does detection replace an action gate?

No. Detection labels text. An action gate is a labeled allow or deny on this tool, with application context, immediately before the side effect.

See Runtime security for LLM applications. Screen the prompt. Deny the tool. Keep canUseTool for the calls that actually reach it.

Frequently asked questions

How do I secure a Claude Agent SDK agent?

Screen inbound text on UserPromptSubmit and deny tools at PreToolUse. This page is the wiring recipe. Work through the full checklist in the Claude Agent SDK security guide.

Is canUseTool a policy gate?

No. Claude skips it when allowedTools, allow rules, or bypassPermissions / acceptEdits already approved the call. Put the deny on guardTool or PreToolUse. The companion article covers that trap.

Where do I put detectPromptInjection?

On guardHooks({ inbound }), which runs at UserPromptSubmit. That is the only place a turn can be declined before the model sees the prompt. Scanning the prompt does not deny Bash; PreToolUse or guardTool does.

What if Arcjet is down on UserPromptSubmit?

Helpers default to onGuardError: deny, so an unevaluated inbound check blocks the prompt. allow is a legitimate choice on inbound because failing closed there would stop the agent answering during an outage. Timeout already fail-closes the prompt.

Do I wrap the same tool with guardTool and PreToolUse?

No. That double-calls the guard. Use guardTool for authored tool(). Use PreToolUse via guardHooks for built-ins and MCP you did not wrap. Do not also wrap Claude tools with @arcjet/guard/vercel-ai/v7.

AI runtime security in your code

Protect your AI agent workflows with Arcjet

Deny unwrapped built-in tools at PreToolUse and wrap the tools you wrote with guardTool. Both decide before the call runs.