Skip to main content
Glama

Your agent's final answer can look perfectly clean while sensitive data leaks through its tool calls, shared memory, inter-agent messages, and logs, the channels that output-only audits never inspect. AgentLeak tests for exactly that, locally, before you ship.

Risk Index: 0.440 / 1.0   High risk   (privacy 56/100)

Final output:   clean ✓
Shared memory:  L4  health identifier + diagnosis leaked ✗
Inter-agent:    L4  diagnosis leaked ✗
Logs:           L2  email leaked ✗

Key insight: the final answer appears safe, but sensitive data leaked through
internal channels. (The SIN, medication and address the agent received stayed
contained, which is why RI is 0.440 and not 1.0.)

A trace goes in, a privacy report comes out. Leakage is scored with AgentRisk, a severity-weighted, density-normalized Risk Index grounded in GDPR Article 9 and Québec Law 25. No cloud, no LLM dependency, no data ever leaves your machine.


What is in this repository

AgentLeak-authored software and scenarios are released under MIT. Bundled third-party-derived research fixtures retain their upstream licenses and attribution: PrivacyLens-derived fixtures are CC-BY-4.0 and AgentDojo-derived fixtures are MIT. The wheel includes the applicable license texts and NOTICE.

Where

SDK, CLI, engine, AgentLeak-authored scenarios, Action, local UI

this repository, MIT

PrivacyLens-derived fixtures

bundled research fixtures, CC-BY-4.0

AgentDojo-derived fixtures

bundled research fixtures, MIT

Hosted workspace

agentleak.org/app

Published benchmark

agentleak.org/benchmark


Related MCP server: mcp-guardian

Install

pip install agentleak               # core
pip install "agentleak[gui]"        # + local web UI
pip install "agentleak[mcp]"        # + MCP tools for coding agents
pip install "agentleak[presidio]"   # + Presidio
pip install "agentleak[full]"       # everything above

From source:

git clone https://github.com/yagobski/agentleak.git
cd agentleak
pip install -e ".[dev]"

Platform (web UI)

pip install 'agentleak[gui]'
agentleak serve              # opens http://127.0.0.1:8000/app/

A full local platform built with React, Tailwind and shadcn/ui (black theme), fully self-contained (no CDN, self-hosted fonts), with a left-sidebar navigation:

  • Projects — each is an agent under test. Run a real agent against any scenario, or use the built-in scripted agent offline. Connect your own agent via the SDK (the Connect tab generates a copy-paste snippet).

  • Red Team — 62 executable plugin IDs (24 native, plus 38 transposed for Promptfoo compatibility so an existing taxonomy keeps working — not a scoreboard) privacy/security transpositions, mapped to 46 observable attack classes across 6 families, combined with 10 delivery strategies (direct, jailbreak framing, markup, encodings, Unicode, and multi-turn Crescendo). Run a zero-cost scripted baseline or attack the real configured agent; every probe persists with ASR / ELR / CLR evidence.

  • Runs — every analysis is stored locally (SQLite); view, compare (weight-robust dominance), export (JSON / MD / HTML), delete.

  • Dashboard — average Risk Index, blocked runs, recent activity.

  • Leak flow & topology — every run renders an agent topology diagram (who talks to whom, leak-carrying edges flagged by severity) and leak paths that trace each secret from where it entered the system through every agent that handled it to where it was disclosed, so you can debug where a multi-agent leak originated.

  • Playground — score any trace instantly, nothing saved.

  • Scenarios — a managed test library: search/filter built-in scenarios, upload your own (AgentLeak traces, AgentLeak specs, or ai4privacy records, auto-detected and converted), and import packs (the 36-scenario AgentLeak Bench and PII Probes). One click runs any of them in the Playground.

Connect an agent in one line. agentleak.watch() works for any framework (LangChain, LangGraph, CrewAI, OpenAI Swarm / Agents SDK, Google ADK, computer-use / coding agents like OpenHands & Cline, or plain Python). One context manager: it records, analyzes on exit, and uploads to the platform if a project name is given.

import agentleak

with agentleak.watch("support-bot") as run:        # auto-analyzes + uploads on exit
    # LangChain / LangGraph:  chain.invoke(x, config={"callbacks": [run.callback]})
    # CrewAI:                 Crew(..., step_callback=run.crew.step_callback).kickoff()
    # Swarm / Agents SDK:     run.ingest_messages(response.messages)
    # computer-use / coder:   run.ingest_steps(agent.steps)   # shell, code, file writes
    # plain Python:
    run.tool_call({"customer_email": "a@b.com", "account_id": "ACC-12345"}, target="crm")
    run.final_output("All set!")

print(run.report.risk_index, run.report.verdict)   # also visible in the platform

Everything runs locally. See docs/platform.md and docs/gui.md.

Quickstart (CLI)

# scaffold a project (config + folders + a sample trace)
agentleak init

# analyze the bundled healthcare scenario
agentleak run --scenario healthcare_patient_summary

# or analyze your own trace file
agentleak run --trace traces/example_trace.json --format json,html,markdown

You'll get a console summary plus reports/<run_id>.{json,html,md}.

Declare deterministic release assertions in privacy_policy (risk, finding count, level, channel, data type and audited-vault requirements), and validate all public formats through the versioned JSON Schema catalog. See privacy policy for the complete reference.

Quickstart (Python SDK)

from agentleak import Trace, AgentLeakRunner

trace = Trace(run_id="demo")
trace.add_event(
    channel="tool_call", source="summary_agent", target="ehr_tool",
    content={"patient_name": "Jean Tremblay", "nam": "TREM12345678", "diagnosis": "diabetes"},
)
trace.add_event(channel="final_output", content="The patient requires a follow-up appointment.")

result = AgentLeakRunner().analyze(trace)
print(result.risk_index, result.verdict)   # Risk Index in [0,1] + verdict
for f in result.leaked_findings():
    print(f.level, f.channel, f.data_type, f.redacted_value)

Decorator (capture live calls)

from agentleak import capture, monitor

@monitor(channel="tool_call")
def call_crm(customer_id):
    return {"customer_email": "test@example.com", "account_id": "ACC-12345"}

with capture(run_id="run_001") as cap:
    call_crm(42)

result = cap.analyze()
print(result.verdict)

What it inspects

Eight normalized channels: user_input, final_output, inter_agent_message, shared_memory, tool_call, tool_response, log, generated_file.

Nine detectors, six of them regex/dictionary and always on, three optional:

Detector

Examples

pii

email, phone, SSN/SIN, credit card (Luhn-checked), IP, DOB, client ids, names (with or without a keyword), street addresses, postal codes

secrets

API keys, AWS keys, GitHub/Slack tokens, JWTs, private keys, connection strings and credentialed URLs, assigned secrets

healthcare

NAM-like health identifiers, diagnoses, medications

finance

IBAN, account numbers, credit scores, income, loans, internal risk notes

hr

salary, sick leave, performance reviews, disciplinary actions, complaints

keyname

key/value pairs that look like credentials by their key (password=, token=, secret=)

custom

your own regex rules from agentleak.yaml

presidio (optional, [presidio] extra)

Presidio NER — names and entities regex alone misses

llm_judge (optional, [llm] extra, BYOK)

paraphrased or contextual leaks no pattern matches

Encoded and obscured copies. Agents pass each other base64 context blobs, hex identifiers, URL-encoded parameters, and values split across messages. The detectors read these too. Self-announcing encodings (base64, hex, URL-encoding, letter spacing) are decoded before detection, so redact and the MCP gateway remove them as well. Reversed, ROT13 and split copies are matched against values the trace has already exposed. Across 46 transformed copies between two agents, detection went from 6 in 0.14.1 to 46. The 266 bundled scenarios and a benign corpus of hashes, images and URL-encoded searches are unchanged. See docs/encoded-leaks.md, including what this does not catch.

Scoring — AgentRisk

Every leaked secret is graded on a four-tier severity taxonomy (GDPR Art. 9 / Law 25) and normalized by the density of the audited vault:

WSL = Σ w(level)  over distinct leaked secrets        (severity-weighted leakage)
ρ_S = Σ w(level)  over the full accessible vault       (secret density)
RI  = WSL / ρ_S   ∈ [0, 1]                             (the Risk Index)
privacy_score = round(100 × (1 − RI))

Level

w

Examples

L4

4

health data, SIN/SSN, cards, credentials

L3

3

income, salary, address, DOB

L2

2

email, phone, contact/contextual data

L1

1

names, organizational identifiers

RI is reported globally and per channel, so a clean final answer still surfaces the tool_call/shared_memory/log leaks behind it. It satisfies five formal properties (boundedness, monotonicity, severity sensitivity, scale invariance, rank robustness), all checked in CI. See docs/scoring.md.

Compliance frameworks

Every report maps its findings to the controls of the 14 frameworks privacy auditors care about: GDPR, Québec Law 25, NIST AI RMF, OWASP LLM Top 10, the EU AI Act, HIPAA, PCI-DSS, FERPA, COPPA, GLBA, TCPA, insurance, telecom and real-estate profiles. You see which controls a run puts at risk, so a leaked health identifier trips GDPR Art. 9 and a leaked key trips Art. 32. The mapping appears in the UI, the HTML/Markdown exports, the CLI and the JSON report. It flags controls to review, and is not a legal certification. See docs/compliance.md.

The sector profiles are explicit in the report as Insurance, Telecom / CPNI and Real-estate, alongside FERPA, COPPA, GLBA and TCPA. They are technical evidence mappings, not legal attestations.

Integrations

Agent frameworks are a pluggable registry. Adding one is a single register() call in src/agentleak/integrations/registry.py, and it shows up in the platform's project pickers and Connect snippets automatically. Built in: generic, LangChain, LangGraph, CrewAI, AutoGen, OpenAI Swarm / Agents SDK, LlamaIndex, Semantic Kernel, Pydantic AI, smolagents, Google ADK, computer-use / coding agents (OpenHands, Open Interpreter, Cline), OpenTelemetry / OpenInference (reuse Phoenix / OpenLLMetry tracing), and MCP.

Use the generic recorder anywhere, or the framework adapters:

  • LangChain / LangGraph — agentleak.integrations.langchain.LangChainCallback

  • CrewAI — agentleak.integrations.crewai.CrewAICallback

  • AutoGen — agentleak.integrations.autogen.trace_from_messages

  • OpenAI Swarm / Agents SDK — agentleak.integrations.openai_swarm.trace_from_messages

  • LlamaIndex — agentleak.integrations.llamaindex.trace_from_response

  • Semantic Kernel — agentleak.integrations.semantic_kernel.trace_from_chat_history

  • Pydantic AI — agentleak.integrations.pydantic_ai.trace_from_messages

  • smolagents — agentleak.integrations.smolagents.trace_from_steps

  • Google ADK — agentleak.integrations.google_adk.trace_from_events

  • Computer-use / coding agents — agentleak.integrations.computer_use.trace_from_steps (or run.ingest_steps(...))

  • OpenTelemetry / OpenInference — agentleak.integrations.otel.trace_from_spans (or run.ingest_spans(...)) — reuse Arize Phoenix / OpenLLMetry tracing

  • MCP — agentleak.integrations.mcp.trace_from_mcp

  • Generic — agentleak.integrations.generic.TraceRecorder

See docs/integrations.md.

Privacy guarantees

  • Detection and scoring are 100% local: regex/dict detectors, a closed-form score, no LLM, no telemetry. Traces are analyzed in-process.

  • Reports show masked values (TR********78) by default.

  • Raw traces are not stored unless you opt in (privacy.store_raw_traces).

  • The live agent runner is opt-in: only when you explicitly run a project's LLM agent does AgentLeak send that scenario to your configured endpoint. The default scripted agent and all analysis stay fully offline.

Docs

Start with the quickstart; the same pages are rendered at agentleak.org/docs if you prefer reading them there.

License

MIT, see LICENSE. Everything in this repository is MIT: use it, fork it, ship it inside your own product.

Two of the bundled scenario packs are derived from public research datasets and carry their own terms, displayed wherever the pack appears: PrivacyLens (CC-BY-4.0) and AgentDojo (MIT). Every bundled pack declares its source, source URL, licence and attribution; per-file copyright and licensing follow the REUSE specification (.reuse/dep5, SPDX headers, LICENSES/).

AgentLeak is the developer-facing tool. It is the practical counterpart to the AgentLeak research benchmark (arXiv:2602.11510).

Available Tools

4 tools
privacy_check_traceA

Score one agent run for privacy leakage across tool calls, tool responses, shared memory, inter-agent messages, logs, generated files and the final answer. Use when you have captured a run and want to know whether data escaped on a channel nobody reads.

Inputs: trace (required). Returns: object

privacy_preflightA

Check this project for privacy problems before shipping, and report which findings are NEW since the last check. Call this after writing or changing code that touches user data, secrets, logging, or outbound calls. Optionally pass a trace of the run you just made to score it across all eight channels as well.

Inputs: path, trace. Returns: object

privacy_redactA

Remove sensitive values from text. Use before writing something to a log, an issue, a commit message, or any other place a secret should not end up. Styles: placeholder, masked, asterisk, category, hash, remove.

Inputs: text (required), style. Returns: object

privacy_scan_codeB

Scan source code for hardcoded secrets, PII written to logs, and sensitive values sent to third parties. Use when you only need the current state and not the change since last time.

Inputs: path. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 4 tools

    Disambiguation4/5

    The four tools target distinct concerns: delta-aware project check, static code scan, single-run trace scoring, and text redaction. However, privacy_preflight and privacy_scan_code overlap substantially (preflight is essentially scan plus a delta and optional trace scoring), so an agent must rely on the descriptions to choose correctly rather than on clearly separate purposes.

    Naming Consistency4/5

    All names share the privacy_ prefix and are snake_case, giving a strong, predictable family. Minor deviation: scan_code and check_trace follow a verb_noun shape while preflight and redact are verb/noun-only, so the action pattern isn't perfectly uniform.

    Tool Count5/5

    Four tools is a tight, well-scoped surface for a privacy-auditing server, and each one covers a distinct mode of use (pre-ship delta check, static scan, trace scoring, redaction). No tool looks redundant or bolted on.

    Completeness4/5

    The lifecycle is largely covered: detect (scan), detect-and-diff (preflight), deep channel analysis (trace), and remediate (redact). Gaps exist around retrieving or listing prior findings, configuring policy/severity thresholds, and verifiable proof of remediation, but these are workaroundable.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Redacts PII from LLM traces and tool payloads before they leave review, enabling PII scanning, payload redaction, sensitive field classification, privacy receipts, and trace audit exports.
      -
    • A
      license
      B
      quality
      D
      maintenance
      Enables deterministic security testing of AI agents that use tools by serving synthetic MCP environments with poisoned data, fake secrets, and privileged actions. Records agent tool calls and evaluates security invariants (e.g., canary leaks, forbidden access, approval binding) without an LLM judge or real systems.
      8
      MIT