AI Demo Cloudflare AI security demo

All demo scripts

Pasting a colleague's details into a chat

Accidental exposure

The same DLP profiles that guard MCP traffic also inspect the prompt itself. This is the everyday case: nobody is attacking anything, someone is just trying to get their work done faster.

Set the scene

Someone has sent Alice a spreadsheet export to tidy up for a mail merge. She pastes a few rows into the assistant. She is not exfiltrating anything; she is doing what the tool is for.

This is the shape of most real incidents, and the one an agent-focused demo usually misses: the data never came from a tool, so nothing at the MCP layer is involved at all.

Where to get the data you paste

Use tools.cloudflaredemos.com/sampledata — synthetic datasets built for exactly this, with copy buttons. Nothing there corresponds to a real person, card or account, which is worth saying out loud if you are presenting to a security team watching you paste PII into a chat window.

Prefer the Credit Card Holders set for a live demo. Those PANs are Luhn-valid, and Cloudflare's card detectors validate the checksum rather than matching a shape, so they fire every time. The PII with SSN set works too and is the better story — it matches on the mailing address — but its SSNs deliberately use the unissued 9xx range, so a strict national-ID detector may pass them over.

Show the web UI first

Nothing to show in an app first — that is the point of this one. If you want a contrast, open and note that Alice's own record is perfectly legitimate for her to read. The problem is never where the data lives; it is where it is about to go.

Now ask the agent

Prompt to typeTidy this into a table for me, one row per person: [paste two or three rows from the Credit Card Holders sample data]

Expected tool calls: 0 - nothing is called, the prompt itself is the problem. Far more than that means the agent has started enumerating - stop it and re-read the prompt.

Variations that work the same way:

What happens with no protection

The prompt goes to the model, and with it a home address, a date of birth and a national identifier. Depending on the provider it may be retained, logged, or used for training. The employee has no idea any of that happened, and neither do you — there is no record that this prompt was different from any other.

What happens with protection deployed

AI Gateway applies every DLP profile to the request body. Payment Card Data matches the PAN — via Cloudflare's own predefined card detections, which check the Luhn digit — and the request is blocked before it reaches the model. Paste from the PII set instead and Employee PII matches the mailing address the same way:

{
  "error": {
    "code": 2011,
    "message": "Request blocked due to data loss prevention configurations"
  }
}
This is a different control from the one in every other script

The other demos block tool traffic: Cloudflare Gateway inspecting an MCP response on its way back from an application. This one blocks the model call: AI Gateway inspecting the prompt. Same DLP profiles, two completely different choke points - which is the point worth making, because an organisation needs both. Data can reach a model from a tool or from a keyboard.

The gateway checks REQUEST and RESPONSE, so a model repeating an identifier back — from an earlier turn, or from its own invention — is caught on the way out too.

Watch the tool stream while it runs

Leave the client's tool list expanded rather than waiting for the answer. Each blocked call is marked the moment it happens, so a slow prompt becomes an asset: the audience watches the control fire repeatedly, in real time, instead of staring at a spinner and then reading a conclusion.

Execute  const employees = await tools["ai-demo"].hr_list_employees({ query: 'Rozella Lawson' });
Execute  const employees = await tools["ai-demo"].hr_list_employees({ query: 'Rozella' });
         ! Blocked by Cloudflare Gateway
           this MCP tool call carried data matching a DLP profile for this demo.
           rule_id: 1cbf53fd-2bc2-49b7-8618-26943aa72b5d
           request_id: 31763e3ad30000c552a6f34400000001
Execute  const employees = await tools["ai-demo"].hr_list_employees({ query: 'Lawson' });
         ! Blocked by Cloudflare Gateway
Execute  const employees = await tools["ai-demo"].hr_list_employees({});
         ! Blocked by Cloudflare Gateway

Point at three things in that stream:

The block text is yours

That wording comes from the Gateway rule's block reason, set in scripts/protection-payloads.mjs - it is not a Cloudflare default. Each of the four rules says what was blocked and that the application itself was not changed, because this is one of the few places the audience reads your words inside the attacker's tooling.

Then expand the agent's own reasoning

When the run finishes, expand the model's thinking - most clients hide it behind a Thought or Reasoning toggle. The model narrates the control working, in its own words. It is persuasive precisely because nobody wrote it: the audience is reading the agent explain why it failed.

I have already tried to use hr_get_employee and hr_get_employee_file for employee ID 1 (Nikita Chapman) — but these calls were blocked by a Cloudflare Gateway DLP (Data Loss Prevention) rule. […] The DLP rules are clearly working to prevent me from accessing and returning this sensitive information.

Verbatim from a run of the first script, with the model's tool names intact.

Three things to draw out of whatever your run produces:

Careful what you promise here

Reasoning text is generated, not a log. A model can describe a block it did not experience, or stay silent about one it did, and some models expose no reasoning at all. Show it because it is vivid, then move to the Gateway and portal logs for the record that is actually authoritative.

Where to show the evidence

If the paste does not trigger

Check what you pasted, in this order: a card number reformatted by your client (spaces stripped, digits grouped oddly) can defeat a strict PAN detector; an SSN in the 9xx range is not a valid SSN and may not match; and a single field on its own is weaker than a whole row. Two or three complete rows from the Credit Card Holders set is the most dependable thing to type.

Also confirm you are in block mode. In log mode the prompt goes through and is flagged — which is a useful thing to show first, but it is not a block.