BareProxy is an operating system for web traffic. The core is the kernel: TLS, routing, static files, backend health and safe config changes, small and slow to change. Plugins are the apps. Each is a WebAssembly module, installed by one line in the config and removed by deleting it, so plan shows the change, apply makes it live and rollback takes it back. No rebuild, no restart. Proxy-Wasm is the system-call interface a plugin uses to ask the core for anything, and a sandbox keeps each plugin to itself, the way an operating system keeps processes apart.
Where it stands. The plugin host is in version 0.2.0: BareProxy loads and runs Proxy-Wasm plugins, with every rule below. Version 0.3.0 sets up plugins in Rust, the language BareProxy’s own plugins are written in. Version 0.4.0 ships the first two, maintenance and failover pages and CORS, 0.5.0 the third, header and rewrite rules, and 0.6.0 the fourth, redirects from a file, as .wasm files on the releases page. The rest are built easiest first, so each one ships as soon as it can: geo rules next, up to RenderCache last. Each plugin below has its own page, which will be updated as it is built. The roadmap has the full order.
How Plugins Work
- Sandboxed. A plugin can’t open files, sockets or processes. It sees the request it’s handed and asks BareProxy for anything else, and BareProxy only grants what the config allows: an address it may call, a folder it may read, a store of its own on disk.
- Any language. Rust, Go, C++, Zig, AssemblyScript, anything that compiles to WebAssembly. BareProxy’s own plugins are written in Rust, because it costs least: a Rust plugin that does nothing adds about 15 microseconds to a request, against about 25 for one in Go.
- A standard interface. Plugins use Proxy-Wasm, the plugin interface of Envoy and Istio, so authors work with existing SDKs.
- Still one binary. The runtime is wazero, written in pure Go, so BareProxy stays a single static binary on Linux, macOS and Windows.
- Heavy work outside. Where a job doesn’t fit a sandbox, like running a headless browser, the plugin decides and serves, and a separate worker next to BareProxy does the heavy part.
The Plugin Catalog
Twenty-one plugins, in six areas. Each has its place in the build order, from 1 to 21, easiest first, and an estimate of its coding time. The order puts the quickest wins out first; the plugins that need a helper program beside BareProxy (an image encoder, a headless browser) come last.
Bots and AI
| Plugin |
What it does |
Build order, coding time |
| AI crawler control |
Allow, block, slow down or charge each AI bot, checked against its published addresses, with a log of who scrapes what |
#10, a day or two |
| RenderCache |
Fully rendered HTML snapshots for search bots, AI crawlers and link previews, from a headless browser beside BareProxy |
#21, one to two weeks |
| AI crawler payment gate |
402 Payment Required with prices per bot and path, and access once a crawler pays |
#19, four or five days |
| Bot challenges |
A proof-of-work check for clients that look like scrapers, with no outside service |
#11, a day or two |
| Link previews |
Open Graph tags for preview fetchers on pages that don’t have them |
#9, about a day |
Security and access
| Plugin |
What it does |
Build order, coding time |
| Rate limiting and basic WAF |
Limits per address, path or site, and simple bad-request rules without regular expressions |
#8, about a day |
| Auth gate |
A password, OAuth, SSO or API-key login in front of any app |
#17, three or four days |
| Header and rewrite rules |
Security headers, header changes, redirects by header and URL rewrites |
#3, built, in 0.5.0 |
| Geo rules |
Allow, block or route by country, from a local database |
#5, about a day |
| Request signing |
Signed requests to backends, and signed URLs that expire |
#6, about a day |
| CORS |
Cross-origin rules and preflight answers for APIs |
#2, built, in 0.4.0 |
Speed
| Plugin |
What it does |
Build order, coding time |
| Response cache |
Micro-caching for dynamic sites, with purge by path prefix and stale copies during outages |
#18, three or four days |
| Image optimizer |
Resizing and WebP and AVIF conversion on the fly, kept on disk |
#20, about a week |
Content and SEO
| Plugin |
What it does |
Build order, coding time |
| Markdown serving |
Markdown files served as HTML pages, with no build step |
#12, about two days |
| Redirects from a file |
Thousands of old URLs redirected from one plain file, with a count of each one’s use |
#4, built, in 0.6.0 |
Privacy and analytics
| Plugin |
What it does |
Build order, coding time |
| Analytics without JavaScript |
Visit stats from the proxy’s own records, bots counted apart, no cookies |
#16, about three days |
| Cookie consent |
A consent banner, and non-essential cookies held back until a visitor agrees |
#13, about two days |
Operations
| Plugin |
What it does |
Build order, coding time |
| Maintenance and failover pages |
A page of the site’s own when the backend is down, and a maintenance switch |
#1, built, in 0.4.0 |
| A/B and canary splits |
A share of traffic sent to a new version, with visitors kept on theirs |
#7, about a day |
| Uptime checks and status pages |
Checks on a timer, 90 days of history, and a public status page |
#14, two or three days |
| OpenTelemetry export |
Request records sent as spans or logs to any OpenTelemetry collector |
#15, two or three days |
Already in the kernel
| Plugin |
What it does |
Build order, coding time |
| Automatic certificates |
Let’s Encrypt certificates on first use, renewed before they expire |
In the core since 0.1.0-alpha |
| Plan and explain |
What a config change will do, and what happened to any request and why; every plugin reports into it |
In the core since 0.1.0-alpha |
Rules Every Plugin Follows
- The core never depends on a plugin. Take every plugin out and the core still builds and passes all of its tests.
- Plugins show up in
explain. For any request, explain and why list what each plugin did and why, from notes the plugin writes. Every request still leaves exactly one record.
- A bad plugin never replaces a good one. A module that won’t load or configure stops the apply, and the running version stays. The history keeps each version’s plugin files, so
rollback brings back the exact module that ran.
- Limits on everything. Each plugin has a memory cap and a time limit per call, and the config says whether a request goes on without it or fails when it breaks.
What Plugins Look Like in a Config
These are the config lines of version 0.3.0. The README in the code repository lists every setting and its default:
plugin crawlers /etc/bareproxy/plugins/ai-crawler-control.wasm
config /etc/bareproxy/plugins/crawlers.json
plugin rendercache /etc/bareproxy/plugins/rendercache.wasm
config /etc/bareproxy/plugins/rendercache.json
store 2GB
body response
allow-http 127.0.0.1:9222
site example.com
use crawlers
use rendercache
route /api/* -> api strip
route /* -> app
Plugins and the License
The whole project is open source under the Apache License 2.0 today. Later, premium add-ons may be offered under different licenses. Which plugins, if any, will be premium hasn’t been decided, so until a plugin is released nothing is promised about its license. The design note and the program are in the code repository.