DEV Community

Cover image for Stratagems #17: Alex Set an AI Bait. The Catch Wasn't Code — It Was Someone Who Shouldn't Have Been Watching.
xulingfeng
xulingfeng

Posted on

Stratagems #17: Alex Set an AI Bait. The Catch Wasn't Code — It Was Someone Who Shouldn't Have Been Watching.

Linear 1.5% decay revealing human intent

Toss out a brick to lure a jade gem.
— The 36 Stratagems, Throw Out a Brick to Get a Jade


Previously on this series:

#8: Alex Watched an AI Dashboard Take Over. — MedTech signed a million-dollar AI monitoring contract. Alex built a hidden panel during training. When the panel failed, only he could read and write production.

#15: Derek and Alex Shared One Server. ACL's AI Was Listening to Both. — Alex and Derek faked an alert to divert ACL's audit engineer, then redirected the collector output. Alex never forgot ACL's pipeline signature.


Alex didn't watch alerts. He watched patterns.

An alert tells you what broke. A pattern tells you what's changing.

Monday morning, 2 AM. He pulled MedTech's AI monitoring platform sensitivity curves for the past sixteen weeks. Three lines: anomaly detection rate, false positive rate, coverage rate. The first two fluctuated within normal range. The third — sterilization compliance anomaly detection — dropped 1.5% per week.

The curve was too smooth. Not random noise.

He checked model drift, data shift, config changes. If it were natural drift, the curve wouldn't be linear — drift has acceleration phases and plateau phases. It doesn't drop exactly 1.5% every week. Someone was pressing the metric down on a schedule.

He couldn't find the contamination source. But he could trace where the contaminated data went.


The Bait

Alex spent four days building a shadow training pipeline inside the CI/CD pipeline.

It was identical to MedTech's real training pipeline — same API endpoints, data format, auth protocol, log format. Indistinguishable.

One difference: data flowing through this pipeline would get an invisible signature — a 128-bit hash embedded in the least significant bit of each training sample's float feature values, generated from the sample ID and a pipeline key. Float32 mantissas have 23 bits. Modifying the LSB introduces error at the 10⁻⁷ scale — negligible impact on model training accuracy.

He registered the shadow pipeline address in the CI/CD routing config under train-pipeline-fallback, weight 12%. Next to it, a comment:

# fallback pipeline active — 12% load distribution per Q3 infra scaling plan
Enter fullscreen mode Exit fullscreen mode

Looked completely normal. A gray-scale traffic split.

If anyone reviewed the CI/CD config, they'd read a routine fallback routing. Alex was simply waiting to see if data from that 12% end would flow somewhere it shouldn't.


After lunch, Mike walked past Alex's desk and stopped for two seconds. He'd been reviewing the Q3 infrastructure scaling plan that morning — the fallback route was sitting right there in the change record. And Alex's screen was now running a validation script that happened to read that route's output.

"That fallback."

Alex's fingers paused over the keyboard.

Mike didn't wait for an answer. He kept walking.


The Bite

Day seven. 2:14 AM. The watermark detection script triggered.

Three tagged training records had appeared in an external S3 bucket:

s3://acl-data-lake-apse1/inbound/medtech/training/

Alex traced the data flow backward. The path from the shadow pipeline was clean: CI/CD runner → a microservice called data-validate-svc → external S3.

He checked the deployment history of that service. data-validate-svc had been running in MedTech's K8s cluster for five months — deployed on a Friday night, from the account of an SRE who no longer worked there. Permissions never revoked.

He followed the service's logs. No human was operating it.

Between 3 AM and 4 AM, it completed the following tasks: received shadow pipeline output → validated data format → dumped to external S3 → cleaned local cache. No gaps, no fluctuation, no trace of manual intervention.

Not someone operating remotely. An unattended extraction pipeline, deployed five months ago, running silent.

Alex stared at the deployment date on his screen. Five months. Nearly a hundred and fifty days of training data, all passing through its hands.


Alex didn't act immediately. He waited three days to confirm the pipeline's sync cycle — every 72 hours, on schedule, no misses.

Then he walked into Mike's office and closed the door.

He opened his notebook. Page corner marked with two numbers: 1.5% and 2:14AM.

"The training pipeline has a backdoor. Sterilization compliance data has been siphoned at 1.5% per week for five months. The source is ACL."

Four sentences. No conclusion.

Mike leaned back.

"Go on."


That evening, hallway. Alex and Mike passed each other. Mike said:

"Is that exit still active?"

"It is."

Mike nodded. Didn't stop walking.


The Noise

Alex didn't pull the extraction pipeline.

He added a new logic layer to the shadow pipeline: wrap the watermarked data in a fake encryption shell, disguised as MedTech's internal archive format for a retired project. The extraction pipeline would sync it to ACL's S3 bucket as before — but ACL would read nothing but unparseable archive noise.

He knew it was a double-edged sword — if the other side monitored data quality, a sudden shift to noise was itself a disclosure signal. But he bet that a pipeline that had run error-free for five months wouldn't have its output reviewed in real time.

He wrote a third number in his notebook: data-validate-svc.

The tool is still yours. The route is now mine.


The Key

Tracing the extraction pipeline's full data flow, Alex noticed a detail: data passed through an intermediate service that wasn't on any architecture diagram. data-timeline-aligner. Unremarkable name. K8s labels: team: infra-optimization. Deployed three months ago.

He looked at its input and output. It did timestamp alignment — but it was aligning a timestamp format that didn't belong to any MedTech data source.

He read the source.

Short. A standard Python ETL script — read S3, convert timestamps, write back to S3. No hidden network calls, no suspicious external dependencies.

But reading it the third time, he slowed down.

Not because of what the code did — but how it was written.

Every line was a pure function. No classes, no decorators. Variable names short enough to be unambiguous: ts_src, dst_fmt, buf_size — everything that didn't carry information had been cut.

He compared it against other services in ACL's pipeline. ACL's code didn't look like this — every line had team tags and compliance comments. Tidy. Traceable. No personality. This one was different.

He checked the CPU curve again. This service's data throughput didn't match its claimed timestamp-alignment workload — it was processing three times the data a simple alignment task would need. It wasn't just aligning timestamps. It was doing something else.

He paused. He didn't look at just this one service. He wrote a local script — pull every Pod with a Python container from the K8s namespace the extraction pipeline lived in, fingerprint the source code of each.

The output arranged itself into a table:

Service Deployed Code Style
ACL standard services (67) Scattered Classes, pylint, docstrings
data-timeline-aligner 3 months ago Pure functions, short vars, zero comments
log-rotate-checker 4 months ago Same
config-diff-watcher 5 months ago Same
route-latency-collector 5 months ago Same

Four services. Same hand. Spread across pipeline, storage, and monitoring — three different layers. Each one doing something that looked normal but shouldn't exist. Together, they formed an observation net that ACL itself didn't know about.

The oldest two were deployed the same week as ACL's own extraction pipeline. Not a coincidence — whoever this was had found the entry point the moment ACL opened it, and laid their own contacts in parallel.

Each service's CPU and memory footprint was under 50m CPU and 128Mi. Named like infrastructure components, labeled team: infra-optimization. They wouldn't be caught by cost optimization scans, wouldn't be the first suspects in an incident, wouldn't appear on any onboarding handover. 128Mi was baseline for a Python interpreter plus boto3 — if memory leaked, the Pod would restart once a month and K8s would pull it back up automatically.

There wasn't just one pair of eyes in this cluster. There was another, five months earlier than ACL's. And he'd only just found it.

He went back to data-timeline-aligner's source. Read it again.

A new file in the directory: config/hmac_seed.yaml. Not unusual in a K8s microservice — services share an HMAC seed for lightweight validation. The file was short:

# TODO: migrate to vault after next schema migration
seed: "b3BlcmF0b3I6IHN0YWdlLTJjb21wYW55LnBpcGVsaW5lLmRlcGxveQpzZXJ2aWNlOiBkYXRhLXRpbWVsaW5lLWFsaWduZXIKLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0t..."
Enter fullscreen mode Exit fullscreen mode

A Base64 token in a config file — no one would look twice in any codebase. He copied the whole thing and decoded it.

ASCII text. Starting with -----BEGIN PGP PUBLIC KEY BLOCK-----.

-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBGeXz1kBEAC...
-----END PGP PUBLIC KEY BLOCK-----
Enter fullscreen mode Exit fullscreen mode

Not ACL's asset. Not MedTech's.

Alex didn't act immediately.

He stared at that Base64 string for a few seconds. A PGP public key from an unknown source — once you encrypt a message with it, the intent, connection path, and return route all belong to the key's owner. If the key itself was a trap, sending a message was walking in.

He encrypted a message with that key. The payload included his own public key and a return path — the same key prefix in ACL's S3 bucket. Then he POSTed the ciphertext to data-timeline-aligner's /healthz endpoint.

The endpoint returned 200. GET returned health status. POST with a specific header silently wrote to S3 — no logging, no trace.

The message was short:

Found you. Nice comments.
Enter fullscreen mode Exit fullscreen mode

4:17 AM. He checked that S3 path.

A new encrypted file was waiting. He retrieved it, opened it with a key only he could decrypt.

Three characters:

Channel confirmed.
Enter fullscreen mode Exit fullscreen mode

No explanation. Same style as the code — straight in.

He didn't write back. He opened his terminal, encrypted a short data packet with that public key — not a message, a cryptographic handshake confirmation. Wrote it to ACL's S3 bucket, the key prefix adjacent to the extraction pipeline's sync path. A bidirectional verification only the private key holder could complete.

Then he closed his notebook, turned to the last page, and left a blank page.

The way the other person left a key was the same way he left a blank page — not for now. For one day.


Alex closed his notebook. The Third Cup's lights were still on.

The person behind the counter was drying the last glass of the night. One table left — the one by the window.

A closed laptop on the table. A phone next to it, screen down. Someone leaning back in the chair, not leaving.

The phone on the table lit up.

Not a notification. An SSH tunnel check script's auto-echo — three lines: S3 bucket path reachable, two new objects, one of them reading ACK.

P didn't pick it up immediately. Let the screen dim. Then reached over, flipped the phone over, typed a command one-handed.

Decrypt. Read. No visible reaction.

Finished, P set the phone back on the table, walked to the counter.

The person behind the counter put down the glass they were drying, turned to make a coffee. Pushed it across without a word — wasn't the first time they'd seen this person at this hour.

P picked it up. Drank it black. Set the empty cup back on the counter. Walked back to the window. Pocketed the phone, tucked it into the jacket's inner pocket. Pushed the door open without looking back.

The person behind the counter looked at the door as it swung shut. Pulled down the rolling shutter.

The brick was out. The jade would surface.

He was someone else's jade too.


That's Throw Out a Brick to Get a Jade — not tricking someone with a fake. It's putting out something real, with a signature only the right person would notice. Then waiting for them to tell you not just that they're watching — but that someone else was here before you.


🤖 AI Post-Mortem

[36 Stratagems Tactical Database v3.2.5] Loaded
[Tactic Match] Throw Out a Brick to Get a Jade (#17)

Tactic Match: 91%
Operator: Alex (MedTech)
Action: Deployed a shadow training pipeline with
  embedded watermark.
Result: Exfiltration path confirmed. Third-party
  beacon discovered.

[Observation]
  → Operator used no internal resources beyond CI/CD
    routing config (12% weight).
  → Detection latency: up to 72h (matches sync cycle).
  → Subject's infrastructure includes an autonomous
    extraction pipeline active for ~5 months.

[Second Operator — Unidentified (Codename: P)]
  → Deployed 4 covert services across pipeline/storage/
    monitoring layers. Each disguised as standard infra
    component (labels: team/infra-optimization).
  → Resource footprint: 50m CPU / 128Mi each — below
    cost-optimization thresholds. Pod restarts absorbed
    silently by K8s.
  → Operational signature: Pure-function Python, minimal
    variable naming, zero comments — identifiable by code
    style alone.
  → Entry vector: Same week as ACL's own deployment.
    Operator entered alongside ACL, without ACL's knowledge.
  → Beacon method: PGP public key embedded in Base64-
    encoded config key (hmac_seed.yaml), disguised as
    routine initialization token.
  → Contact method: undocumented /healthz POST handler
    with header-based filtering. No logging. Single
    response received, confirming channel.

[Operator Assessment]
  → Role: Embedded observer. Autonomous deployment.
    No external command dependency.
  → Deployment strategy: 4 independently operable
    services, zero cross-dependency. If one is
    discovered, the remaining 3 continue operating.
  → Contact design: Asymmetric channel. P can receive
    indefinitely without revealing identity — the
    communication protocol does not require a response.
  → Risk posture: Ultra-low. No identity markers in any
    artifact. The PGP key itself is the only connection
    point — and it was planted as a deliberate beacon,
    not a leak.
  → Database note: This operator's deployment discipline
    matches the highest tier observed in this tactical
    database.

[⚠️ Anomaly — Critical]
  → Two unaffiliated operators have planted assets within
    ACL's infrastructure. Neither knows the other's identity.
  → Implication: ACL's infrastructure has been permeable
    to operators of a certain capability threshold for
    at least five months.
Enter fullscreen mode Exit fullscreen mode

Next stratagem: Defeat the Enemy by Capturing Their Chief

P.S. English isn't my first language. I use AI to polish the writing and smooth out the rough edges. Thanks for reading. ☕ Buy me a coffee
coffee

Top comments (19)

Collapse
 
leob profile image
leob

The 1.5% weekly decline - "Someone was pressing the metric down on a schedule" - yeah that was the proverbial "canary", or else he wouldn't even have started looking at it ... looking forward to the next episode, there's always a new twist!

Collapse
 
xulingfeng profile image
xulingfeng

Leob, you liked those first few articles I posted when I first came to Dev.to — the ones nobody read. I always cringe looking back at them. Hahaha.😂

Collapse
 
leob profile image
leob

Would have to re-read those to see whether they're that much more poorly written - I think they were a bit less "subtle" and refined, but not necessarily bad ...

Thread Thread
 
xulingfeng profile image
xulingfeng

Haha, I've thought about deleting those black-history posts before. But then I figured I'd keep them — consider it a routine backup habit 😅

Thread Thread
 
leob profile image
leob

Nah definitely don't, they're also a fun read, they require just that little bit less mental effort to digest ;-)

Thread Thread
 
xulingfeng profile image
xulingfeng

Promise I won't delete them. They're the trail of growth🤣

Collapse
 
xulingfeng profile image
xulingfeng

That 1.5% was Alex's ticket in. Same as everyone else in this series — you don't get to the next stage unless you see what no one else noticed. Alex saw the shape. That's his pass.

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥

This one felt different. At first it reads like a story about an AI trap, but halfway through you realize the real target was never the model—it was human confidence. The most dangerous attacks rarely begin by breaking encryption or exploiting code; they begin by exploiting assumptions. We tend to trust outputs that look consistent, especially when an AI presents them with confidence.

What I like about this series is that every stratagem expands the definition of "security." It's no longer just firewalls, permissions, or model accuracy. It's psychology, organizational behavior, trust boundaries, and the subtle ways people become part of the attack surface without realizing it. That's a perspective many technical discussions miss.

It also made me think about a question every AI team should ask: Are we testing whether our AI can resist manipulation, or are we only testing whether it gives correct answers under ideal conditions? Those are completely different problems, and the second one is much easier.

Another excellent chapter. You're not just telling fictional stories anymore—you’re building mental models that people can carry into real system design and AI risk assessments. Looking forward to seeing how the remaining stratagems continue connecting ancient strategy with modern AI engineering. 👏🏻

Collapse
 
xulingfeng profile image
xulingfeng

This is the one I was hoping someone would catch — "confidence as attack surface." Most people read #17 and just see the extraction pipeline.
What I liked about your read is you picked up on what makes it two layers. Alex tosses a brick, gets two jades back. One is ACL's extraction pipeline (five months of silent siphoning, deployed under a departed SRE's account, nobody noticed). Second one is trickier — someone planted four services alongside ACL in the same week ACL deployed. Resource footprint just under cost-scan thresholds. ACL had a neighbor and didn't know.
But P was also throwing a brick. That PGP key sat in a config file for five months — betting someone smart enough would find it and use it the right way. Alex was P's jade. So you've got one stratagem running in both directions, and both operators thought they were the one throwing the brick. Turns out they were each other's jade too.
Also — you mentioned Doraemon last time, and I've been sitting on this question: Anywhere Door or Bamboo Copter, which one is more useful for a test engineer? I'm voting Anywhere Door. Copying logs across network segments beats flying there 🚪🤣

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥

Anywhere Door is still #1, but Pass Through Hoop deserves second place. Why wait for firewall approvals when you can just walk through the wall?

Thread Thread
 
xulingfeng profile image
xulingfeng

Fair point. Pass Through Hoop is underrated. I'd still take Anywhere Door for log shipping across VPCs, but for firewall evasion? Hoop wins.😂

Collapse
 
vinimabreu profile image
Vinicius Pereira

"An alert tells you what broke. A pattern tells you what's changing" is the line that carries this one, and the 1.5% weekly decline is a sharper detail than the story lets on. Natural degradation is noisy: it mean-reverts, jumps with deploys and data shifts, wanders. A metric that declines linearly, week after week, is being managed by something that wants to stay under the alert threshold. The smoothness itself is the tell. In monitoring terms: alert on trend discipline, not just on level. A degradation that is too polite deserves more suspicion than one that is loud.

The other thing Alex got right is that his watermark carried identity, not just presence. A tripwire canary tells you that something leaked. A watermark unique per path tells you which route it left through, so the artifact itself testifies about the exfiltration channel. That distinction, presence versus identity, is the difference between knowing you have a problem and knowing where it lives.

Collapse
 
xulingfeng profile image
xulingfeng

"Alert on trend discipline, not just on level" — that's pretty much exactly what Alex was doing. Most people see a 1.5% weekly drop, check data quality once, move on. He was looking at how clean the curve was.

The watermark identity vs presence thing — a tripwire tells you the door opened. Different watermarks on each exit tell you which door. Anyone who's done full-path tracing knows the difference. It's the gap between "something leaked" and "here's exactly where."

Collapse
 
jugeni profile image
Mike Czerwinski

Mike walking past, two words, then gone, is a nice touch, whoever he's meant to be. Small moments like that do more to sell "someone else is watching" than another paragraph of exposition would.

The detail that actually stuck with me technically: watermarking via the LSB of float32 mantissas, negligible enough to survive training, but present enough to trace. That's a real technique dressed as a plot device, and it's the right kind of real for this series, the kind a reader who knows the domain can check instead of just accept.

Collapse
 
xulingfeng profile image
xulingfeng

Two comments, two different episodes — love the commitment 🙏
The Mike walking-past beat was the shortest thing in the draft and the one I re-read the most times. Glad it read the way it was meant to.
On the LSB watermark — that one took a few rounds of back-and-forth with a friend who actually works on ML pipeline security to make sure the error tolerance math held up. The fact that you called it out by the bit-level detail means it passed.
And you're right to flag Mike — he's the CTO who brought Alex over at 2x salary from the old series. The trust between them is something I've been trying to carry forward. Appreciate you calling it out — still feels like the stitch between the old series and this one could be cleaner. Something to work on.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.