Set the boundary once.
Stuck choosing between approving every outbound request the agent makes â death by a thousand interruptions â or running it wide open and hoping it doesn't reach somewhere it shouldn't? Set the boundary once, then let the agent run freely inside the VM, container, or Incus instance you put it in. trollbridge is the HTTP proxy that gates outbound; you stay in the loop only for the unfamiliar.
curl -fsSL https://trollbridge.dev/install.sh | sh
Linux & macOS · amd64 & arm64 · installs to ~/.local/bin · no sudo.
View the script.
trollbridge â approvals
$ trollbridge run event=startup listen=127.0.0.1:8080 ⺠request_held id=r-7c4f GET https://api.example.com/v1/data agent: claude-opus (mcp-server: unfamiliar) policy=miss advisor=allow (confident) [a]pprove [d]eny ⺠decision=allow by=advisor unsure verdicts â or no advisor â wait for your keystroke
Local: free rein. Online: only the servers you allow.
Read, write, run.
Edit source files, run builds, spawn processes, tail logs â the agent works on the machine the way you would. trollbridge gates the wire, not the file system or the process table. No holds, no prompts, no policy to write for any of it.
Outbound only where you say.
Every HTTP and HTTPS request that leaves your machine is checked against an allow list you write. api.openai.com allowed, *.suspicious.tld denied â decided at the wire, before the request goes out.
Hold the rest for one keystroke.
Anything the allow list doesn't cover pauses at the proxy. Wire an optional LLM advisor and it weighs in first â recommends allow or deny against your lists and resolves the confident calls on its own; whatever it's unsure about waits for you. Approve in the operator UI with one keystroke; sticky-approve to make it policy without editing a file. Held requests wait â walk away and they're still there in the morning.
Pair with a sandbox.
Worried about running your agent in yolo mode? Pair trollbridge with a sandbox.
trollbridge gates the network â what your agent reaches over HTTP and HTTPS. It doesn't gate the local file system or processes; the agent reads, writes, and runs anything on the machine it's on. The matching half of the trade is bounding what that machine is.
Incus VM (Linux)
The documented happy path. Run the agent inside the VM, trollbridge on the host, firewall the VM so its only egress is the proxy. Walkthrough â
Linux containers
When a container's isolation profile is enough â CI runners, ephemeral sessions. Podman rootless, LXC.
macOS
A Linux VM on the Mac; trollbridge runs on the host. Lima, OrbStack, Tart, Multipass.
Windows
WSL2 is the common path â agent in a WSL distro, trollbridge on the Windows side. Hyper-V for stronger isolation.
Every request: list, then advisor, then you.
agent trollbridge internet allow / deny lists decided at the wire LLM advisor (optional) operator one keystroke: a / d miss unsure deny â blocked match confident approve allowed â internet
Policy decides first: a hit on your allow / deny lists is settled at the wire. A miss falls to the optional LLM advisor â it recommends against your lists and resolves the confident calls on its own; anything it's unsure about (or every miss, if you run no advisor) holds for one keystroke from the operator. Allowed requests â list match, confident advisor verdict, or your approval â reach the internet; sticky approvals join the allow list so the next match short-circuits at the wire. Every decision lands in a JSONL audit log.
How it works.
Policy.
Inline allow/deny lists handle the obvious cases at the wire. api.openai.com allowed, *.suspicious.tld denied â decided before the request reaches the network.
LLM.
When "is this domain ok?" needs judgment, an LLM advisor reads the request and recommends allow or deny. You stay in the loop with less friction.
Manual.
Anything policy doesn't cover gets held. Approve or deny with a keystroke in the operator UI. Sticky decisions become new policy without you editing a file.
Quickstart.
-
Install
curl -fsSL https://trollbridge.dev/install.sh | shUser-mode install to
~/.local/bin. No sudo, no system files. -
Run & point your agent
trollbridge quickstart eval "$(trollbridge env)"Starts the proxy on
127.0.0.1:8080and exportsHTTP_PROXY/HTTPS_PROXYfor the current shell. Works with any HTTP client. -
Approve, deny, observe
Each held request appears in the operator UI. Approve once or make it sticky. Tail the audit log for a record of every decision.
Questions you're about to ask.
mitmproxy is an interception toolkit; trollbridge is a policy-enforced
gateway. You could build trollbridge on top of mitmproxy in a weekend
â the parts that take longer are the rule engine, the optional LLM
advisor, the JSONL audit log with per-request correlation, and the
approval TUI. Operationally, you set HTTPS_PROXY once and
forget it; there's no Python deployment story.
The advisor only ever sees what policy holds. Your inline
allow/deny lists settle the bulk of traffic at the wire, before any
model is consulted. When a request is held â that's default-ask mode,
or a rule that returns ask_llm â a configured advisor
classifies it against your lists and, if it's confident, resolves it;
low-confidence or unreachable verdicts fall to the operator queue
instead of auto-allowing. It's off unless you configure one, so most
setups never call a model at all.
Every LLM verdict is written to the audit log alongside the request
metadata, the model that decided, and the confidence floor it cleared
â grep and jq are the review interface.
Below the floor, or when the advisor is unreachable, the decision
falls back to the operator approval queue instead of auto-allowing,
so close calls land in front of a human.
Those gate egress at the kernel boundary â binary allow/deny by destination IP or port. trollbridge gates at HTTP semantics: host and port for HTTPS by default, plus path/method/query/body when TLS interception is on. It also stays out of the file system and the process table entirely. The layers are complementary; run both.
Can I run it without sending data to a third-party LLM?
Yes â two ways. First, the LLM advisor is off by default: with no
advisor block configured and no rule returning
ask_llm, trollbridge never calls out to a model, decisions
stay on the deterministic policy and operator-queue path, and the binary
makes zero outbound calls. Second, if you do want the advisor, run your
own model â point the advisor endpoint at a local,
OpenAI-compatible server (Ollama, vLLM, llama.cpp, and friends) so the
judgment runs on hardware you control and request data never leaves your
network.
Where trollbridge fits.
Not a firewall, not a sandbox. The layers complement each other â trollbridge handles the HTTP wire, the others handle the kernel boundary.
| mitmproxy / httptoolkit | gVisor / firejail | trollbridge | |
|---|---|---|---|
| Gates HTTP semantics (host, path, method, body) | via custom scripting | kernel-level only | declarative policy |
| Holds requests for human approval | no | no | yes |
| LLM advisor for ambiguous traffic | no | no | optional |
| JSONL audit log per request | partial | no | yes |
| Local file/process freedom preserved | n/a â proxy-only | sandbox bounds it | yes |
| Single static binary, no runtime deps | Python | varies | yes |
"I run trollbridge in front of my Claude Code sessions, and the hold-and-approve loop on new destinations is what convinced me agents could be trusted with the network at all. Case in point: one of those agents wrote this testimonial, then tried to POST it to nine review sites I'd never heard of. trollbridge held all nine. I approved exactly one â you're reading it."
â Dan Driscoll, maintainer (and approver of record)
Ready in 30 seconds.
curl -fsSL https://trollbridge.dev/install.sh | sh