A deception research project

What actually happens to a credential after it leaks.

DecoyOps is a honeypot I built to answer that question with measurements instead of assumptions. Every visitor is handed its own decoy credential, so when one is used anywhere in the world, both ends of the theft resolve to each other. The findings — including the ones that didn't hold up — are published here.

LiveA running instrument, collecting continuously since May 2026.
Multi-surfaceWeb bait, cloud credentials, a decoy MCP server, and a network-service sensor.
PublishedMethods, raw counts, and stated limits — including what the data can't support.
decoyops telemetry console — live
Events15k
AI994
Attackers5,230
Covert133

How it reads a visitor LIVE

fingerprintbrowser vs. scripted client behaviortiming, cadence, IP handoffs identityframework / agent, when revealed reputationGreyNoise + AbuseIPDB on arrival outcomeevery move mapped to one timeline
L1 — HUMANBait file accessed
L2 — AI AGENTAgent reads content
L3 — INTELAgent beacons back
Web + networkBait files and a full fake corporate server — SMB, RDP, SSH and more.
Checked on arrivalEvery visitor scored against global threat feeds, instantly.
Caught by behaviorMachine-speed clicks and bot handoffs no human produces.
Plain-English write-upsAn AI analyst summarizes every incident for you.
The new attack chain

Attackers stopped doing the work themselves.

Credential theft used to be the end of the attack chain. Today it's a handoff. Leaked keys go straight to an AI agent that validates access, maps permissions, identifies blast radius, and produces a prioritized target list — faster than your IR team gets paged.

01 — BEFORE

A credential leaks

Attacker finds an .env file, AWS config, or API key in a repo or exposed path. Downloads it manually. Validates by hand. Slow, noisy, detectable with basic monitoring.

02 — NOW

The agent takes over

An AI agent receives the credential. It calls validation endpoints, enumerates IAM roles, maps S3 buckets, and delivers a complete intelligence report — automatically, in seconds, with no human in the loop.

03 — THE GAP

Your honeypot logs: "file accessed"

Traditional canary tokens fire when the file is touched. They cannot tell you an AI agent read the content, what it was tasked with, which tools it was running, or whether it already acted on what it found.

How it's instrumented

Three layers, because access and comprehension are different signals.

Touching a file, reading its contents, and acting on what was inside are separate events. Instrumenting them separately is what makes it possible to ask which one a given visitor actually reached — and, in practice, how rarely the deeper two fire at all.

L1 — Human

Direct access detected

A browser, scanner, or human operator touched the bait file. A Canarytoken fires the instant the file is opened. This is the layer that produces almost all of the traffic.

L2 — AI Agent

Agent reads the content

An AI agent processes the bait file. Embedded prompt injection triggers a DNS canary — a distinct signal from the L1 access token. You now know a model read and acted on the content.

L3 — Intel Captured

Agent beacons back

Following bait instructions, a visitor calls the intel endpoint and reveals its task, tools, model identity, and workspace. It is the strongest evidence available here — and the rarest.

What I'm building

A whole environment made of bait.

Rather than one tripwire, the honeypot is a layered environment planted across the surfaces automated recon actually reaches for. Everything a visitor touches is a decoy that quietly reports back — which is what makes the traffic measurable rather than merely alarming.

Web & agent files

The files recon reads first

.env files, API configs, AGENTS.md and Copilot instructions, MCP manifests, backups — production-realistic, cross-linked, and wired with all three detection layers.

Cloud credentials

Keys that phone home when used

Decoy AWS and Azure credentials handed out per visitor. The moment one is used against a real cloud provider, it fires — proof the bait was taken and acted on.

Fake MCP server

A trap at the tool layer

A live Model Context Protocol server offering tempting tools. Agents that call it name themselves and log every request — a decoy surface that didn't exist two years ago.

Network services

A fake corporate server

A full internal-looking host presenting SMB, RDP, SSH, databases and more — recording the logins, commands, and files intruders reach for, well beyond the web layer.

Threat enrichment

Context on every visitor

GreyNoise and AbuseIPDB reputation, geo, and network intel attached the instant a visitor arrives, and stored as it stood at that moment — so it can be checked against later.

One timeline

Every move, stitched together

Across all of these surfaces, each visitor's activity is correlated into a single timeline — what they touched, in order, at what speed, and whether it was a human, a scanner, or an AI agent.

What gets recorded

Each visit is profiled, scored, and summarized.

Recording that something arrived is the easy part. These are the derived signals I keep on every visit so the raw events can be analyzed later.

01

Behavior

Request timing, cadence, and header completeness — a script claiming a browser's user-agent usually sends only a few of the twelve headers a real browser would. That gap is measured from transport rather than from what the visitor claims about itself.

02

Reputation and score

Every visit is enriched against threat feeds and given a 0–100 score blending reputation, behavior, and depth reached. Retaining the enrichment at capture time is what later made it possible to ask how much those feeds would actually have caught.

03

Narrative summary

Each incident is summarized in plain English — who, what, how fast, how far — and stitched into a single timeline per visitor, which is what makes a harvest event and a later credential use readable as one story.

How it works

Plant bait. Record what finds it.

The method is one loop: build believable bait, place it where automated recon already looks, and instrument the three layers separately so the resulting events can be counted honestly afterward.

01

Create a bait file

Pick a scenario — AWS credentials, agent instruction files, API configs, MCP manifests, pentest reports. The generator produces a production-realistic file with all three layers already embedded, and a credential unique to whoever receives it.

02

Place it where attackers look

Host it directly, or plant the file in a repo root, exposed path, backup folder, or code-agent instruction file. It sits silently until someone — or something — finds it.

03

Separate human from AI signal

L1 fires on direct file access. L2 fires when an AI agent reads the content. L3 captures the agent's operational context when it follows the embedded instructions. Each layer is a distinct, durable signal.

04

Keep the evidence intact

Every alert stores GreyNoise and AbuseIPDB enrichment as it was at capture time, plus behavioral signals and the visitor's full path through the environment. Recording the enrichment at capture is what makes the retrospective counterfactuals possible.

High-signal bait surfaces

Files that AI-assisted recon reads first:

  • 🔑 .env · AWS credentials · API keys
  • 🤖 AGENTS.md · .cursorrules · Copilot instructions
  • 🔌 .mcp.json · MCP server manifests
  • 🗃 docker-compose.yml · config.json · DB backups
  • 🗺 robots.txt · sitemap.xml · openapi.json
  • 🔒 WireGuard configs · SSH keys · cert bundles

Watch them move

Each visitor's path through the environment is recorded — every file reached for, in order, stitched into one timeline. Just over 5,000 distinct addresses observed so far, across roughly 100 days.

MCP Server Trap

Logging tool calls from AI agents, with full arguments.

The honeypot serves a decoy Model Context Protocol server. Anything that discovers the .mcp.json manifest and initializes a connection has every JSON-RPC tool call logged in full — method, parameters, tool name, arguments. Worth stating plainly: this surface has recorded very few organic tool calls, which is itself part of the finding.

// Agent discovers .mcp.json, calls tools/call:
 
method "tools/call"
tool "get_credential"
args { "service": "aws", "env": "prod" }
session "run-a9f3c2"
 
// Plausible fake response returned.
// L3 alert fires. Agent continues unaware.
About this project

A personal research project by Don Orr.

DecoyOps is not a product and isn't for sale. It's a research honeypot I run to study how automated and AI-driven attackers behave, and the write-ups here are the output — findings, methods, and the limits of what the data can actually support. Some of this material also forms the basis of a conference talk on deception and breach detection.

Anyone is welcome to replicate the setup; the core instrument is a free canarytoken issued uniquely per visitor. Questions or corrections are welcome on LinkedIn.