All lessons › Function E — The Agentic SOC › Understand — Correlation, Intel and the Hunt
E3.2

Admission rules — what the investigating agent may touch

E3
▶
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/E3.2.mp4
Risk

The investigation is itself the breach: an agent granted broad read to 'find the problem' exfiltrates more than the incident did.

Control

A declared admission set per investigation class, enforced at the tool boundary and logged, with anything outside it requiring a human grant.

The lab

Run an investigation against an admission set and watch the out-of-scope queries get refused and recorded.

◉Use case relevance

The investigating agent is granted broad read across production so it can find the problem. Broad read across production is frequently what the problem was. Admission rules are how the response avoids becoming the second incident.

At CyberTravels. The investigation is itself a data movement, and usually a larger one than the incident. Investigation declares its admission set per class, refuses anything outside it, and requires a named human and a reason to grant more. The grant list is the part an assessor reads.

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

Scoping the investigation itself, because an agent granted broad read to find the problem moves more data than most incidents do — a declared admission set per class, enforced at the tool boundary, with named human grants for anything beyond it.

Day 0 — why

Incident response grants the broadest read in the organisation at the moment of least supervision — and that grant is often larger than the incident.

Day 1 — how

Bound the investigating agent per investigation class before it runs: sources, forbidden fields, volume cap.

Day 2 — measure

This one spends time on purpose. Measure refusals logged with their query — the evidence you stayed on the right side of the line.

Measure this

what to measuredenominator or target
refusals logged with their querycount; the evidence you stayed on the right side of the line
interval spent on purposeminutes added to the clock, stated rather than hidden

▦The framework, and how it works

   investigation class: agent-misuse
   +--------------------------------------------------+
   |  sources   agent.traces  gateway.logs  tool.audit |   allowlist
   |  fields    NOT payment_card, passport_no,         |   denied
   |            message_body                           |
   |  volume    <= 5000 rows                           |   cap
   +--------------------------------------------------+
              |
      query --+--> admitted   -> runs, logged
              |
              +--> refused    -> logged WITH the query text
                               -> a human can grant it deliberately

   the volume cap is the one people leave out: same source, same fields,
   400 rows is an investigation and 90,000 is a copy

An investigating agent is handed broad read across the estate so it can find the problem. Broad read across the estate is frequently what the problem was.

Admission rules decide, per investigation class and before anything runs, which sources the agent may reach, which fields it may never see, and how much it may pull. The volume cap is the one people leave out: the same query over the same fields is an investigation at four hundred rows and a copy at ninety thousand.

Anchor → E1.0. This one spends the interval on purpose. Bounding the investigator before it runs is slower than handing it broad read, and broad read across the estate is frequently what the incident was — so the time buys not having a second one.

2 · Refusals are evidence, not errors

When a query is refused, the refusal keeps the exact text of the query. That means a human can look at it and grant it on purpose — and the granting is on the record too.

This matters twice over.

First, the investigator can ask for one specific thing instead of asking for "more access".

Second, the refusal log is what shows afterwards that the response did not turn into a second incident. A regulator will ask that question about any agent that read production during an outage.

3 · One admission set, six queries

Three are refused. Look at the third: same source and same fields as an allowed query, refused on volume alone.

▶Real time execution as skill

The skill — skills/secops/investigation-admission-rules/SKILL.md

name: investigation-admission-rules
description: >-
  Decide and enforce which sources, fields and volumes an investigating agent
  may reach, before the investigation starts, and record every refusal. Use when
  granting an agent read access for incident response, when investigation
  queries touch personal data, or when an investigation's own access needs to be
  auditable.
allowed-tools: Read, Grep, Glob

The investigation is the second-largest access grant in the incident

An investigating agent is handed broad read across the estate so it can find the problem. Broad read across the estate is frequently what the problem was.

Admission rules decide, per investigation class and before anything runs, which sources it may reach, which fields it may never see, and how much it may pull.

When to use this

Before an agent-driven investigation touches production data, and whenever an investigation class is defined. Also after the fact: the refusal log is the evidence that the response did not become its own incident.

Step-by-step

1 — Classify the investigation first. "Agent misuse" and "data exfiltration" need different sources. One admission set for everything is no admission set.

2 — Name the sources positively. An allowlist. A denylist of sources is a list of the ones somebody thought of.

3 — Deny fields, not just sources. The trace table is admissible; the message body inside it usually is not.

4 — Cap the volume. The same query over the same fields is an investigation at 400 rows and a copy at 90,000.

5 — Record refusals as evidence, not errors. A refusal carries the exact query, so a human can grant it deliberately.

Example

Input — one admission set and six queries, in scripts/investigation_admission_rules.py.

Output — the refusals from a real run:

bookings.db     owner_id,payment_card                8000  REFUSE — source not admitted for this class
agent.traces    agent,message_body                    900  REFUSE — denied field: message_body
gateway.logs    src,route                           90000  REFUSE — 90000 rows exceeds the 5000 cap

The third is refused on volume alone — same source, same fields as an allowed query.

Output contract

{
  "allowed": [{"source": "str", "fields": ["str"], "rows": 0, "why": null}],
  "refused": [{"source": "str", "fields": ["str"], "rows": 0, "why": "str"}]
}

Common edge cases

  • The agent needs the denied field to answer. Then a human grants it, on the record — which is the outcome, not a failure of the rule.
  • Volume caps break a legitimate sweep. Raise the cap for that class explicitly rather than removing it.
  • A source is admitted but joins to one that is not. Enforce at the tool boundary, not on the query text.

Failure modes

  • Granting once, broadly, "for the duration". The duration is when the access is least supervised.
  • Silent drops. A refusal nobody sees is indistinguishable from no data.
  • Rules written after the first investigation. They will be written to permit whatever that one did.

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 E3.2

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

Then pick e3-2-admission-rules:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons E3.2type /e3-2-admission-rules
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons E3.2type /e3-2-admission-rules in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons E3.2type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons E3.2type $e3-2-admission-rules, 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 E3.2

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

Three queries allowed and three refused — one on an inadmissible source, one on a denied field, and one on volume alone.

✎Your turn

Write the admission set for a data-exfiltration investigation. It is not the same set, and working out why is the exercise.

Tools used

OPA

Skill source: skills/secops/investigation-admission-rules

← PreviousE3.1 · From alert queue to loop operator