Skip to content

feat(extension-server): Hook to modify EDS endpoints before sending to Envoy #8150

@codefromthecrypt

Description

@codefromthecrypt

Description

Extension server hooks exist for Clusters, Routes, VirtualHosts, and Listeners, but not for EDS (ClusterLoadAssignment). For EDS-type clusters (K8s Services, Backend with static IPs), LoadAssignment is nil at translation time and endpoints arrive via the EDS stream, bypassing all hooks. Extension servers cannot stamp per-endpoint metadata such as per_route_rule_backend_name that ai-gateway's ext_proc needs to resolve backends for OpenTelemetry spans and metrics.

Use case

ai-gateway stamps per_route_rule_backend_name on each endpoint so the upstream ext_proc can resolve the backend and populate OpenTelemetry spans and metrics with gen_ai.system (provider name), model, and token usage per backend.

Without endpoint metadata, the ext_proc receives no backend identity, so OTel data is missing or wrong.

    ext_proc resolves backend from endpoint metadata
         |
         v
    SetBackend(backend)
         |
         v
    metrics.SetBackend(backend)
         |
         v
    OTel span/metric attributes:
      gen_ai.system = "openai"    <-- derived from backend schema
      gen_ai.request.model = ...
      gen_ai.response.model = ...
      gen_ai.usage.* = ...

    When endpoint metadata is missing (EDS clusters):
      gen_ai.system = "unknown"   <-- backend unresolved

A cluster-level fallback exists (envoyproxy/ai-gateway#1822), but it only stamps BackendRefs[0], so multi-backend route rules still can't distinguish backends (see envoyproxy/ai-gateway#902, envoyproxy/ai-gateway#950).

Proposal

Add a new extension server hook (e.g., PostEndpointModify) that is called when ClusterLoadAssignment resources are built or updated, allowing extension servers to modify LocalityLbEndpoints metadata before they are sent to Envoy via EDS.

EG xDS Translation
     |
     v
+--------------------+        +---------------------+
| PostClusterModify  |        | EDS Stream          |
| PostTranslateModify|        | (ClusterLoadAssign) |
+--------------------+        +---------------------+
     |                               |
     v                               v
Cluster sent to Envoy         +---------------------+
                               | PostEndpointModify  |
                               +---------------------+
                                     |
                                     v
                               Endpoints sent to Envoy
                               (extension server CAN
                                stamp per-endpoint
                                metadata here)

Open Issues:

Related PRs:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions