v0.4.1 shipped · mit licensed · local-only

See what your AI tools actually send

When you press Tab in Cursor or paste into Claude, the assumption is “just my prompt goes out.” The reality is messier. upbox is a local proxy and dashboard that records every request your AI assistants make, redacts secrets before forwarding, and keeps a tamper-evident audit log of what happened: on your machine, with zero cloud calls.

Tamper-evident audit log Zero outbound calls VPN-safe by default Linux · macOS · Windows
~/projects · zsh3 lines
$pipx install upbox-sh
$upbox init # one-time CA install
$upbox start # curated capture · VPN-safe
dashboard ready at http://127.0.0.1:8800
CA installed · proxy readyPython 3.12+ · or one binary, no Python
what's leaving your laptop

A day in the life of one developer.

illustrative figures · your real numbers appear in the dashboard · single workstation

captured2,847requestsacross 6 AI toolsCursor, Claude, Copilot, ChatGPT, Codeium, Gemini: all logged locally.
redacted41secretsbefore they shipped.env vars, AWS / OpenAI / Anthropic / GitHub tokens. All stripped at the proxy layer before forwarding.
blocked12unknown hostsoff the allowlistTools quietly reaching new domains. You'd never have seen any of these without upbox.
outbound from upbox0bytesphone-home callsThe auditor itself stays local. Binds 127.0.0.1 only. The whole point.
the problem

“Just my prompt goes out.” Not really.

Vendors aren't necessarily being shady. Their docs just don't match what people think is happening, and there's no built-in way to verify from the outside. So we built one.

  1. 01
    The current file. Often neighbor files too.
    Tab-complete in Cursor frequently ships several KB of surrounding context, including files you didn't have open.
  2. 02
    The project tree, env vars, sometimes shell history.
    Workspace metadata gets bundled in. None of it is logged anywhere you can read.
  3. 03
    Secrets from .env files you never meant to share.
    An AWS_ACCESS_KEY sitting two lines above the function you're editing goes out by default.
  4. 04
    4–8 AI tools running at once.
    A typical developer can't track all of it. Nobody can.
live preview

The dashboard, running locally.

Every request, in real time, grouped by tool. Click any row to inspect the body, headers, redactions, and what was forwarded.

↓ this is rendered with mock data,
but the layout is the real dashboard.
http://127.0.0.1:8800/feedupbox v0.4.1
8requests
1redacted
1blocked
127.0.0.1bind
live
timetool · host · pathsizeredactstatus
-2sCsPOSTapi2.cursor.sh/aiserver.v1/AiService/StreamChat12.4 KB·forwarded
-7sClPOSTclaude.ai/v1/messages8.9 KBforwarded
-14sCoPOSTapi.githubcopilot.com/v1/engines/copilot-codex/completions3.2 KBredacted
-21sCsPOSTapi.cursor.sh/aiserver.v1/AiService/CmdK21.7 KB·forwarded
-34sGpPOSTapi.openai.com/api/conversation4.1 KB·forwarded
-41sCdPOSTserver.codeium.com/exa.language_server_pb.LanguageServerService/GetCompletions6.3 KB·blocked
-58sCsPOSTapi2.cursor.sh/aiserver.v1/AiService/StreamChat9.0 KBforwarded
-1m 11sClPOSTclaude.ai/v1/messages14.2 KB·forwarded
Tool
Cursor
Destination
api2.cursor.sh
SHA-256
00000000…
Forwarded
yes
Request body (100 KB excerpt)
{
  "model": "gpt-4o-cursor",
  "stream": true,
  "messages": [
    { "role": "system", "content": "You are a coding assistant." },
    { "role": "user", "content": "Fix the type error in this file." }
  ],
  "context": {
    "file": "src/payments.ts",
    "neighbors": ["lib/utils.ts", "types.d.ts"],
    "snippet": "const STRIPE_KEY = 'sk_live_3Hf9...XQpZ';\n  const AWS_ACCESS = 'AKIAXXXXXXXXXXXXXXXX';"
  },
  "metadata": { "endpoint": "cmd-k", "workspace": "monorepo" }
}
what's in upbox

Six capabilities. One binary. One SQLite file.

download · no pythonnew in v0.4.1

One file per platform. On Windows, double-click and it runs.

Every release ships one-file executables for Windows, macOS (Apple Silicon) and Linux, built and smoke-tested on GitHub's runners, with a .sha256 beside each. Double-click upbox.exe and it asks for administrator rights, asks once before installing the local CA, starts, and opens the dashboard in your browser. Unsigned for now; pipx stays the path for Intel Macs and other architectures.

upbox start --open opens the dashboard|glibc 2.35+ on Linux
upbox-0.4.1-windows-x86_64.exedouble-click
upbox-0.4.1-macos-arm64.dmgcopy, then xattr -d
upbox-0.4.1-linux-x86_64.tar.gztar, then install
01capture · VPN-safe

Live feed, curated capture

Every request as it happens, grouped by tool. 15 bundled fingerprints: Cursor, Claude, Claude Code, Copilot, ChatGPT, Windsurf, Codeium, Continue, Cody, Perplexity, Tabnine, Replit, plus generic OpenAI / Anthropic / Gemini fallbacks. upbox start redirects only a curated list of AI-tool processes; VPN clients (Tailscale, WireGuard, OpenVPN, NordVPN, Mullvad, ProtonVPN) and unrelated apps are never touched, so tunnels stay up. Override with --capture-spec "claude,cursor" or --capture-all.

Cursor · Claude · ChatGPTcapture
Codex · Ollama · browserscapture
Tailscale · WireGuard · VPNsskip
02inspect

Bodies, headers, the lot

The actual prompt. The actual file content. The actual headers, with credential values replaced by markers. JSON, NDJSON, and SSE bodies formatted and captured up to 100 KB. Content-Type-aware: parses JSON properly so gzipped or nested-field secrets don't slip through. Or store no bodies at all: capture.yaml keeps metadata only.

"model":"claude-sonnet-4-5"
"file":"server/db.ts"
"key":sk_live_3Hf9…XQpZ
03redact

Strip secrets before forwarding

Regex rules strip .env blocks, API keys, and PII patterns before the request reaches the cloud. Ships with AWS / OpenAI / Anthropic / Google / Slack / GitHub defaults, live-reloaded when you edit them. Auth headers and URL keys are never written to the audit log.

AWS_KEY=AKIA…AWS_KEY=[REDACTED]
04enforce

Domain allowlist per tool

Allow only the destinations you've sanctioned. An off-allowlist host is either flagged (warn: forwarded, but recorded) or blocked (HTTP 403, never leaves the machine). A TLS allowlist (built from tools.yaml) means non-AI HTTPS traffic passes as a CONNECT tunnel without decryption, so Teams and pinned-cert apps keep working. Banking, health, webmail, government, and identity providers are never decrypted at all, even under --capture-all.

api.anthropic.comallow
api2.cursor.shallow
unknown.hostblock
05audit

Evidence and subject rights

SHA-256 hash chain over every row, upbox verify to check it, upbox checkpoint to seal it. Export as upbox.audit.v1, JSONL, or CSV, filtered by tool and time range. capture.yaml can stop at metadata, upbox erase removes records as chain-preserving tombstones (GDPR Art. 17), and upbox report writes what upbox holds about you (Art. 15).

06local-only

Nothing leaves your machine

SQLite on disk. Dashboard binds to 127.0.0.1 only and refuses to start on any other host. Zero outbound calls from upbox itself. Owner-only file permissions, and upbox doctor tells you whether the disk underneath is encrypted.

127.0.0.1upboxinternet
architecture

Supervisor. Two children. Boring stack.

upbox start supervises two child processes: the proxy and the dashboard. They never talk directly. They share state through SQLite in WAL mode: the proxy writes audit rows, the dashboard reads them. SQLite WAL is the IPC. mitmproxy is the proxy core. FastAPI + Jinja2 for the dashboard: server-rendered partials, a little vanilla JS, no build step.

  • mitmproxy · MIT · proxy core
  • FastAPI · MIT · dashboard backend
  • Jinja2 · BSD-3 · server-rendered templates
  • SQLite · public domain · audit log
  • Typer · MIT · CLI framework
  curated AI processes                  (VPN clients, banking, OS noise:
  Claude · Cursor · ChatGPT              never redirected · tunnels stay up)
  Codex · Ollama · code · browsers
              
                LocalMode redirector · mitmproxy-rs · OS-level capture
  ┌─────────────────────────────────┐
    mitmproxy core + upbox addons    ─ AI host (allowlist) ─▶  decrypt · process · forward
  │  ┌───────────────────────────┐  │                              to cloud LLM
  │  │ 1 fingerprint (tag tool)  │  │
  │  │ 2 enforce     (allow|warn|403)│  │  ─ pinned host (off list) ─▶  CONNECT tunnel
  │  │ 3 redact      (json-aware)   │  │                              (no decryption ·
  │  │ 4 capture     → SQLite       │  │                               Teams · banking
  │  └───────────────────────────┘  │                               keep working)
  └────────────────┬────────────────┘
                   
         ┌──────────────────┐       ┌──────────────────┐
           SQLite · WAL    │ ◀────┤  dashboard       
           ~/.upbox/       │       │ FastAPI + Jinja2 
         └──────────────────┘       └──────┬───────────┘
                                           
                                           
                                   127.0.0.1:8800  ← you
                                   ✗ refuses any other host
install

Six ways. Same upbox.

Pick whichever fits your setup. The download needs nothing; the package installs need Python 3.12+.

then:
$ upbox init
$ upbox start
→ OS-level capture: no per-tool proxy config
(admin/root on first run for WinDivert / iptables / Network Extension)
→ open http://127.0.0.1:8800
Recommended when you have Python: isolated venv, no system Python conflicts.
# install pipx if you don't have it$python3 -m pip install --user pipx$python3 -m pipx ensurepath# install upbox (package: upbox-sh, command: upbox)$pipx install upbox-sh# verify$upbox --help
gdpr · eu ai act

The deadline moved. The evidence still has to hold.

On 24 July 2026, Regulation (EU) 2026/1744 deferred the AI Act's high-risk deployer obligations, Article 26 among them, to 2 December 2027 and 2 August 2028. Article 50 transparency applies since 2 August 2026, and GDPR always did. upbox is a deployer-side tool: it does not certify you compliant, it produces evidence and controls that hold up.

2025-02-02AI Act Article 4 (AI literacy) applies
2026-05-27upbox v0.1.0 ships
2026-05-31v0.1.1: 100 KB bodies · JSON pretty-print
2026-07-24Regulation (EU) 2026/1744 defers Article 26 by 16 months
2026-08-02Article 50 transparency applies
2026-09-04upbox v0.2.0: hash chain · audit export · retention · credentials never stored
2026-09-04upbox v0.3.0: metadata-only capture · erase on request · transparency report
2026-09-04upbox v0.4.1: one-file binaries for Windows, macOS and Linux
2027-12-02Article 26 applies to Annex III high-risk systems
2028-08-02Article 26 applies to Annex I high-risk systems
Obligation
What upbox does to help you comply
GDPR
Art. 5: data minimisation ↗Redaction runs before the request leaves the endpoint, capture can stop at metadata, and retention clears what was stored on a schedule.
  • Content-aware: JSON bodies parsed, walked, and re-serialised
  • Defaults: AWS / OpenAI / Anthropic / Google / Slack / GitHub keys and dotenv lines
  • Credentials in headers and URL query strings are never written to the audit log
  • capture.yaml with bodies: false and headers: false stores metadata only
  • Two-tier retention in retention.yaml: body_days (default 7) clears bodies and headers, record_days deletes rows and records the gap in the chain
GDPR
Art. 15: right of access ↗One command writes what upbox holds about the machine's user: categories and whether each is stored, recipients per tool and host, retention in force, erasures, chain status, and how to get a copy.
  • upbox report -o report.md --records records.ndjson: the hand-over document plus the machine-readable copy
  • The dashboard shows the same live at /transparency
  • The controller's identity is yours to fill in; the report says so rather than guessing
GDPR
Art. 17: right to erasure ↗Individual records can be erased without the audit log reading as tampered with.
  • upbox erase --id N --reason "...", or by host, tool, or time range, with --dry-run
  • The row becomes a tombstone: only the timestamp and chain hashes survive; every content column and digest is cleared
  • Disclosed, not hidden: upbox verify, every export, and the report count erasures and carry the reason
  • A legal hold refuses erasure until released (Art. 17(3)(e), data needed for legal claims)
GDPR
Art. 30: records of processing ↗A per-tool inventory of destinations, data classes, and volumes, taken from real traffic rather than from a questionnaire.
  • upbox export --format csv for the register, --format audit for evidence
  • Every row names the tool, the host, the size, and the outcome
GDPR
Art. 32: security of processing ↗Technical measures for visibility, control, and integrity of what leaves the endpoint.
  • Local CA the user installs and can uninstall (upbox init --uninstall)
  • Dashboard binds 127.0.0.1 only; zero outbound calls from upbox itself
  • Tamper-evident SHA-256 hash chain: upbox verify recomputes it, upbox checkpoint seals the head
  • Owner-only file permissions; upbox doctor reports whether the volume is encrypted. No in-app encryption, by design
GDPR
Art. 35: DPIA ↗Concrete per-tool data flows that feed impact assessments.
  • Per-tool destinations, data classes, and observed volume from the audit log
  • The audit export states its own coverage: what was intercepted and what passed through undecrypted
GDPR
Art. 88: employee monitoring ↗Intercepting TLS on an employee device is monitoring. Inform workers and their representatives first; in Italy it needs a union agreement or Labour Inspectorate authorisation under Art. 4 of Law 300/1970.
  • Never-decrypt list on by default: banking, health, private webmail, government, identity providers (no_intercept.yaml), even under --capture-all
  • Metadata-only capture is the recommended configuration on machines you do not own
  • Bodies cleared after 7 days by default; per-record legal hold when something must be kept
  • Read the Article 88 section of docs/ai-act-mapping.md before deploying on machines you do not own
AI Act
Art. 50: transparency · since 2 Aug 2026 ↗Records of AI-system interactions sufficient to support transparency duties toward affected persons. This is the obligation that actually landed in August 2026.
  • What was sent, when, where, by which tool, in what size, with what status. Queryable per tool, exportable.
AI Act
Art. 4: AI literacy · since 2 Feb 2025 ↗A visible, inspectable record of what AI tools are doing on your endpoints. The 2026 Omnibus softened Article 4 to taking measures that support AI literacy.
  • Live dashboard groups traffic by tool, host, request size
  • Audit log queryable and exportable per tool and time window
AI Act
Art. 26: deployer obligations · from 2 Dec 2027 ↗Per-request audit log supporting Art. 26(1) use-per-instructions and Art. 26(5) monitoring. Art. 26(6) covers logs the high-risk system generates about itself; upbox observes the network from outside, so its records corroborate those logs rather than replace them.
  • ts · tool · method · scheme · host · path · req_bytes · resp_bytes · status
  • body_hash · headers_sha256 · body_excerpt_sha256 · entry_hash: integrity that survives retention
  • redactions_applied_json · enforcement: what the engine intervened on, and whether the request was forwarded
  • upbox export --format audit: versioned NDJSON with ruleset digests, the chain verification result, and a coverage statement
  • upbox export --format jsonl|csv|audit with --since / --until / --tool filters
AI Act
Art. 99: penalties ↗Helps demonstrate good-faith effort and concrete technical measures.
  • Auditable open-source proxy + redaction + enforcement + retention
  • Exportable evidence trail rather than verbal policy claims
primary sourcesstable ELI URLs · publisher: EUR-Lex

upbox is not legal advice. It is a deployer-side technical measure: it produces evidence and controls, not a certification. Consult counsel for compliance sign-off. The article-by-article pages linked in the table render the Act as published in 2024 and do not yet reflect the 2026 Omnibus amendments; check dates against EUR-Lex and the official implementation timeline.

faq

Questions you should be asking.

A closed-source tool that watches your AI traffic is itself a privacy problem. The auditor has to be open.

No. upbox makes zero outbound network calls of its own. The proxy forwards the requests your AI tools were going to make anyway: that's the entire network footprint. The dashboard binds to 127.0.0.1 only and refuses to start on any other host.

Not since v0.4.0. Each release ships one-file executables for Windows x86_64, macOS Apple Silicon, and Linux x86_64 (glibc 2.35 or newer), built by PyInstaller on GitHub's runners and smoke-tested on each platform before upload. They bundle Python and mitmproxy. They are unsigned, so macOS needs xattr -d com.apple.quarantine and Windows shows SmartScreen once; a .sha256 sits beside every file. Intel Macs and other architectures use pipx install upbox-sh, which needs Python 3.12 or newer.

Stored locally in ~/.upbox/upbox.db (SQLite, WAL mode, owner-only permissions). The body_excerptcolumn holds up to the first 100 KB of each body; when a body is larger, the dashboard shows a “first 100 KB of N” notice rather than silently cutting it. body_hash (SHA-256 of the full body) and req_bytes (true size) are always recorded, so a truncated excerpt is still provable. Auth headers and credentials in URL query strings are replaced with markers before anything is written. By default, retention clears stored bodies and headers after 7 days while the row and the hash chain stay intact. Or store no bodies at all: see the next question.

Yes. ~/.upbox/rules/capture.yaml has two switches, bodies and headers. With both false, upbox keeps timestamps, tools, hosts, paths with credentials removed, sizes, status codes, the SHA-256 of each body, and the redaction and allowlist outcomes, and nothing a prompt contained. Redaction still runs on the way out. The setting is live-reloaded, editable on the dashboard settings page, and recorded in every audit export. A file that fails to parse puts upbox in metadata-only mode rather than storing more than you meant. It is the recommended configuration on machines you do not own.

It scales with how large the captured bodies are and how long you keep them. Retention is configured in ~/.upbox/rules/retention.yaml: body_days (default 7) clears bodies and headers but keeps the row, and record_days (default: never) deletes whole rows and records the gap in the chain so upbox verify reports a disclosed deletion rather than tampering. upbox prune --dry-run shows what a pass would remove; upbox hold exempts a range. With the defaults, the database stays small: once bodies are cleared, a row is roughly a kilobyte of metadata and hashes.

Yes, since v0.2.0. Every row carries a SHA-256 over its own fields plus the previous row's hash. upbox verify recomputes the chain and reports edited content, deleted rows, inserted or reordered rows, and a botched restore. What it cannot do: the algorithm is public and keyless, so anyone with write access to the file could recompute a consistent chain or truncate the tail. The chain is worth something once a head hash has left the machine, which is what upbox checkpoint is for: seal the head, then mail it, commit it, or have it timestamped. upbox will not anchor it for you, because it makes no outbound calls. Erasures on request are disclosed, not hidden: a tombstone keeps its position and hash, and verify counts it.

Yes. upbox erase --id N --reason "..." (or --host, --tool, --since, --until) erases individual records for GDPR Article 17. The row becomes a tombstone: tool, host, path, sizes, headers, body, and hashes of the content are cleared, and only the timestamp and the chain hashes stay, so upbox verify still passes and reports the erasure with its reason. Preview with --dry-run. A row under legal hold refuses the whole operation until you release the hold.

upbox report -o report.md --records records.ndjson. The Markdown says what upbox holds about this machine's user: the categories of data and whether each is stored, recipients per tool and host, the retention policy in force, any erasures, chain status, and how to get a copy or erase. The NDJSON is the machine-readable copy of the records. The dashboard shows the same at /transparency. The controller's identity is yours to fill in; upbox says so rather than guessing.

Not by upbox, on purpose. It runs as an unattended daemon, so any in-app key would sit next to the database and defeat strings upbox.db and nothing else. upbox sets ~/.upbox to 0700 and the database to 0600, and leaves encryption to the volume: FileVault, BitLocker, or LUKS, with keys in a TPM or Secure Enclave. upbox doctor reports whether that is on, along with file modes and chain health. The stronger control is not storing the data in the first place: metadata-only capture, redaction, and retention.

Negligible. The mitmproxy core handles tens of thousands of requests per second; AI tools peak in the low hundreds per hour. Latency added per request: ~1–5 ms.

A handful of mobile and certain desktop clients ship with hard-coded CA fingerprints. Without modifying the app binary, you can't MITM them. Known-working and known-broken tools are listed in the docs. Banking, health, webmail, government, and identity-provider destinations are deliberately never decrypted at all, whatever else you configure.

Yes. Edit ~/.upbox/rules/tools.yaml (or redact.yaml, allowlist.yaml, capture.yaml), or use the dashboard's /settings page. The running proxy picks up the change within about two seconds, no restart. A broken edit keeps the previous rules loaded. Adding a brand-new intercepted host still needs a restart, since the TLS scope is fixed at boot.

Technically yes. Legally, intercepting TLS on an employee device is employee monitoring, and GDPR Article 88 leaves the rules largely to national law; in Italy it needs a union agreement or Labour Inspectorate authorisation. Inform workers and their representatives first, run metadata-only capture, keep the default never-decrypt list, and read the Article 88 section of the AI Act mapping doc. Running upbox on your own machine raises none of this.

ship the screenshot

Install once. Run it for a week. The first screenshot is usually a surprise.

v0.4.1 just shipped: one-file binaries for Windows, macOS and Linux, no Python needed, on top of metadata-only capture, erasure, and the transparency report. The fastest way to help: install it, run it against your daily tools, and report what surprised you.

quick start~30s
$pipx install upbox-sh
$upbox init && upbox start
★ Star on GitHubkrishnamallam/upbox