Skip to content

Support Envoy sidecar compatibility for AuthBridge #61

@huang195

Description

@huang195

Summary

kagenti-extensions uses Envoy as a sidecar proxy for AI agent workloads in Kubernetes. Praxis offers significant advantages as a drop-in replacement:

Metric Praxis Envoy Ratio
RSS at idle 7.8 MB 56.6 MB 7.2x less
Binary size 12.6 MB 84 MB 6.7x smaller
Container image 20 MB 84.4 MB 4.2x smaller
Startup ~10–20 ms ~70 ms 3–7x faster

At 100 sidecars, this saves ~4.88 GB of RSS and ~6.4 GB of image storage.

Gaps

Four features are needed for praxis to serve as a drop-in replacement across kagenti-extensions deployment modes.

1. ext_proc — External Processing (gRPC bidirectional stream)

Needed for: envoy-sidecar mode

Envoy's ext_proc filter sends request/response headers and bodies to an external gRPC service (envoy.service.ext_proc.v3.ExternalProcessor) for inspection and mutation. kagenti-extensions uses this to call the authbridge binary for:

  • Inbound: JWT validation
  • Outbound: OAuth2 token exchange and Authorization header injection

Processing mode used:

processing_mode:
  request_header_mode: SEND
  response_header_mode: SKIP
  request_body_mode: NONE
  response_body_mode: NONE

This requires praxis to act as a gRPC client, speaking the Envoy ext_proc protocol so the existing authbridge binary works unmodified.

2. ext_authz — External Authorization (gRPC unary call)

Needed for: waypoint mode

Envoy's ext_authz filter makes a unary Check() gRPC call (envoy.service.auth.v3.Authorization) to an external service for allow/deny decisions. In waypoint mode, an Istio waypoint proxy calls authbridge via ext_authz.

Simpler than ext_proc — single request/response, no streaming.

3. Original Destination (SO_ORIGINAL_DST)

Needed for: envoy-sidecar mode

When iptables redirects pod traffic to the proxy, the real destination is lost at the socket level. Envoy recovers it via envoy.filters.listener.original_dst, which calls getsockopt(SO_ORIGINAL_DST) on accepted connections.

Praxis currently requires static endpoint lists. It would need to:

  1. Read the original destination from the kernel socket metadata
  2. Use that address as the upstream target dynamically (without a predefined cluster)

This is Linux-specific (SO_ORIGINAL_DST / IP6T_SO_ORIGINAL_DST).

4. TLS Inspector + Protocol-Based Filter Chain Routing

Needed for: envoy-sidecar mode

The outbound listener handles both plaintext HTTP and HTTPS on a single port (15123). Envoy uses tls_inspector to peek at the first bytes of each connection and routes to different filter chains:

  • Plaintext (raw_buffer): HTTP filter chain → ext_proc → router
  • TLS: TCP filter chain → raw passthrough (no decryption)

Praxis currently binds each listener to a fixed protocol (http or tcp). It would need:

  1. A connection-level protocol detection mechanism (SNI/TLS inspection)
  2. The ability to route to different filter chains based on detected protocol within a single listener

Scope

Gap Deployment Mode Complexity
ext_proc envoy-sidecar High
ext_authz waypoint Medium
Original Destination envoy-sidecar Medium
TLS Inspector + routing envoy-sidecar Medium

The proxy-sidecar mode does not use Envoy (pure Go HTTP proxy via HTTP_PROXY), so no praxis changes are needed for that mode.

References

  • kagenti-extensions: https://github.com/kagenti/kagenti-extensions
  • Envoy ext_proc proto: envoy.service.ext_proc.v3.ExternalProcessor
  • Envoy ext_authz proto: envoy.service.auth.v3.Authorization
  • AuthBridge unified binary: authbridge/cmd/authbridge/main.go

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions