oproxy: a programmable Rust proxy with a web UI and an AI control plane
Open-source MITM proxy to intercept, inspect, and mock network traffic.
At a glance
- What is it?
- oproxy is an MIT licensed local proxy written in Rust that captures HTTP, HTTPS, HTTP/3, WebSocket and SOCKS5 traffic, lets you replay, mock, rewrite, throttle and script it, and adds an OpenAI-compatible assistant that prepares changes as reviewable cards. It suits developers debugging an API or testing a mobile app, and the MITM trust decision is the whole security story.
- Who is it for?
- oproxy fits a developer who needs to see exactly what an application sends to an API, to replay a request against a test server, or to mock an upstream without changing a line of application code, since the sessions view, the Compose editor and the HAR export cover that workflow in one local process.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 36 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One local process for capture, UI, API and assistant
oproxy is a local HTTP, HTTPS, HTTP/3, WebSocket and SOCKS5 proxy for inspecting, replaying and modifying traffic from browsers, command line tools, mobile apps, API clients, services and test suites. The project positions it against commercial tools in its topic tags, naming charles-alternative and charles-proxy-alternative.
The architecture decision is in the second paragraph of the README. The web UI, the API and an optional AI assistant run on the same local listener, so you can capture traffic, inspect requests and responses, replay requests, mock upstreams, rewrite traffic, throttle responses and export reproducible snippets without changing application code.
That last clause is the point of the whole project. The usual cost of intercepting traffic is that you have to modify the application, install a certificate, or route through a sidecar. oproxy is designed so the application does not know, and the certificate is the only concession.
The highlight list is concrete about what the inspection surface covers: headers, bodies, status, timing, tags, notes, JWTs, GraphQL, gRPC metadata and WebSocket frames. That list is a good indication of the target user, someone working on an API client, a mobile app or a service integration rather than someone browsing the web.
The licence is MIT, the primary language is Rust, and the last push was on 2026-09-16, the same day as the v0.1.11 release. The repository is not archived.
The CA decision, and the assistant that prepares changes for review
Two things need to be understood before anything is run: how the trust works, and what the assistant is allowed to do.
The security note is short and explicit. HTTPS interception requires trusting a local oproxy root CA, and the instruction is to install that CA only on machines and browsers you control, to keep the generated private key safe, and not to expose the admin UI without a strong token. A MITM proxy is a certificate authority for your traffic, and its private key is the most sensitive file in the project. The CA is generated with rcgen and served for installation from an admin endpoint.
The Assistant is described as an OpenAI-compatible control-plane client, and the distinction it draws is a good one. It can inspect current proxy state through allowlisted tools and prepare traffic and configuration changes as reviewable confirmation cards. So the model does not act, it proposes. The actual state-changing operation happens when a human accepts a card.
That design is what makes an AI feature tolerable in a security-sensitive tool. A model that could silently rewrite a proxy rule or install a mock would be a liability, and the allowlist plus the confirmation card put a human in the loop at the exact point where it matters. The documentation separates this into its own page at docs/assistant.md, with configuration in docs/configuration.md and security notes in docs/security.md.
The topics list includes ai-powered, and the second highlight bullet is about using the Assistant to inspect sessions, understand proxy state and prepare confirmed changes through an OpenAI-compatible chat model, so you can point it at any model that speaks the API.
Running it in Docker, and why bridge networking needs 0.0.0.0
The Docker quick start is a single command with an unusual number of flags, and each one teaches you something about how the tool is configured.
docker run --rm \
--name oproxy \
-p 127.0.0.1:8080:8080 \
-p 127.0.0.1:1080:1080 \
-p 127.0.0.1:8443:8443/udp \
-e OPROXY_BIND_HOST=0.0.0.0 \
-e OPROXY_MITM_ENABLED=true \
-e OPROXY_HTTP3_ENABLED=true \
-e OPROXY_HTTP3_PORT=8443 \
-e OPROXY_ALLOW_REMOTE_ADMIN=true \
-e OPROXY_ADMIN_TOKEN=change-me-to-a-strong-secret \
-v oproxy-certs:/app/certs \
-v oproxy-storage:/app/storage \
ghcr.io/sauravrao637/oproxy:latestThe port mappings bind to host loopback, so nothing is exposed to the network even though the container listens on 0.0.0.0. That combination is not accidental, and the compose file explains why in unusually detailed comments. Docker bridge networking needs OPROXY_BIND_HOST=0.0.0.0, and Docker's port-publishing NAT means the proxy never sees a genuinely loopback peer even for host-local traffic, which is why reaching the admin UI through the published port relies on OPROXY_ALLOW_REMOTE_ADMIN plus OPROXY_ADMIN_TOKEN rather than the loopback-peer check used on bare metal.
The compose file also documents the 8443 situation, which looks like a conflict and is not. Both mappings use port 8443, but they are two distinct listeners on two distinct transports: HTTP/3 is UDP-only over QUIC, while OPROXY_HTTPS_PORT is a TCP listener, and the TCP mapping is only useful if you uncomment that variable. The SOCKS5 mapping on 1080 is present in the run command but commented out in the compose file, to be enabled with OPROXY_SOCKS5_PORT.
Two named volumes persist the certificates and the storage across runs, which matters because regenerating the root CA invalidates every browser and device that trusted the old one.
Building from source, and a Rust and Node toolchain in one repo
The source route needs Rust 1.85 or newer, Node.js 22 or newer, and Yarn via Corepack, and it is a three step sequence:
corepack enable
yarn --cwd src/design install --frozen-lockfile
yarn --cwd src/design build
cargo run --releaseThe design directory has its own package.json and its own lockfile, because the web UI is a separate frontend application that is built and then embedded in the Rust binary. The Dockerfile shows the same structure with explicit stages: a node:22-bookworm-slim stage that installs the UI dependencies and runs the UI build, then a rust:1.95-slim builder stage, then a debian:trixie-slim runtime stage. The copy from the UI stage into the Rust build is the moment the two halves become one binary.
The dependency set in Cargo.toml confirms the design. Axum is the HTTP server, Tower and tower-http supply the middleware stack, reqwest is the outbound client configured with rustls and HTTP/2, and rustls with tokio-rustls handles TLS, with rcgen generating the root CA. There is no OpenSSL in the dependency list, which is consistent with a project that wanted no system TLS dependency in the runtime image.
Two feature flags are worth knowing. The http3 feature pulls in quinn, h3, h3-quinn and webpki-roots for QUIC support, and the otel feature gates OpenTelemetry export of per-exchange protocol spans, with the exporter layer attached at the logging layer. Both are off by default, and default = [] in the features table, so the default build is a plain HTTP and HTTPS proxy.
The Cargo.toml also carries a lint policy in the repository so every contributor gets the same bar locally and not only in CI, with unsafe_code set to warn, which forces a documented allow at each genuine unsafe site, and clippy all set to warn.
The Compose editor, the rules engine and the export formats
The modification surface is where a proxy tool either becomes useful or becomes a toy, and oproxy covers it broadly. The highlight list names rules, mocks, map-local and map-remote, access rules, throttling, breakpoints, DNS overrides, Lua scripts and upstream proxy chaining.
Those are the features of a professional interception tool rather than a packet logger. map-local and map-remote redirect a request to a different host, which is how you point a test at a local server without editing configuration files. Mocks return a canned response for a matching request. Breakpoints hold the exchange until you act. DNS overrides change name resolution. Lua scripting gives you arbitrary transformation logic, which is the escape hatch when none of the built-in rules fit. And upstream proxy chaining lets oproxy sit in front of another proxy, which is how you add your own to an existing corporate egress setup rather than replacing it.
The inspection side is equally complete. JWTs are decoded so you can read a token without a separate tool, GraphQL and gRPC metadata are surfaced, and WebSocket frames are captured, which is where a surprising amount of real application logic lives that never appears in an HTTP log.
Two output paths make the captured data useful afterwards. Replay lets you take a captured request and send it again, optionally edited, and the export formats are HAR, cURL, Fetch and Python snippets. HAR is the one that matters most, because it is the format every other analysis tool reads, and the cURL export is the one that turns a captured request into a bug report someone else can run.
The repository carries two example files that show the embedding side, custom_middleware.rs and embed_proxy.rs, which are the answer for anyone who wants oproxy as a library inside a Rust application rather than as a separate process.
Where oproxy is the wrong tool
The first and most important case is a machine you do not control. A MITM proxy requires every TLS client on that machine to trust a certificate that the proxy holds the private key for. On a work laptop with device management, on a shared server, or on anything with a security policy, that is a non starter. The README's own instruction to install the CA only on machines and browsers you control is the security model stated plainly, and the failure mode of ignoring it is silent and total.
The second case is a shared or long-lived deployment. The project version is 0.1.11, which is early, and the release cadence has been roughly monthly through 2026 with v0.1.9 on 2026-06-14, v0.1.10 on 2026-07-15 and v0.1.11 on 2026-09-16. That is active development of a young tool, which is fine for a developer tool on your own machine and wrong for something a whole team depends on for a release pipeline.
The third case is when you only need to read a request and nothing else. If the goal is to see one API response, a terminal tool or a browser network panel does it with no certificate to install and no token to manage. oproxy pays for itself when you need replay, mocking, scripting or multi-protocol inspection, and it is overkill when you need one of the first three things on the list of highlights.
The alternative worth comparing is a script with a scripting HTTP client, for example a Python script using a requests wrapper with a CA bundle you control. The difference in approach is that a script is a program you write for a specific question, while oproxy is a persistent environment that holds your traffic and lets you experiment interactively. For a one-off capture the script is faster. For an afternoon of trying three different mock responses against the same endpoint, the interactive tool earns its setup cost, and its replay and export features are what turn that afternoon into something you can hand to a colleague.
Editorial conclusion
oproxy fits a developer who needs to see exactly what an application sends to an API, to replay a request against a test server, or to mock an upstream without changing a line of application code, since the sessions view, the Compose editor and the HAR export cover that workflow in one local process. It is the wrong choice for a machine you do not control, since trusting the root CA means the proxy can read everything that passes through it, and it is the wrong choice if you need a maintained, audited proxy for a team. Before running it, set OPROXY_ADMIN_TOKEN to a real secret rather than the placeholder, install the CA only on machines and browsers you own, and confirm the ports stay bound to host loopback, because the container needs OPROXY_BIND_HOST=0.0.0.0 for bridge networking and that is exactly the setting that makes the mistake easy.
Frequently asked questions
How do I run oproxy with Docker?
Run the published image with the ports bound to host loopback, set OPROXY_BIND_HOST=0.0.0.0 so bridge networking works, and set OPROXY_MITM_ENABLED=true, OPROXY_HTTP3_ENABLED=true with OPROXY_HTTP3_PORT=8443, OPROXY_ALLOW_REMOTE_ADMIN=true and a real OPROXY_ADMIN_TOKEN. Then open http://127.0.0.1:8080 and sign in with that token.
How do I capture HTTPS traffic with oproxy?
Trust the local root CA. You can fetch it with curl http://127.0.0.1:8080/admin/ca and pass it with --cacert, or configure the browser or OS to use 127.0.0.1:8080 as the HTTP and HTTPS proxy and import the CA from the same admin URL.
What can the oproxy Assistant do?
It is an OpenAI-compatible control-plane client that inspects current proxy state through allowlisted tools and prepares traffic and configuration changes as reviewable confirmation cards, so a human accepts the change rather than the model applying it.
How do I build oproxy from source?
You need Rust 1.85 or newer, Node.js 22 or newer and Yarn via Corepack. Run corepack enable, then yarn --cwd src/design install --frozen-lockfile, then yarn --cwd src/design build, then cargo run --release, and open http://127.0.0.1:8080.
What licence is oproxy released under?
oproxy is MIT licensed, with the licence file at the repository root. The repository is not archived and the last push was on 2026-09-16, the same day as the v0.1.11 release.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sauravrao637-oproxy)Was this useful?