Canary Tokens: Catching Intruders With Bait They Can't Resist
Canary tokens and honeytokens turn an attacker's curiosity into an early-warning alarm. Here's how I plant fake creds and decoy files to detect breaches fast.
- #security
- #hardening
- #detection
- #honeytokens
- #blue-team
The most useful alert I ever got fired at 3:14 a.m. and read, roughly, “someone just tried to use the AWS key in /opt/legacy/.env.bak.” The thing was, that key never existed. It was a canary token I had planted eight months earlier and completely forgotten about. Within twenty minutes we knew an attacker had pulled a backup off a misconfigured host, and we knew it before they found anything real. That is the entire pitch for honeytokens: you stop trying to catch the breach and instead bait the attacker into announcing themselves.
This is strictly a defensive, blue-team technique. We are planting tripwires on our own infrastructure to detect intrusion early — not probing anyone else’s. Everything below is about detection, not attack.
What a canary token actually is
A canary token is a fake credential, file, URL, or DNS name that has no legitimate use. Nobody on your team should ever touch it. So the moment it is touched — a fake AWS key gets used, a decoy document gets opened, a unique hostname gets resolved — you know someone went somewhere they shouldn’t have. There are no false positives from normal operations, because legitimate operations never reference the token at all.
The cheapest way to start is canarytokens.org, Thinkst’s free generator. You pick a token type, give it an alert email or webhook, and it hands you a payload. For anything beyond a hobby setup, though, you’ll want to self-host so the alert data never leaves your network. The reference deployment is a single Docker Compose stack:
git clone https://github.com/thinkst/canarytokens-docker
cd canarytokens-docker
cp frontend.env.dist frontend.env
cp switchboard.env.dist switchboard.env
# set CANARY_DOMAINS, CANARY_PUBLIC_IP, and SMTP creds in the env files
docker compose up -d
Self-hosting means you control the DNS zone the tokens phone home to, and your alerts go straight into your own SIEM instead of a third party’s inbox.
Fake AWS keys that scream when used
An AWS access key is the perfect honeytoken because it’s valuable, easy to recognize, and trivially testable by an attacker. Canarytokens generates a real-looking but inert key pair tied to an AWS account that does nothing except log every API call attempt.
Drop the generated credentials somewhere plausible — a stale .env, a CI secret, an old ~/.aws/credentials profile:
[backup-legacy]
aws_access_key_id = AKIAQYLPMN5HNL3GEXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
The instant someone runs aws sts get-caller-identity with that key, the token fires with the source IP and the API call attempted. Attackers almost always validate stolen keys this way before pivoting, so you catch them at the reconnaissance stage.
Pro Tip: name the profile something an attacker can’t resist, like prod-admin or root-billing. Greed shortens the time between breach and alert.
Honeytoken files and decoy documents
Files are the workhorse honeytokens. A Word doc, PDF, or Excel sheet can carry an embedded token that beacons out when the file is opened. Name them to attract a thief sifting a compromised file share:
\\fileserver\HR\Compensation_2026_FINAL.docx
\\fileserver\Finance\wire_transfer_credentials.xlsx
/home/svc-deploy/.ssh/prod_rootkey_backup
For plaintext configs and code repos, a fake DB connection string works the same way. Point it at a hostname under your canary domain so any attempt to connect — or even just resolve the host — trips the wire:
database:
host: prod-replica-7.db.internal-canary.example.com
user: app_readwrite
password: "Sup3rS3cr3t-DO-NOT-COMMIT"
Seed these into document repositories, wiki exports, and the kind of secrets.yaml.old files that accumulate in every monorepo.
DNS canaries and decoy S3 buckets
DNS-based tokens are beautifully low-friction: the token is just a unique hostname, and a resolution of that name is enough to alert. You don’t need the attacker to complete a connection — a tool that merely does DNS lookups on discovered strings will give them away.
You can test the alerting path yourself without ever exposing real infrastructure:
dig +short a1b2c3d4e5.canarytokens.example.com
# the lookup itself fires the alert; the answer is irrelevant
Decoy S3 buckets are a variant worth planting if you live in AWS. Create a bucket whose name screams “valuable” and put a canary file in it, then alert on access via CloudTrail data events:
aws s3 mb s3://acme-prod-db-backups-2026
aws s3 cp restore-creds.txt s3://acme-prod-db-backups-2026/
# enable S3 data-event logging, then alert on any GetObject/ListBucket
# from an identity that isn't your monitoring role
Any ListBucket or GetObject against that bucket from anything but your own monitoring identity is, by definition, hostile reconnaissance.
Where to plant them — and where not to
Placement is everything. Tokens belong where attackers look but operators don’t:
- CI/CD environment variables — a fake
AWS_SECRET_ACCESS_KEYin a pipeline that never legitimately calls AWS. - Old config and backup files —
.env.bak,config.old,terraform.tfstate.backup. - Document and wiki repos — decoy runbooks with “emergency root credentials.”
- Internal landing pages — a hidden link or honeytoken URL a scanner will crawl but a human won’t click.
- Browsable file shares — the share is the first stop after a workstation compromise.
Avoid planting them anywhere automation walks: health-check scripts, smoke tests, log scrapers, or paths a backup job traverses. If a cron job opens your decoy doc nightly, you’ve built a false-positive generator, not a detector.
Alerting pipelines and tuning out false positives
A token is only as good as the pipeline behind it. Route the webhook into something that pages a human — Slack, PagerDuty, or your incident tooling — and treat any hit as high-severity by default. A self-hosted Canarytokens server can POST JSON straight to a webhook:
curl -s -X POST https://hooks.example.com/canary \
-H 'Content-Type: application/json' \
-d '{"token":"prod-aws-key","src_ip":"203.0.113.9","channel":"aws_api"}'
Tuning is mostly about cataloguing your own tokens so a real hit is unambiguous. Keep a private inventory — token ID, where it’s planted, what it impersonates, who knows about it — and check fires against it. If a token you control reports a hit from your office IP during a planned audit, that’s noise. A hit from an unknown ASN at 3 a.m. is the real thing.
This inventory work is where an AI assistant genuinely helps. I’ll paste my token registry and recent alert metadata into a model and ask it to cross-reference IPs, flag tokens that overlap with automation paths, and draft the triage runbook. Think of the model as a fast junior security engineer: great at spotting patterns across a wall of text, terrible as a final authority. A human verifies every conclusion before it changes a control. And the hard rule — never hand the model a real secret. Honeytokens are fake by design, so they’re safe to share; your production keys are not, ever. If you’re standardizing that review workflow, the prompts in our security-hardening category and the reusable Prompt Packs give you a tested starting point, and you can iterate on them live in the prompt workspace.
When a token does fire, speed matters more than polish. Feeding the raw alert into an incident-response workflow gets you a containment checklist while the source IP is still warm, and a quick code review pass over your token-planting scripts catches the embarrassing mistake of committing a decoy into a path your CI actually executes. Whichever model you reach for — Claude or otherwise — keep it reasoning over sanitized, fake data only.
Conclusion
Honeytokens flip the economics of detection. Instead of trying to watch every door, you leave a few irresistible, fake valuables lying around and let the attacker’s own curiosity sound the alarm. They’re cheap to plant, near-impossible for an intruder to distinguish from the real thing, and they generate almost no false positives when placed away from automation. Start with one fake AWS key in a backup file this week, wire its alert to your pager, and you’ve bought yourself an early-warning system that most breaches never see coming. Keep it defensive, keep the bait fake, and keep a human in the loop on every alert.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.