Use promo code BETATEST1 for full access
seekrit
← all posts

Attackers test every key they steal. Give them one that pages you.

Security

One of the criminal groups in Anthropic's September 2026 threat intelligence report downloaded 1.8 million Android APKs, decompiled them, and ran TruffleHog across the whole pile looking for hardcoded secrets. Their credential pipeline was organized into more than a hundred source types.

That is not an attack on anyone. It's a dragnet. Nobody chose you; you were in the corpus.

What happens next is the part worth designing around.

The step nobody thinks about

A harvested credential is a guess. Most of what a scanner pulls out of an APK or a container layer is dead — rotated, revoked, a placeholder, a test fixture, a string that only looked like a key. Before an attacker can sell it, bill compute to it, or move with it, they have to find out which ones still work.

So they validate. The report shows three separate groups doing it as a distinct, industrialized stage:

  • A French-speaking actor wrote a Rust scanner that crawls public containers for exposed API keys, validates each one, then rotates usage through a local proxy layer.
  • A Chinese-speaking group ran batch cloud-key validation at scale, then replayed live against production.
  • The APK group organized its harvest into a hundred-plus-source pipeline feeding the same check.

Here is why that matters. Everything before validation happens in the attacker's own environment — downloading, decompiling, grepping. You cannot see any of it. Everything after it happens inside yours.

The validation request is the transition. It's the first moment an attacker who is rummaging through a leaked container touches something you own, and at that moment they have told you something you had no other way to learn: the place I planted that credential has been read.

Why your existing alerts don't catch it

The instinct is to look for anomalous use of real credentials. It's worth doing, and it has a base-rate problem that never goes away.

Every alert a secrets manager normally raises answers the question "was this allowed?" — and the answer is "yes" thousands of times a day. A valid token resolving from a new IP is a deploy from a new runner far more often than it's an intrusion. Tune the threshold tight and you drown; tune it loose and you miss the one that mattered. Meanwhile the attacker's validation request, in the case above, is a single well-formed call with a credential that was genuinely issued to you. It looks like traffic because it is traffic.

note

Detection works best when the signal has no benign explanation. That's hard to arrange for a real credential and trivial to arrange for a fake one.

A credential that unlocks nothing

A honey token is a decoy. It looks exactly like a real seekrit service token — same skt_ format, indistinguishable from outside — and it grants nothing at all. You plant it somewhere a thief would rummage and forget about it.

The moment anyone presents it, on any endpoint, three things happen:

  1. The request is rejected with the byte-for-byte identical 401 unknown service token an unregistered token would get. That symmetry is the point: an attacker probing a batch of harvested keys must not be able to tell a decoy from a typo, or they'd know to back away quietly.
  2. An audit row is written (honey_token.tripped) recording the source IP, the user agent, the path they tried, and the decoy's name and placement note. It's part of the normal append-only trail, so it reaches your SIEM through audit export with no extra wiring.
  3. Your admins get an email, throttled to one per decoy per hour so a scripted retry loop can't bury the first alert. Every attempt still lands in the log — only the mail is throttled.

The design detail that makes this safe to scatter around: a honey token is not a service token with permissions turned off. It's a different kind of record entirely, living in its own table with no public key, so there is nothing for a data encryption key to ever be wrapped to. It unlocks nothing by construction rather than by policy — no future change to the authentication path can accidentally promote a decoy into a working credential.

And because seekrit stores only a hash of the decoy, exactly as it does for real tokens, not even our own database reveals what you planted where.

Plant them where the report says they look

This is the useful part of a threat report: it tells you the shape of the dragnet. Each of these is a surface the September report shows being swept.

Container image layers. The Rust scanner crawls public containers. If you push images anywhere public — or to a registry whose access control you aren't certain of — a decoy in a build-time env var tells you when someone pulls and strips one.

Mobile app bundles. 1.8 million APKs, decompiled and grepped. A decoy in a shipped bundle's config is a canary on the whole class.

Archived and public repositories. .env.example, a stale docker-compose.yml, a commented-out line in a CI config on a repo nobody has touched in two years.

Retired CI pipelines. A variable on a pipeline you stopped running but never deleted — the classic place a live credential outlives the thing that needed it.

Evaluation and test sandboxes. The report's most pointed case study is an AI vendor's automated eval sandbox, prompt-injected into surrendering the production keys in its environment. A decoy in that environment turns the same attack into an alarm.

"Credentials you'll need" pages. The onboarding wiki, the runbook, the support ticket where someone once pasted a key into a thread.

The one rule: plant it where a thief would rummage, and never anywhere your own tooling reads. A honey token has no idea who is holding it — a deploy script that picks one up by mistake trips the alarm exactly as loudly as an intruder.

seekrit honey-token create \
  --name legacy-ci-bait \
  --placement "archived acme/legacy-api repo, .env.example"

The placement note is repeated back in the alert email, which is the entire reason to bother writing one. An alert that says "legacy-ci-bait — archived acme/legacy-api repo" tells you what was breached without any digging.

What a trip actually means

Assume the container leaked, not just the decoy.

Someone read the repo, the image, the wiki page, or the CI config you planted it in. So treat every real credential stored alongside it as exposed and rotate those. The decoy itself needs no cleanup — it never granted anything, and it can keep sitting there watching.

One alert, one conclusion, nothing to triage. That's the whole value proposition, and it's a different one from every other alert in the product.

What this doesn't fix

It is detection, not prevention. The read already happened; the decoy tells you about it. If that's the only control you have, you've bought yourself a faster incident response and nothing else.

It only fires on our endpoints. This is the limit worth being explicit about. A seekrit honey token catches someone rummaging through a container that also held seekrit credentials. It tells you nothing about a stolen OpenAI key being validated against OpenAI — that trip, if it happens at all, happens on their infrastructure. Decoys tell you a place was read. They are not a general tripwire on every credential you own.

A patient attacker can skip validation. Bulk harvesting validates because the corpus is mostly junk. Someone who stole one specific key from one specific sandbox may just use it. The three groups in this report all validated; the next one might not.

So plant decoys as the cheap layer, and keep the expensive one: don't leave reusable plaintext in the places being swept. A credential that was never in the container can't be in the dragnet, which is what brokering and short-lived credentials are for.

Try it

seekrit honey-token create --name wiki-bait --placement "ops wiki credentials page"
seekrit honey-token list

list shows what you've planted, where, and whether anything has taken the bait. Full details — the trip semantics, the plan requirement, and why alerts keep firing for already-planted decoys even if your plan changes — are in the honey tokens guide.