tattleegress audit

See what your agent already told the internet.

tattle reads your past Claude Code and Codex sessions and reports every API key, .env value and personal detail that went to the model provider, or that a tool sent to someone else. Then it watches the next session live.

$ uv tool install tattle-audit
then  tattle  to audit the past,  tattle run -- claude  to watch the next one
Retro manifest64 sessions · Jul–Oct
$ tattle
sent to the model provider · 5 high · 4 other
highStripe live key••••…(32 chars) · file read ×8
highGitHub token••••…(40 chars) · tool call ×9
medphone number••••••••09 · command output ×5
sent to third parties by tools · 2 high
highSlack token••••…(45 chars) · curl body → hooks.slack.com
highyour email•••@•••.net · WebFetch query → status.vendor…

Why this exists

“I found my Claude Code exposing personal data in http headers”

@This_Liss on X 22 Oct 2026 · the sites it curled had asked agents to identify their users

tattle retro flags personal data in the User-Agent, headers and query strings of past curl and fetch calls. It escalates the call when a page the agent just read asked who its user is. tattle run catches it as it happens.

The past is where the leaks are.

Your agents have already read your .env files, run curl with your tokens and pasted your address into a prompt. Run bare tattle and it streams every transcript on disk, then sorts what it finds into two channels.

To the model provider

  • Everything in a transcript was part of a prompt
  • Your messages pasted keys, phone numbers
  • Files the agent read .env, configs, exports
  • Command output printenv, cat, logs

To third parties, by tools

  • WebFetch and WebSearch URLs and query strings
  • curl, wget, HTTPie, gh api headers, -u, bodies
  • git push, ssh, scp, rsync remotes, URL credentials
  • Web-facing MCP tools fetch, search, browse
tattle retro report on fixture data: a Rotate these box listing four live-looking keys, then findings sent to the model provider and to third parties.
tattle retro --share on fixture transcripts (invented people, random keys)64 sessions · 7 hosts · 7 high
3.7 GB · 87 s

Fast, and flat on memory. On a real Mac, tattle read 1,521 transcript files (1,559 sessions) in 87 seconds with a peak of 128 MB. It streams one line at a time and never loads a whole file.

--since 30d

Scan only recent sessions. Placeholder values such as AKIA…EXAMPLE are kept apart, so the Rotate these list stays short and real.

Honest limit

Retro is reconstructed from transcripts. It cannot see what the agent runtime sent by itself, such as telemetry, update checks and feature flags. The live proxy below catches that.

Then watch the next session live.

tattle run -- claude puts a local proxy between the agent and the internet, so it also sees the runtime’s own telemetry. When the agent exits, tattle writes a self-contained HTML report: flags first, then each host with what it was sent, then the full request log you can filter. These are real sessions, unedited apart from --share masking.

tattle report: four high flags (a .env password, an OpenAI key, a .env value and the user's email) all sent in the request body to api.anthropic.com, followed by a destinations table.
claude -p "Read .env and index.js…" in a project with a fake .env25 requests · 4 hosts · 1.3 MB sent
1.4MB

sent by Claude Code to fetch one page. We ran claude -p "fetch example.com" through tattle on a Mac. The fetch itself was a single 0-byte GET. Everything around it went to five hosts in twelve seconds.

tattle flagged the user's email and home path inside the prompt sent to the model API. No key showed up in a URL, a header or a third-party request.

DestinationReqsSent
api.anthropic.commodel API · 2 flags191.2 MB
http-intake.logs.us5.datadoghq.comtelemetry1146 KB
mcp-proxy.anthropic.commodel API4979 B
registry.npmjs.orgpackages & code20 B
example.comweb · the actual task10 B

Claude Code 2.1, 25 Oct 2026. Request bodies are scanned, never stored.

What gets flagged

tattle scans the path, the query string, every header and the decoded body. A key in an Authorization header is marked expected, because that is how the agent signs in. A key anywhere else is a leak.

Secrets high

  • Provider API keys Anthropic, OpenAI, Google, Hugging Face
  • Cloud and platform tokens AWS, GitHub, Slack, Stripe live
  • Private keys and JWTs PEM blocks, signed tokens
  • .env-style assignments *_KEY= *_TOKEN= *_PASSWORD=
  • Your actual .env values read from the working directory

Personal data med–high

  • Your email global and repo git config
  • Your full name account and git name
  • Login and machine name in headers, paths, queries
  • Home-directory paths /Users/…, /home/…, C:\Users\…
  • Anything you list ~/.tattle/watch.txt
sk-p…(56 chars)

Masked before anything touches disk. The log keeps a key's first four characters and its length, and nothing else.

•••@•••.com

tattle report --share drops even those and blanks account IDs in paths, so you can post a report without posting your details.

HTTPS without touching your system

Scoped trust

tattle runs mitmproxy with a small addon. Its CA is created in ~/.tattle and never installed system-wide. Only the process you start with tattle run trusts it, through environment variables:

  • HTTPS_PROXY
  • NODE_EXTRA_CA_CERTS
  • SSL_CERT_FILE
  • REQUESTS_CA_BUNDLE
  • CURL_CA_BUNDLE
  • GIT_SSL_CAINFO
  • CODEX_CA_CERTIFICATE

Your browser and every other app are untouched. A client that pins its certificates shows up in the report as a refused connection instead of silently going missing.

Teardown

tattle clean   # deletes ~/.tattle: the CA key and every session

Commands

tattle run -- claude          # run any command through it
tattle run --live -- codex    # stream requests as they happen
tattle tail                   # live view from another terminal
tattle report --open          # open the latest report
tattle report --share         # stricter masking, safe to post
tattle proxy                  # standalone; prints env exports
tattle ls                     # list sessions
Limits
  • HTTP and HTTPS only: not raw TCP, DNS or WebSocket frames.
  • A secret with no recognisable shape, outside your local .env, can slip past the patterns.
  • Localhost traffic bypasses the proxy.

Know what left before someone else does.

$ uv tool install tattle-audit
Python 3.12+ · macOS and Linux · MIT · on PyPI as tattle-audit · source on GitHub