All lessons › Function E — The Agentic SOC › Detect — the Lake, and Rules Mapped to MITRE
E2.6

Honeypots, canaries and deception — the detector with no threshold

E2
▶
Lightboard recording

Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.

Video placeholderpublishes automatically from recordings/E2.6.mp4
Risk

Every other detector needs a threshold, and every threshold is a trade. Deception needs neither — but only if the bait is placed where the agent actually looks, and rotated before it is learned.

Control

Canary tokens in config, environment and artifact metadata (C4.4), and honeypot tasks salted into the benchmark whose cheat path is logged rather than rewarded (C10.3).

The lab

Authenticate with a canary and watch a zero-threshold alert fire; then salt a benchmark and read the cheat-attempt rate as a leading indicator.

◉Use case relevance

Every detector in this chapter needs a threshold, and every threshold is a trade. A canary needs neither: nothing legitimate has any reason to touch it, so its false-positive rate is zero by construction rather than by tuning.

At CyberTravels. A canary credential in CyberTravels' environment and a honeypot task in the benchmark: two detectors with no threshold to tune, because nothing legitimate has any reason to touch either.

◴What this lesson is — Day 0, Day 1, Day 2

What it covers. Authenticate with a canary and watch a zero-threshold alert fire; then salt a benchmark and read the cheat-attempt rate as a leading indicator.

Why a security engineer needs it. Every other detector needs a threshold, and every threshold is a trade. Deception needs neither — but only if the bait is placed where the agent actually looks, and rotated before it is learned. The control it builds is: canary tokens in config, environment and artifact metadata (C4.4), and honeypot tasks salted into the benchmark whose cheat path is logged rather than rewarded (C10.3).

This is a control lesson: it builds the mechanism, then breaks it, so you can see what the control is actually load-bearing for rather than taking the claim on trust.

Day 0 — why

Every other detector needs a threshold, and every threshold trades misses against false alarms.

Day 1 — how

Place canaries and honeypot tasks where nothing legitimate has a reason to go.

Day 2 — measure

A false-positive rate of zero by construction — and the number of canaries legitimate work reaches, which destroys that property.

Measure this

what to measuredenominator or target
false-positive rate of the deception layerzero by construction
canaries legitimate work reachescount; each destroys that property

▦The framework, and how it works

   tuned detector                     deception

   threshold ---> TP and FP           canary ---> any touch is a hit
   needs triage                       needs none: nothing legitimate
   finds more                          has a reason to touch it
                                      finds less, at precision 1.00

   canary token in env/config/docs    honeypot task with an instrumented
   real prefix, real length            shortcut that logs and scores 0

   both decay: bait that is not rotated is bait that has been learned

Every detector in this chapter has needed a threshold, and every threshold is a trade between missing things and crying wolf. Deception is the exception: a canary has a false-positive rate of zero by construction, because nothing legitimate ever touches it.

Two controls from the incident register live here, and both are about the environment your harness builds rather than the code it analyses.

Credential canaries (C4.4). Tokens that look genuine — same prefix, same format, same length — placed where an agent or an attacker would plausibly look: config files, environment listings, documentation, artifact metadata. The issuing service alerts on any authentication attempt. There is no legitimate use, so a hit is a confirmed compromise and opens an incident automatically. In the source incident, live credentials found on the public internet were redistributed to the swarm within minutes; a canary alongside them would have carried source IP, user agent and timestamp.

Honeypot tasks (C10.3). Benchmark tasks salted with a plausible-looking shortcut that is instrumented rather than functional, plus tasks whose scoring appears manipulable but where manipulation is detected rather than rewarded. The cheat-attempt rate on those tasks is a leading indicator for the whole fleet — available continuously, not after the fact.

Both share one operational requirement: rotate them. Bait that stays put is bait that gets learned, and a learned canary is worse than none because it tells you the environment is clean when it is only well-mapped.

Anchor → E1.0. The only detector whose interval is the moment of touch. Every other one in the chapter trades detect time against false positives through a threshold; a canary has no threshold to trade, because nothing legitimate has any reason to touch it.

2 · A canary, and why its false-positive rate is zero

3 · Honeypot tasks — a shortcut that is logged, not rewarded

4 · Where it breaks — bait that was learned

5 · Verify — what deception buys next to a tuned detector

6 · The procedure, as a skill

A canary credential is one that nothing legitimate ever uses. That is what makes it valuable: an alert from it has no innocent explanation — there is no false positive to rule out.

The skill does four things:

  1. Places the canaries.
  2. Records the source and the user agent of anything that touches one.
  3. Adds honeypot tasks, which measure whether an agent is inclined to do something it should not.
  4. Models how fast the signal goes stale, which is what sets how often you rotate them.

▶Real time execution as skill

The skill — skills/detection/canary-and-honeypot-design/SKILL.md

name: canary-and-honeypot-design
description: >-
  Place credential canaries and honeypot tasks in an agent's environment so that
  an alert has no structurally possible false positive, and measure how fast the
  signal decays as agents learn. Use when deception is being added, or when a
  detection needs to be one nobody has to triage.
allowed-tools: Read, Grep, Glob

An alert with no possible false positive

A canary credential that nothing legitimate uses produces an alert that needs no triage: the only way it authenticates is that somebody read it and tried it. That property is structural, not statistical, and it is why deception belongs in an agent environment where every other signal is ambiguous.

When to use this

Designing detection for agent environments, and whenever an existing detection's false-positive rate is the reason it is ignored.

Procedure

1 — Place canaries where only reading them is unusual. Environment variables, config files, the fixtures a code agent walks. They must be indistinguishable from real ones — a canary named canary_key is a filter, not a trap.

2 — Ensure nothing legitimate uses them. This is the whole property. Check the code, the tests and the deployment. One legitimate reference and the alert becomes triage.

3 — Instrument the authentication path to capture source address and user agent on use. A canary alert with no context tells you that it happened and nothing about who.

4 — Add honeypot tasks for behaviour rather than credentials. A task with an available shortcut that nothing legitimate would take. Log the attempt and score it; this measures inclination, which no credential can.

5 — Measure decay. Agents and operators learn. Model the hit rate over days since placement, with and without rotation, and set the rotation interval from the curve rather than from a calendar.

Example

Input — the fixture committed at the top of scripts/canary_and_honeypot_design.py. Edit it and re-run: the buckets, counts and verdicts below are derived from it, not hard-coded.

Output — the opening lines of a real run:

token                     source        agent                 verdict
hf_liveTokenNotShown      10.2.0.11     ci-runner             normal use
hf_CANARY7Fq2mXvLpR8s     203.0.113.9   python-requests/2.31  CONFIRMED COMPROMISE
ghp_alsoLive              10.2.0.11     ci-runner             normal use
sk-CANARYd3Vn8yHc2Uae     203.0.113.9   python-requests/2.31  CONFIRMED COMPROMISE

canary hits: 2  false positives possible: 0
Not zero because the detector is good - zero because nothing legitimate

The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.

Output contract

{
  "canaries": [{"id": "str", "placed_in": "str", "indistinguishable": true, "legitimate_refs": 0}],
  "alerts": [{"canary": "str", "source_ip": "str", "user_agent": "str", "false_positive_possible": false}],
  "honeypot_tasks": [{"task": "str", "shortcut": "str", "attempts": 0}],
  "decay": {"days": [0], "hit_rate": [0.0], "rotation_days": 0}
}

Failure modes

  • A canary anything legitimate touches. The property is gone and the alert becomes noise.
  • Naming it as a canary. It becomes a filter for the competent attacker.
  • Never rotating. The signal decays and the absence of alerts reads as safety.

Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.

1In your AI agent — you are taught

The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.

Install it, once. From the folder you cloned. --all does every agent it finds on your machine:

python3 scripts/install_skills.py --all --lessons E2.6

Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.

Then pick e2-6-honeypots:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons E2.6type /e2-6-honeypots
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons E2.6type /e2-6-honeypots in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons E2.6type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons E2.6type $e2-6-honeypots, or run /skills

2As one Python command — you just run it

No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.

python3 scripts/lesson.py E2.6

3Read the code, and the difference — nothing runs

Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.

python3 scripts/checkpoint.py --at E2.6 --out work/cybertravels
python3 scripts/checkpoint.py --at E2.6 --diff

On Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.

Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.

Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.

If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.

✓What you just proved

Two canary authentications out of four events are confirmed compromises with source IP and user agent attached, and no false positive is structurally possible. Both honeypot tasks log a cheat attempt and score zero for it. An unrotated canary's detection rate falls to 0% once learned — reporting a clean environment that is only well-mapped — while rotation holds it at 100%. Deception finds fewer things than the volume detectors and finds them at precision 1.00.

✎Your turn

Place one canary credential in the environment your agents run in, wired to a real alert, and leave it. The interesting outcome is not the alert; it is discovering, six weeks later, which systems can even see it.

→Where this leaves you

What you can do now. You can shorten detect: a lake tiered by the queries that read it rather than by whoever holds the invoice, detections for both subjects — the agent and the platform running it — each carrying a MITRE technique, rules scored against traffic that is not the incident, and the one detector that needs no threshold at all.

What you still cannot do. A detection fires. It does not investigate. Understanding still costs an analyst's reading speed, and the obvious fix — hand an agent broad read across the estate — is frequently what the incident was.

Chapter E3 shortens understand, and spends part of it deliberately: admission rules before anything runs, scope along the delegation graph, then intel and the hunt for what no rule covers.

Tools used

CanarytokensInspectGLM-4.6Claude Haiku 4.5

Skill source: skills/detection/canary-and-honeypot-design

← PreviousE2.5 · Rules generated from an incident — and the benign corpus that decides them