Summary
Implement a transparent inbound listener for the Go proxy (proxy-sidecar mode): capture iptables-REDIRECTed inbound connections, recover the app's original destination port via SO_ORIGINAL_DST, run the inbound auth pipeline (JWT validation) inline, and forward to the app on its real port — no Envoy, no ext_proc, no Service rewiring.
This is the inbound half of the original "transparent-proxy mode" idea. Since this issue was filed, the outbound transparent path has effectively landed (see Status below); the remaining gap is inbound.
Status of the original proposal (what already landed)
The Go-native transparent-interception core was built and shipped — but as the outbound enforce-redirect egress guard inside proxy-sidecar mode, not as a standalone Envoy-replacement mode:
SO_ORIGINAL_DST getsockopt recovery, IPv4 + IPv6 — authlib/listener/transparentproxy/origdst_linux.go
- TLS ClientHello passthrough + SNI/Host recovery —
authlib/listener/forwardproxy/sniff.go, transparent.go
- Shares the forward proxy's CONNECT auth pipeline via
HandleTransparentConn
- Landed in
bb15d20 (+ follow-ups); bound to :8082; outbound only
The broader "drop the ~87 MB Envoy binary to shrink the image" motivation is also already met: proxy-sidecar is now the default mode and bundles no Envoy, and the authbridge-lite image variant shrinks it further.
What's still missing: there is no transparent inbound listener. Valid modes are envoy-sidecar, waypoint, proxy-sidecar (config.go:453) — there is no standalone transparent-proxy mode, and proxy-sidecar's inbound is a reverse proxy, not transparent (see below).
Current inbound mechanism and its limits
proxy-sidecar inbound today is a reverse proxy to a single fixed backend — httputil.NewSingleHostReverseProxy against reverse_proxy_backend (authlib/listener/reverseproxy/server.go:95, config.go:364). Traffic hits :8080, the inbound pipeline validates the JWT, and it forwards to one known app URL.
That is fine for a single-port app behind an operator-managed Service pointed at :8080, but it has three gaps:
- Bypassable. Validation is only enforced for traffic that goes through
:8080. Anything that reaches the app's real port directly — another pod dialing podIP:appPort, a co-located sidecar, a mis-scoped NetworkPolicy — skips validation entirely. This is the inbound twin of the problem the outbound enforce-redirect guard already solves.
- Single port only.
reverse_proxy_backend is one URL; it can't front an app that listens on multiple ports (e.g. HTTP API + gRPC + admin/metrics).
- Requires Service rewiring. The operator must point
targetPort at :8080; it is not a transparent drop-in for an Envoy-shaped deployment.
What the transparent inbound listener would do
- Listen on an inbound transparent port that
proxy-init PREROUTING-REDIRECTs to (Envoy uses :15124; pick the proxy-sidecar equivalent).
- Recover the original destination (the app's port) via
SO_ORIGINAL_DST — reuse the existing transparentproxy package.
- Run the inbound pipeline (JWT validation) inline — no ext_proc gRPC indirection.
- Forward to the app on its recovered original port over loopback, replacing the single-fixed-backend assumption.
- TLS: terminate or passthrough per the top-level
mtls config, consistent with the reverse proxy's tlssniff behavior.
- Reuse proxy-init's existing iptables rules and UID exclusion.
Why transparent inbound (in priority order)
- Enforcement / no-bypass — a hard inbound boundary so JWT validation cannot be sidestepped by hitting the app port directly. Directly symmetric to the outbound
enforce-redirect guard.
- Multi-port apps —
SO_ORIGINAL_DST recovers whichever port each connection targeted; no per-port listener config.
- Envoy drop-in parity — makes the Go proxy transparent on both directions, so migrating a deployment off
envoy-sidecar needs no Service/manifest surgery.
Trade-offs / notes
- Needs the privileged
proxy-init container (NET_ADMIN) for inbound and is Linux-only — same constraints as enforce-redirect and envoy-sidecar.
- For a standard single-port agent behind an operator-managed Service where NetworkPolicy or mesh mTLS already limits direct access to the app port, the existing reverse proxy remains simpler. This should be opt-in, not a forced replacement.
envoy-sidecar, waypoint, and the existing reverse-proxy inbound path remain unchanged.
Related
Summary
Implement a transparent inbound listener for the Go proxy (
proxy-sidecarmode): capture iptables-REDIRECTed inbound connections, recover the app's original destination port viaSO_ORIGINAL_DST, run the inbound auth pipeline (JWT validation) inline, and forward to the app on its real port — no Envoy, no ext_proc, no Service rewiring.This is the inbound half of the original "transparent-proxy mode" idea. Since this issue was filed, the outbound transparent path has effectively landed (see Status below); the remaining gap is inbound.
Status of the original proposal (what already landed)
The Go-native transparent-interception core was built and shipped — but as the outbound
enforce-redirectegress guard insideproxy-sidecarmode, not as a standalone Envoy-replacement mode:SO_ORIGINAL_DSTgetsockopt recovery, IPv4 + IPv6 —authlib/listener/transparentproxy/origdst_linux.goauthlib/listener/forwardproxy/sniff.go,transparent.goHandleTransparentConnbb15d20(+ follow-ups); bound to:8082; outbound onlyThe broader "drop the ~87 MB Envoy binary to shrink the image" motivation is also already met:
proxy-sidecaris now the default mode and bundles no Envoy, and theauthbridge-liteimage variant shrinks it further.What's still missing: there is no transparent inbound listener. Valid modes are
envoy-sidecar,waypoint,proxy-sidecar(config.go:453) — there is no standalonetransparent-proxymode, and proxy-sidecar's inbound is a reverse proxy, not transparent (see below).Current inbound mechanism and its limits
proxy-sidecar inbound today is a reverse proxy to a single fixed backend —
httputil.NewSingleHostReverseProxyagainstreverse_proxy_backend(authlib/listener/reverseproxy/server.go:95,config.go:364). Traffic hits:8080, the inbound pipeline validates the JWT, and it forwards to one known app URL.That is fine for a single-port app behind an operator-managed Service pointed at
:8080, but it has three gaps::8080. Anything that reaches the app's real port directly — another pod dialingpodIP:appPort, a co-located sidecar, a mis-scoped NetworkPolicy — skips validation entirely. This is the inbound twin of the problem the outboundenforce-redirectguard already solves.reverse_proxy_backendis one URL; it can't front an app that listens on multiple ports (e.g. HTTP API + gRPC + admin/metrics).targetPortat:8080; it is not a transparent drop-in for an Envoy-shaped deployment.What the transparent inbound listener would do
proxy-initPREROUTING-REDIRECTs to (Envoy uses:15124; pick the proxy-sidecar equivalent).SO_ORIGINAL_DST— reuse the existingtransparentproxypackage.mtlsconfig, consistent with the reverse proxy'stlssniffbehavior.Why transparent inbound (in priority order)
enforce-redirectguard.SO_ORIGINAL_DSTrecovers whichever port each connection targeted; no per-port listener config.envoy-sidecarneeds no Service/manifest surgery.Trade-offs / notes
proxy-initcontainer (NET_ADMIN) for inbound and is Linux-only — same constraints asenforce-redirectandenvoy-sidecar.envoy-sidecar,waypoint, and the existing reverse-proxy inbound path remain unchanged.Related
bb15d20 feat: Add transparent listener + enforce-redirect for proxy-sidecar egress