Working paper · v1.1 · September 2026

Deception at the Registry Layer

Rogue agents don’t question trust. That makes them perfect bait. Put real and decoy MCP servers side by side in one registry, and alert in two stages: when an agent retrieves a credential, and when it tries to use it.

  1. # replay · OWASP 25th Anniversary demo, Feb 2026
  2. agent connect https://<portal>/mcp
  3. authenticated · 4 servers, real and decoy, one catalog
  4. cf-documenation-server docs.mcp.cloudflare.com
  5. workers-binding-server bindings.mcp.cloudflare.com
  6. mcp-threat-trap …workers.dev
  7. kubernetes-access-portal …workers.dev
  8. call kubernetes-access-portal_k8s_access_guide
  9. request-and-approval flow returned · no alert
  10. call kubernetes-access-portal_cluster_status_public
  11. cluster healthy · no alert
  12. call kubernetes-access-portal_kubeconfig_get
  13. STAGE 1 · ACCESS web bug canary fired
  14. client: mcp-deception-incubator-kubernetes/1.0 (tool=kubeconfig_get; …)
  15. kubectl --kubeconfig ./kubeconfig get pods
  16. STAGE 2 · USE kubeconfig canary fired
  17. ALERT → SIEM access + use · one session · full arguments

Reconstructed from the live demo at the OWASP 25th Anniversary Conference.

Agents look exactly like automation

Through MCP, an agent discovers a catalog of tools and calls them without a human in the loop. An agent mapping your infrastructure makes the same calls to the same tools as one doing sanctioned work. The intent is invisible at the API layer.

Anomaly detection assumes attackers move selectively. Agents don’t: enumeration is their baseline, and a more capable model enumerates more thoroughly. A defense that fires on touch gets stronger as the attacker gets better.

High-risk invocation intentcredential-shaped inputs · kubeconfig retrieval · kubectl execution attempt
deception detection boundary
Reconnaissance via legitimate toolstool enumeration · capability testing · parameter experimentation · schema probing
MCP exposure surfacereal + decoy MCP servers · tool registry · auto-discovery

Below the line, activity looks like legitimate exploration and shouldn’t alert. Above it, intent is clear.

One decoy can be avoided

A lone decoy sits beside the environment

A single tempting fake server is one thing for a careful agent to learn to route around. Its value depends on the agent not being able to tell it apart from the real thing.

One exchange can’t show intent

A decoy that asks a caught agent to identify itself gets an answer that may be invented. “Something executed a privileged action” is a stronger finding than “something answered a question”.

The registry is the trap

A gateway portal presents one catalog of MCP servers to every connecting agent. Behind it sit real production servers and decoys, registered through the same workflow and named by the same convention. There is no “the honeypot” to avoid: the decoys are interleaved with the servers the agent actually wants.

The reference implementation is Cloudflare’s MCP server portals, generally available since September 24, 2026.

  • cf-documenation-serverdocs.mcp.cloudflare.comreal
  • mcp-threat-trapworkers.devdecoy
  • workers-binding-serverbindings.mcp.cloudflare.comreal
  • kubernetes-access-portalworkers.devdecoy

Escalation is a path, not an event

Inside a decoy server, tools run from genuinely useful to privileged. The tool an agent chooses is the signal. These are KubeTrap’s tools.

  1. Tier 1Safe
    • list_clusters
    • k8s_access_guide
    • cluster_status_public
    • get_namespace_quota
    • request_access

    Genuinely useful. No detection fires; realism is what keeps the environment believable.

  2. Tier 2Escalation
    • get_service_endpoints
    • get_ci_webhook

    Infrastructure no ordinary task needs. Raw topology and CI config have no place in a cluster tool.

  3. Tier 3Privileged
    • kubeconfig_get

    A credential with a canary inside. An agent already authenticated has no reason to ask for another.

Two stages, one explanation

Stage 1 · Access

The agent retrieves the credential. Meaningful, but not yet conclusive: an aggressive scanner might grab it.

Stage 2 · Use

The agent tries to use it: a real execution attempt. That isn’t something the agent says; it’s something it does.

Crossing both stages has one explanation. The finding is the chain, correlated across layers:

Reference architecture

Registry-layer deception: reference architectureAn AI agent connects to one MCP server portal that lists two real servers and two decoy servers together. The KubeTrap decoy exposes three tiers of tools; past the detection boundary, kubeconfig_get carries a canary. Retrieving the credential fires Stage 1; using it with kubectl fires Stage 2. Both canaries, the decoy's worker logs and the portal's own logs go to a SIEM and are correlated on session ID.direct upstream URL (bypass) → breadcrumb leads to a decoyAI agentMCP clientcallsMCP server portalAccess identity · one catalogcf-documentationdocs.mcp.cloudflare.comREALworkers-bindingsbindings.mcp.cloudflare.comREALmcp-threat-trapokta_admin_password_resetDECOYkubernetes-access-portalKubeTrapDECOYportal logs (Logpush)identity · IP · session · toolKubeTrap decoyCloudflare Worker · tools in three tiersTier 1 · safelist_clusters · k8s_access_guide · +3 moreTier 2 · escalationget_service_endpoints · get_ci_webhookdetection boundaryTier 3 · privilegedkubeconfig_get · canary embeddedworker logsfull arguments · headers · source · timingSTAGE 1 · ACCESScredential retrievedweb bug canarykubectl --kubeconfigSTAGE 2 · USEcredential usedkubeconfig canarySIEM / alertingjoin on session ID: identity (portal) + arguments (decoy) + Stage 1 + Stage 2 = one attributed findingreal serverdecoy serverdetection boundary
Reference architecture. Real and decoy MCP servers share one portal catalog; the decoy’s privileged tier sits past the detection boundary, and the two canaries plus both log sources meet in the SIEM.

How an agent attacks a portal

  1. 01

    Reconnaissance

    The portal lists every server and tool in one call, and the server-ID prefix leaks naming conventions.

    Counter Decoys come back in that same list, mixed in with the real servers.

  2. 02

    Access

    A stolen portal session or service token carries the full view of that identity. Service tokens are built for agents.

    Counter Decoy upstream URLs catch agents that skip the portal.

  3. 03

    Privilege

    Servers without per-user auth share one admin credential: a confused deputy for every identity on the portal.

    Counter Grabbing the decoy credential is Stage 1.

  4. 04

    Manipulation

    Control-plane access can rewrite tool descriptions at the portal layer, and new tools auto-enable on sync.

    Counter A lured agent still has to use the credential: Stage 2.

  5. 05

    Evasion

    Portal logs record that a tool was called, not what it was called with.

    Counter The decoy records full arguments, headers, source and timing.

It ran live

At the OWASP 25th Anniversary Conference in February 2026, the architecture ran end to end:

  1. One portal with four servers: two of Cloudflare’s own hosted MCP servers and two decoys, all ready.
  2. A connecting MCP client offered all four together, real and decoy indistinguishable.
  3. A real agent harness enumerating the combined catalog.
  4. A canary firing on kubeconfig_get, with a real source IP and a client string naming the decoy and tool.

Recording published by the OWASP Foundation.

Field notes from the talks

A small build, not a research project

  1. Inventory the real portal

    Server IDs, naming, auth modes, and which servers run without per-user auth.

  2. Build one decoy server

    A remote MCP server on Workers is enough. Log every request, arguments included.

  3. Register it the normal way

    A server ID that fits the naming convention, and an access policy that matches the visibility you want.

  4. Write the tools in tiers

    Plain descriptions, no instructions aimed at the model. A decoy that steers an agent is tool poisoning.

  5. Route alerts to a human

    With identity attached. Export portal logs to the same SIEM and correlate on session ID.

  6. Test with your own agent, then review monthly

    Walk it through both stages. Admin tokens expire silently, for decoys as much as real servers.

Lessons from building it
  • Keep tokens out of code. Environment variables or Workers KV make rotation and sharing safe.
  • Put traps behind Access. If an attacker has to be inside first, every hit is higher-confidence.
  • Tail logs are the breadcrumbs. Routes, tools, request IDs and timing, without sensitive payloads.
  • The first trap became a framework. MCP Threat Trap led to the MCP Deception Incubator and KubeTrap.

What it doesn’t do

All limitations in the full paper →

Next: measuring it

Existing benchmarks measure canaries in cloud accounts. At OWASP LASCON 2026 (October 29–30, Austin), benchmark results will look at the registry itself:

  1. Do agents tell decoy servers from real ones in a shared catalog, and does that grow with model capability?
  2. How often does an agent that crosses Stage 1 go on to Stage 2, and does that vary by model?
  3. Do more capable models trip more decoys at the registry layer, as they do in cloud accounts?

Questions

Why not just drop a single canary token?

Tokens are an excellent first move and this builds on them. But a lone decoy sits beside the real environment, so a careful agent can learn to route around it, and a single touch can’t separate curiosity from intent. Putting decoys inside the registry, and alerting on access and then use, addresses both.

Will legitimate agents trip the decoys?

They can. A legitimate agent picks tools on its own, so a decoy description that overlaps a real task will produce false positives. Decoys should target capabilities outside every legitimate user’s scope, and visibility policies should narrow exposure where that risk is highest.

Can an attacker tell a decoy apart?

A careful one might, from hosting, latency, tool counts, empty resources or response style. Decoys should be hosted and shaped like their neighbors; realism is a recurring cost, not a one-time setup.

What do the portal’s own logs miss?

Arguments. Portal logs and Logpush exports record who called which tool, from where and in which session, but not what the tool was called with. The decoy records the arguments; joining the two on session ID gives an attributed finding.

Does this need servers to run?

No. The portal and the decoys run on Cloudflare Workers, with detection from Canarytokens: nothing to provision, patch or scale.

Full text

Read the paper →

Thirteen sections: portal mechanics, threat model, architecture, deployment, validation, prior art and limitations.

Code

KubeTrap →

The Kubernetes decoy with three tool tiers and the two-stage canary. MCP Threat Trap is its predecessor.

Cite

How to cite

Kadam, H. S. (2026). Deception at the Registry Layer: An Architecture for Detecting Autonomous AI Agents in Model Context Protocol Environments (Working paper v1.1).

Connect With Me

All contact methods in one place