Skip to content
GitHubOpen source
Product
Docs
Solutions
IndustriesAll industries
CompareCompare all AI data-leak tools
Benchmarks
GitHubApache-2.0

Integrating any endpoint

Shadow is not tied to a list of applications. If something sends HTTP requests to a model API, Shadow can sit in front of it. This page shows how to decide where to plug it in.

  1. Can you set a base URL? Use gateway mode. Most SDKs, CLIs and frameworks (LangChain, LlamaIndex, Vercel AI SDK, LiteLLM, the OpenAI and Anthropic SDKs) accept one, often from OPENAI_BASE_URL or ANTHROPIC_BASE_URL.
  2. Does it honour HTTPS_PROXY or the system proxy? Use proxy mode. This covers most IDE extensions, Electron apps, Python and Node scripts, and CI jobs, as long as they call an intercepted AI host. Tools that talk to their vendor’s own backend instead (GitHub Copilot, Cursor) are not masked unless you add that host with extra_hosts, and then only if Shadow can parse their request format.
  3. Is it your own Rust code? Embed shadow-core.
  4. Is the endpoint not a built-in provider? Add a route or an intercepted host for it (below).

Any HTTPS endpoint that accepts JSON prompts can be protected: an internal LLM gateway, a vLLM or TGI server on another machine, a vendor API that wraps a model.

[proxy]
# proxy mode: decrypt and mask traffic to these hosts too
extra_hosts = ["llm.internal.example.com"]
[proxy.routes]
# gateway mode: http://127.0.0.1:8877/gw/internal/... -> https://llm.internal.example.com/...
internal = "https://llm.internal.example.com"

Shadow masks every string value in a JSON request body, except protocol keys such as model, role and type, so it works with request shapes it has never seen. Responses are restored in full JSON bodies and in SSE or NDJSON streams. Streams of unknown formats are still restored string by string; only the cross-event reassembly of split fakes is format-specific (OpenAI Chat Completions and Responses, Anthropic, Gemini, Cohere and Ollama-style NDJSON).

Non-JSON request bodies are forwarded as they are, except for file uploads, which are masked.

Agents are where privacy and usefulness collide: the model has to act on real values. Shadow handles this with the intent-aware policy:

  • The person the instruction asks the agent to contact or act on is the recipient and passes through as written, logged, so the model addresses the right person ([policy.act] targets, default keep; surrogate fakes it).
  • When the agent’s tools run on your side (your code executes the tool call), the model sees fakes for everything else and writes tool calls with them. Shadow restores the real values in the tool-call arguments before they reach your code.
  • When tools run in the provider’s cloud (hosted MCP servers, server-side tools), Shadow cannot restore values there. By default it keeps real what the action needs (the contact details, people, companies, addresses, usernames and IBANs named in the instruction, and for a follow-up that names no email or phone, the emails, phones and people anywhere in the request), keeps secrets, cards and IDs masked, and logs each keep. You can change this.

Details and examples in Tool calls and agents.

Coding assistants send file contents, paths, hostnames and pasted configuration, which is exactly what Shadow is good at protecting. Usernames in paths (/Users/jdoe/...), internal hostnames, IPs and API keys are masked, and the code intent keeps identifiers readable.

  • VS Code and JetBrains extensions. Most use the IDE’s proxy setting or HTTPS_PROXY. Set the IDE’s HTTP proxy to http://127.0.0.1:8877 and make sure the CA is trusted by the OS (VS Code uses the OS store; JetBrains IDEs can be pointed at it in Settings → Tools → Server Certificates).
  • Terminal assistants and CLIs. Start them from a shell where env.sh is sourced, or set their base URL variable.
  • Desktop chat apps. Use the PAC file or system proxy for apps that call a provider API with your key. The ChatGPT and Claude desktop apps talk to their consumer backends (chatgpt.com, claude.ai), which are not intercepted. Apps that pin certificates will refuse the local CA; there is no workaround for those besides using a different client.

Point the service’s model client at the gateway URL through configuration, and run Shadow next to it as a service or sidecar. No code change is required beyond the base URL.

Terminal window
# Python, Node, Go, Java: any OpenAI-compatible client
OPENAI_BASE_URL=http://127.0.0.1:8877/gw/openai/v1 ./my-service
  • Run shadow scan on a few representative prompts and documents to see what is detected before you rely on it.
  • Add your organisation names, codenames and customers with organization, terms or shadow terms add.
  • Decide how actions in provider-hosted tools are handled ([policy.act] remote_tool_targets).
  • Keep Shadow on loopback, or inside the pod.
  • Check the log line per request (masked N value(s)) during rollout.

Frequently asked questions

Does Shadow work with Claude Code and other coding assistants?

Yes, when the tool accepts a base URL such as ANTHROPIC_BASE_URL or honours HTTPS_PROXY and calls an intercepted AI API host. Usernames in paths, internal hostnames, IPs and API keys are masked.

Does it work with Cursor or GitHub Copilot?

Not by default. They talk to their vendors' own backends, which are not on the intercept list; you can add a host with extra_hosts, but it is masked only if Shadow can parse the request format.

Can I protect a self-hosted or internal model API?

Yes. Add its host to [proxy] extra_hosts for proxy mode, or a route under [proxy.routes] for gateway mode. Shadow masks every string value in a JSON body, so unknown request shapes work too.

Are the ChatGPT and Claude desktop apps covered?

No. They talk to their consumer backends, chatgpt.com and claude.ai, which are not intercepted.