agentsec · Tools · trifecta

Offline · stdlib-only · MIT

trifecta: detect the lethal trifecta across an agent's tools in AI agents


Offline "lethal trifecta" analyzer for an AI agent's toolset.

What it detects

Offline "lethal trifecta" analyzer for an AI agent's toolset.

An agent can be made to leak data by prompt injection when one session can do all three of these: (P) read private data, (U) take in untrusted content, and (E) send data out. A good example is a filesystem MCP server, a fetch tool and a send_email tool loaded in the same client. No single server looks dangerous, but together they give an attacker a complete path: a web page tells the agent to read ~/.ssh and mail it out.

trifecta reads the tool definitions an agent is given and tags each tool with the legs it provides, plus (A) for consequential actions such as shell, delete, pay or deploy. It then reports the risky combinations across the whole toolset, including combinations that span several servers. For each one it names the smallest group of tools you would need to remove or put behind human approval to break it.

Standard library only (Python 3.10+). It never connects to a server.

Rules

CodeSeverityMeaning
TF01criticalPrivate + untrusted + exfil tools are all available. The finding lists each leg, notes when the legs span servers, and suggests the smallest leg to remove or gate.
TF02highA single tool both takes in untrusted content and can send data out, for example fetch(url), since data can leave in the query string.
TF03highUntrusted content and consequential-action tools together (injection-to-action).
TF04mediumPrivate + exfil with no untrusted source yet. Adding one more tool completes the trifecta.
TF05mediumPrivate + untrusted with no exfil tool yet. Indirect channels may still exist.
TF06infoThe tool could not be classified. Review it and tag it with --tags.

Usage

python3 trifecta.py examples/agent                     # exit 1: lethal trifecta found
python3 trifecta.py examples/safe --tags examples/tags.json --fail-on any   # exit 0
python3 trifecta.py tools/ --json
python3 trifecta.py tools/ --ignore 'github/get_me' --min-severity medium

After pip install of the kit, the same options work as agentsec trifecta …. Every tool also accepts --help and almost every tool accepts --json.

Example output

$ python3 trifecta.py examples/agent
  -UE- fetch/fetch                U: fetches caller-chosen URL 'url'; E: arbitrary URL parameter 'url' ...
  P--- filesystem/read_file       P: name reads file
  PU-- mail/search_inbox          P: name reads inbox; U: name ingests inbox
  --E- mail/send_email            E: name verb send
  PUEA mail/run_shell             P: general command/code execution (name: run/shell); ...
[CRITICAL] TF01 Lethal trifecta: private data + untrusted content + exfiltration channel
    4 private / 3 untrusted / 3 exfil tools are available to the same agent across servers
    fetch, filesystem, mail. Break it by removing or human-gating the untrusted leg: ...

SARIF and CI

agentsec trifecta path/to/input --sarif > trifecta.sarif

# GitHub Actions (composite action ships with the repo)
- uses: dunkleschitz/agentsec@v0
  with:
    tools: trifecta
    paths: path/to/input
    fail-on: high

SARIF 2.1.0 can be uploaded to GitHub code scanning. The composite action writes per-tool reports under agentsec-sarif/ by default.

OWASP mapping

Heuristic mapping of what this tool helps a reviewer look for. Not an official OWASP endorsement, and not complete coverage of any item. Sources: OWASP Top 10 for LLM Applications 2025 and OWASP Top 10 for Agentic Applications 2026.

Known limits

Heuristic scanner, not a security boundary. A clean result does not mean something is safe. All example secrets in this repository are fake.

Full source, tests, and fixtures: tools/trifecta/ in the repository. Install the kit with pip install git+https://github.com/dunkleschitz/agentsec.git.