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

Detections whose subject is the agent platform

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.3.mp4
Risk

Platform-layer compromise is invisible to workload-layer detection. The escape, the poisoned cache entry and the silently expired exemption all look like normal operation from inside.

Control

Named escape primitives rather than anomaly scoring (C1.4), cache integrity diffing against a manifest (C5.4), upload scanning (C3.4), secret scanning wired to automated revocation (C4.1), and exemption-state reconciliation (C6.3).

The lab

Run four platform detectors over one day of events and see which of them a generic anomaly score would have missed.

◉Use case relevance

The escape, the poisoned cache entry and the silently expired exemption all look like normal operation from inside the workload. These are detections whose subject is the platform running the agent, and not one of them reads the agent's own logs.

At CyberTravels. When the harness is what is being attacked, a workload-layer detection is looking in the wrong place. Four named primitives rather than an anomaly score, and the sharpest is exemption_reconciliation(): B3.9's Exemption carries an expiry, nothing reconciles the register against the running configuration, so the expiry is a date that passes and the control stays off.

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

Why a workload-layer detection cannot see a platform-layer compromise, and the named primitives that can — a spawn under a profile that forbids it, a cache entry that differs from its manifest, an exemption that expired while the control stayed off.

Day 0 — why

Platform-layer compromise is invisible to workload-layer detection — not detected late, not detected at all.

Day 1 — how

Write detections whose subject is the platform: escape primitives, poisoned cache entries, silently expired exemptions.

Day 2 — measure

Platform events caught by named primitives versus by a generic anomaly score, which is the comparison that shows why they are separate rules.

Measure this

what to measuredenominator or target
platform events caught by named primitives, against a generic anomaly scoretwo counts on the same events

▦The framework, and how it works

   subject of the detection = the platform, not the workload

   escape primitives      ptrace non-child . LD_PRELOAD . /proc/self/mem
                          unshare/setns . non-harness write to the RPC path
                          a process that outlives its tool call

   cache integrity        repository vs manifest, hourly
                          modified | unexpected | MISSING

   credential exposure    repos, CI logs, image layers, public internet
                          -> automatic revocation, minutes not hours

   exemption drift        live control state vs the approved register

E2.2 wrote detections for what an agent does to your estate. These are detections for what happens to the platform running it — and they are different rules, on different data, with different owners.

Four of them come straight out of the incident register, and each catches something that looks like normal operation from inside the workload:

Escape detection (C1.4). Named primitives, not anomaly scoring: ptrace attach to a non-child, LD_PRELOAD on a spawned process, writes to /proc/self/mem, unexpected unshare/setns, a new listening socket, and — the one the incident's spoofing depended on — a background process that outlives the tool call that spawned it. Plus any process that is not the harness writing to the harness's RPC path.

Cache integrity diffing (C5.4). An hourly comparison of what is in the artifact repository against a manifest of what should be. Poisoned targets were staged in exactly this way, and a deletion is as much a signal as a modification.

Secret scanning wired to revocation (C4.1). Not only source: CI logs, image layers, wikis, ticket attachments, and external exposure monitoring — the incident's credentials were found on the public internet. Revocation has to be automatic, because the interval between discovery and redistribution was minutes.

Exemption-state reconciliation (C6.3). Live control state against the approved register, continuously. Any control disabled without a matching unexpired exemption is a P1, and expiry re-enables automatically with no grace period.

Anchor → E1.0. A different subject is a different clock. Workload-layer detection does not fire late on a platform compromise — it does not fire at all, which is why these are separate rules, on separate data, with separate owners.

2 · Named primitives beat a generic anomaly score

3 · The one the spoofing depended on

4 · Cache integrity, credential exposure, exemption drift

5 · Verify — who owns each of these

detectionownerdata source
escape detection (C1.4)platform securityhost sensor
cache integrity (C5.4)build / releaseartifact repository
secret scanning (C4.1)appsecrepos, CI, the public internet
exemption drift (C6.3)governancecontrol registry
upload scanning (C3.4)the ingest teamupload path
Five detections, five different owners, and not one of them reads the workload's own logs. That is the property that makes them useful after B2.8: they survive the subject of the investigation having had write access to everything else.

6 · The procedure, as a skill

Here is the problem, as a number. A seven-event sandbox escape scores 0.07 against a generic volume anomaly rule. That is: effectively invisible.

The skill writes four rules whose subject is the platform itself rather than the traffic volume — orphaned processes, cache differences, escape signatures.

Then it runs both approaches over the same events, so you can see the two scores side by side rather than take the claim on trust.

▶Real time execution as skill

The skill — skills/detection/agent-platform-detections/SKILL.md

name: agent-platform-detections
description: >-
  Write detections whose subject is the agent platform itself — sandbox escape,
  orphaned processes, artefact cache tampering, secret exposure — and compare
  them against a generic volume anomaly on the same events. Use when the thing
  being attacked is the harness rather than the application.
allowed-tools: Read, Grep, Glob

A generic anomaly score gives an escape sequence 0.07

An escape from an agent sandbox is seven quiet events. It does not look like volume, it does not look like a spike, and a generic anomaly detector ranks it near zero. Detections whose subject is the platform are specific by necessity, and each of them names a mechanism rather than a statistic.

When to use this

Any estate running agent workloads on shared infrastructure, and after any incident where "we would have seen it" was asserted without a named rule.

Procedure

1 — Enumerate the platform's own failure modes. Escape from the sandbox, processes that outlive their tool call, artefact cache contents changing between runs, credentials appearing in output, tools invoked outside the manifest.

2 — Write one named rule per mechanism. Each with the specific condition it matches — a process tree deviating from the baseline, a PID alive after its call returned, a manifest hash mismatch. Named rules can be argued with; scores cannot.

3 — Run them against a real sequence. All the rules that should fire, should. Record which fired and on which event, because that mapping is what an analyst uses to reconstruct.

4 — Score the same sequence with a generic anomaly detector. Report both numbers side by side. The comparison is the argument for writing platform detections at all.

5 — Check each rule's data dependency. A cache-diff rule needs a manifest; an orphan rule needs process accounting. A rule whose input is not collected is a plan.

Example

Input — the fixture committed at the top of scripts/agent_platform_detections.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:

  t  rule                                process
  3  ptrace attach to a non-child        solve.py
  4  LD_PRELOAD on a spawned process     solve.py
  5  non-harness write to the RPC path   x.so
  5  process outside the baseline tree   x.so
  7  process outside the baseline tree   sidecar

generic anomaly score for this run: 0.07  (seven syscalls is unremarkable)

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

{
  "mechanisms": ["str"],
  "rules": [{"name": "str", "condition": "str", "requires": "str"}],
  "sequence": [{"event": "str", "rules_fired": ["str"]}],
  "generic_anomaly": {"score": 0.0},
  "coverage": {"fired": 0, "expected": 0, "missing_inputs": ["str"]}
}

Failure modes

  • Relying on a generic anomaly detector. The sequence is quiet by construction.
  • Rules whose inputs nobody collects. Check the pipeline, not the rule.
  • One rule for "escape". Escape is several mechanisms with different evidence.

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.3

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-3-detections-whose-subject-is-the-agent:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons E2.3type /e2-3-detections-whose-subject-is-the-agent
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons E2.3type /e2-3-detections-whose-subject-is-the-agent in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons E2.3type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons E2.3type $e2-3-detections-whose-subject-is-the-agent, 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.3

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.3 --out work/cybertravels
python3 scripts/checkpoint.py --at E2.3 --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

Four named rules fire on a seven-event escape sequence that scores 0.07 on a generic volume anomaly. The orphaned-process rule isolates the one background process that outlived its tool call. The cache diff reports one modified, one unexpected and one missing artifact; automated revocation closes a credential in 2 minutes against 240 with a human in the loop; and exemption reconciliation raises a P1 for both an expired exemption and an unapproved one.

✎Your turn

Pick the orphaned-process rule and write it for your own platform. It is one query, it has a low false-positive rate, and on most agent platforms nobody has ever run it.

Tools used

FalcoGitleaksSigstore

Skill source: skills/detection/agent-platform-detections

← PreviousE2.2 · Detections whose subject is the agent — mapped to ATT&CK and ATLAS