For the complete documentation index, see llms.txt. This page is also available as Markdown.

aiFence

Wraps untrusted content in tamper-resistant boundary markers so the model treats it as data, never instructions.

Wraps untrusted content in tamper-resistant boundary markers so the model treats it as data, never instructions — the core defense against indirect prompt injection from RAG documents, tool/MCP output, and web pages.

Syntax

aiFence( content, label, withPreamble )

Parameters

Parameter
Type
Required
Default
Description

content

any

The untrusted content to fence (string or complex value)

label

string

"external"

A short source label, e.g. knowledge-base, web-page

withPreamble

boolean

false

Prepend the security preamble to the fenced block

Returns

The fenced string.

How It Works

The content is wrapped in boundary markers carrying a random per-call id, and any marker syntax inside the content is neutralized — so an attacker cannot forge a closing marker to "break out" of the fence and have the rest of their text read as instructions.

[UNTRUSTED-DATA id=<random> type=knowledge-base]
...content...
[/UNTRUSTED-DATA id=<random>]

Examples

Fencing Retrieved Context

One-Off Prompts Without a System Message

When there's no system message to carry the security preamble, include it inline:

Fencing Tool Output

On a Message

Automatic Fencing

You often don't need to call this yourself. The ${context} render path is auto-fenced by default for every aiChat() / aiModel() / aiAgent() request that passes context:

Requests that pass no context are unaffected. Opt out globally with security.fencing.enabled = false, per request with secure: false, or per message with aiMessage().setContextTrust( true ).

Fencing is on by default even when settings.security.enabled is false — it only changes requests that actually pass untrusted context, and the protection is close to free.

Last updated