
Stop trusting privacy policies. Put your AI coding assistant behind a proxy and watch exactly what your code transmits: what fires on every keystroke, what "local mode" really hides, and how to shut the channel.
A deep read: the full picture, with the receipts.
AI coding assistants have a data transmission problem, not necessarily a malicious one, but an invisible one. Most developers using tools like GitHub Copilot, Cursor, Windsurf, Tabnine, or Continue (or terminal agents like Claude Code, Gemini CLI, and Codex CLI) have never watched their own network traffic during a completion request. They've read a privacy page, clicked accept, and moved on. That page is marketing copy with legal hedging. The packets are evidence.
This piece walks through a reproducible methodology for capturing that traffic, documents the transmission patterns that appear across popular tools, stress-tests "local mode" claims, and gives you a practical playbook for controlling what leaves your machine. The goal isn't alarm: it's clarity.
The Test Bench: How to Capture the Traffic#
The methodology matters more than the findings here, because vendor behavior changes with updates and you should be able to reproduce this yourself. The setup is straightforward.
Test repository design: Create a synthetic repo that mimics the shape of sensitive code without being actually sensitive. Include:
- A
.envfile with fake API keys in recognizable formats (e.g., strings that look like AWS access keys but aren't) - A file with a plausible-looking internal function name (
calculateRiskScore,applyProprietaryDiscount) - A configuration file with internal hostname patterns (
internal.corp.example.com) - Comments referencing a fake unreleased product name
Open all files in your editor before triggering completions. This maximizes the context window that tools can sample from and gives you a clear test of what gets included in payloads.
Capture triggers: test three distinct events separately, logging the full request URL, headers and body for each.
Limitations to be honest about: You're seeing what leaves the client. You cannot see what the vendor does with that data server-side: whether it's logged, deduplicated, retained, or fed into training pipelines. TLS inspection only gets you to the edge of their infrastructure.
Two client-side caveats also matter. First, WebSocket streams: some tools push completions over WebSockets, and mitmproxy intercepts those natively (each frame shows up in the flow detail, no special flag required). (The --ssl-insecure flag people reach for is unrelated; it tells mitmproxy to skip verifying the upstream server's certificate, which you occasionally need when a backend uses a cert mitmproxy can't validate.) Second, and more serious: certificate pinning. A tool that pins its server certificate rejects mitmproxy's injected CA outright: you'll watch the connection open and immediately fail, and you won't be able to read the payload at all. Some native desktop apps and hardened extensions do this. Getting past it means patching the client or hooking it with something like Frida to strip the pin, which is beyond a quick audit and may run afoul of the tool's terms. If a tool's traffic is pinned, treat the opacity itself as a finding: you're being asked to trust it without any way to verify.
What Fires on Keypress: Mapping the Transmission Triggers#
Across the tools most developers use, a few transmission patterns emerge consistently when you watch the proxy.
The critical observation: that context array often includes files you haven't explicitly referenced. Tools that index your workspace for retrieval-augmented completion will pull related files into the payload silently. If your .env is open in a background tab and the tool's context-gathering logic scores it as relevant, it may travel in that array.
'Local Mode' Under the Microscope: Do Air-Gap Claims Hold?#
Several tools advertise a "local" or "privacy" mode, and this is where the gap between marketing and packet inspection is most pronounced.
True local inference, a tool like Continue pointed at a locally hosted runtime such as Ollama or LM Studio, running an open-weight coding model (a Qwen or DeepSeek coder, say), produces a verifiably different traffic pattern. Completion requests go to 127.0.0.1 or localhost, not an external hostname. No code leaves the machine. This is reproducible and confirmable in about two minutes with mitmproxy.
But "local mode" in some commercial tools means something narrower. The model inference may be local while licensing verification, telemetry, and crash reporting still hit external servers. When testing, filter your proxy capture for any non-loopback connection during an editing session. A true air-gap should produce zero external connections after initial authentication. Several commercial tools fail this test: they continue to phone home on idle with session pings even when local inference is enabled.
Licensing pings are the most common survivor. Tools that require a valid subscription to unlock local mode must periodically verify that subscription. That verification request typically carries a device identifier and timestamp. It doesn't carry code, but it does tell the vendor that a specific licensed user is actively coding at a given time: a metadata trail.
If air-gap compliance is a hard requirement, a regulated environment or classified contract work, only fully open-source toolchains with self-hosted inference satisfy it without reservation.
Any commercial tool with a cloud-based license server has at minimum a metadata channel you cannot close.
Reading the Fine Print vs. Reading the Packets: Where Terms and Reality Diverge#
Vendor privacy pages typically cover three things: what data is collected, how long it's retained, and whether it's used for model training. The language is almost always ambiguous in the same specific ways.
The honest framing: an enterprise contract converts a privacy policy (which the vendor can change unilaterally) into a contractual obligation they can be sued for breaching. That's genuinely meaningful. It's not the same as the data not being transmitted.
The High-Value Targets: Code That Carries the Most Exposure#
Not all code is equally sensitive in context. These categories warrant explicit attention:
The common thread: these categories become risks not because you explicitly shared them, but because your context window is broader than you think and you never checked.
Your Egress Playbook: Practical Controls You Can Apply Now#
These controls are tool-agnostic and additive: stack as many as your threat model requires.
Context hygiene first: Only open files you're actively working on. Close background tabs with config files, .env files, and test fixtures before using AI completion. This is low-tech but directly reduces the surface area of what can enter a context window.
Know your tool's exclusion mechanism: they all differ: There is no universal .aiignore standard yet, and the differences matter.
Whatever your tool, put .env, *.pem, *secret*, *credential*, and any fixtures with real data on the list: then confirm with a proxy capture that the exclusion is actually honored. "Ignored" is a vendor claim like any other.
What We Still Can't See: Honest Gaps#
Proxy inspection gets you client-side truth, when the client lets you have it. It doesn't get you server-side reality. You can confirm that a payload was sent; you cannot confirm what the vendor does with it once it arrives.
Vendors can change their transmission behavior in an update. The tool you tested this month may behave differently next month. Treat your traffic audit as a periodic check, not a one-time certification.
Embeddings and derived representations are invisible to you. If a vendor's system converts your code snippet into a vector embedding for retrieval or fine-tuning, that embedding may persist long after any raw code retention window expires. Current privacy frameworks are still catching up to this distinction.
Finally, enterprise contracts give you legal recourse, not technical certainty. You're trusting a vendor's infrastructure controls and audit commitments. For most organizations that's an acceptable risk posture. For classified or highly regulated environments, it isn't, and the only alternative is eliminating the external channel entirely.
Key takeaways:
This article is informational and does not constitute legal or compliance advice. Organizations in regulated industries should consult qualified counsel before adopting any data-handling policy.
Sources
- GitHub, Responsible use of GitHub Copilot featuresdocs.github.com
- GitHub, Copilot documentationdocs.github.com
- Cursor, documentation (agent, rules, MCP)cursor.com
- Carlini et al., Extracting Training Data from Large Language Models (USENIX Security '21)usenix.org
- mitmproxy, the interactive HTTPS proxymitmproxy.org



Discussion