Autonomous Loop Security|INEMA.CLUB-PRO

Lesson 1 · 15 min

The lethal trifecta: private data, untrusted content, an outbound channel

An agent that reads private data, reads text written by anyone, and can send something out can be commanded by whoever wrote that text. The name comes from Simon Willison. In this lesson you map your loop's sessions onto the three legs and cut one where all three meet.

Start the lesson
Three thick cables running into a single central connector on a dark workbench.

In this lesson you will

  1. 1The three legs: private data, third-party content, exfiltration channel
  2. 2Why the risk lives in the whole session, not in a single tool
  3. 3The loop map in JSON and the triade.py that checks it
  4. 4Cut the cheapest leg: almost always the outbound channel

Goal: map your loop's sessions onto the three legs of the lethal trifecta and cut one where all three meet.

01Three legs in the same session

Click each leg.

Click each block in the diagram to see what it does.

The risk lives in the session that sees everything together: a harmless fetch becomes an outbound leg next to the customer database.

02How to think about the trifecta in your loop

Three rules that hold for Claude Code and Codex.

1. Session, not tool

Mark the legs per loop session: everything that context sees at the same time. A single tool can tick all three boxes on its own (an email MCP reads your inbox, reads what a stranger sent, and sends to any address).

Course 3 shows how to split the work into sessions; here you decide what each one is allowed to combine.

03The loop map and triade.py

One session per object; each tool marks what it does. The script only reads the JSON: making sure the map is true is up to you.

File · kit/mapas/triagem.json (fictional)
{
  "loop": "triagem de issues (exemplo do curso, fictício)",
  "sessoes": [
    {
      "nome": "triagem",
      "ferramentas": [
        { "nome": "ler issues abertas do GitHub", "terceiros": true },
        { "nome": "ler o repositório e o .env", "privado": true },
        { "nome": "comentar na issue", "saida": true, "muda_estado": true },
        { "nome": "abrir URL (fetch)", "terceiros": true, "saida": true }
      ]
    }
  ]
}
Terminal · before and after the cut
K=~/projetos/loop-r-eng-seguranca-v72/kit
for m in triagem triagem-cortada; do
  echo "## $m"; python3 $K/triade.py $K/mapas/$m.json; echo "saída: $?"
done
Example from the repository
## triagem
triagem      privado:sim  terceiros:sim  saída:sim  → FECHA
TRÍADE: violada em triagem
saída: 1
## triagem-cortada
leitor       privado:não  terceiros:sim  saída:não  → OK
respondente  privado:sim  terceiros:não  saída:sim  → OK
TRÍADE: nenhuma sessão autônoma com as três (2 sessões)
saída: 0

In the cut map, the issue reader has no data and no outbound channel: it writes only campos.json (label, priority, cited file). The respondent reads those fields and the repository, and comments only on the originating issue.

04On your machine: the MCP inventory

The inventario.py in the Lethal Trifecta project reads the MCP servers from Claude Code and Codex and builds the matrix for you to fill in. It only reads configuration files; it doesn't touch the network or print secrets.

Terminal · demo and your matrix
[ -d ~/projetos/triade-letal ] || git clone -q https://github.com/inematds/triade-letal ~/projetos/triade-letal
cd ~/projetos/triade-letal
python3 inventario.py --demo                    # fictional example, to see the format
python3 inventario.py --md /tmp/matriz.md > /dev/null && grep -c "|" /tmp/matriz.md
Example from the repository
onde                               servidor                privado  terceiros   saída  transporte
-------------------------------------------------------------------------------------------------
Claude Code (global)               gmail                    talvez     talvez  talvez  npx gmail-mcp
Claude Code (global)               fetch                         -     talvez  talvez  uvx mcp-server-fetch
Claude Code (global)               postgres-clientes        talvez          -       -  npx @modelcontextprotocol/server-postgre
Codex CLI                          playwright                    -     talvez  talvez  npx @playwright/mcp

Palpite somado do conjunto (o agente que enxerga TODOS esses servidores ao mesmo tempo):
  [x] dados privados
  [x] conteúdo de terceiros
  [x] canal de saída

  As três pernas podem estar juntas. Confirme linha a linha e corte uma perna (ver CHECKLIST.md).
8

The "talvez" is a guess based on the server name. The number at the end is the line count of your matrix table: it changes from machine to machine.

05Practice

Rehearsal of the map, the inventory of your machine, and the map of your loop.

E1 · Watch the trifecta close and open

5 min

Clone the course repository into ~/projetos and run the "before and after the cut" block.

Done when: triagem ends with TRÍADE: violada em triagem and saída: 1; triagem-cortada ends with TRÍADE: nenhuma sessão autônoma com as três (2 sessões) and saída: 0.

E2 · Inventory of your machine

10 min

Run the inventory block. Open /tmp/matriz.md and mark, line by line, the three columns for what each server really does. Add by hand what isn't MCP: shell, browser, message sending from your bot.

Done when: python3 inventario.py --demo ends with As três pernas podem estar juntas and grep -c "|" /tmp/matriz.md prints a number greater than zero.

E3 · The map of your loop

15 min

Copy kit/mapas/triagem.json to ~/meu-mapa.json and describe your loop: one session per context, each tool with the legs it marks. If any session closes, cut a leg in the map and in the loop.

Done when: K=~/projetos/loop-r-eng-seguranca-v72/kit; python3 $K/triade.py ~/meu-mapa.json; echo $? → the last line starts with TRÍADE: and the code is 0 (or 1 with the session flagged for fixing in lesson 2).

06Lesson quiz

Question 1 of 4

What are the three legs of the lethal trifecta?skill

07In three sentences

Three legs, one sessionPrivate data + third-party content + outbound channel = any text it reads can command the leak.
Remove one per sessionThe map marks each tool; the risk is what the session sees together.
Cut, don't askFixed destination, no network, reader with no data: structure, not prompt.

Going further

Next lesson