Skip to content

docs: proposal for MCPBackend CRD - #2144

Merged
nacx merged 3 commits into
envoyproxy:mainfrom
aishwaryaraimule21:mcp-backend-crd
Jun 3, 2026
Merged

docs: proposal for MCPBackend CRD#2144
nacx merged 3 commits into
envoyproxy:mainfrom
aishwaryaraimule21:mcp-backend-crd

Conversation

@aishwaryaraimule21

@aishwaryaraimule21 aishwaryaraimule21 commented May 18, 2026

Copy link
Copy Markdown
Contributor

Description

This proposal introduces a standalone MCPBackend CRD to replace the inline backend configuration currently embedded in MCPRoute.spec.backendRefs[]. The inline model hits Kubernetes object size limits as backends scale, and becomes untenable with the addition of token exchange (RFC-8693) which adds ~25 lines of nested config per backend and conflation of concerns.

The proposal evaluates multiple design approaches — inline security policy, separate security policy with Policy Attachment, backend-refs-policy, and route-refs-policy — analyzing each for reconciliation complexity, use case coverage, backward compatibility, and consistency with the LLM-side AIServiceBackend + BackendSecurityPolicy pattern.

The recommended approach is MCPBackend CRD + extending the existing BackendSecurityPolicy with Policy Attachment (targetRefs), combined with explicit Name/Group/Kind fields on MCPRouteBackendRef for backward compatibility. The existing securityPolicy field is reused with mode-dependent semantics (full definition in legacy mode, per-route scope override in MCPBackend mode).

Related Issues/PRs (if applicable)

Special notes for reviewers (if applicable)

This is a design proposal document only — no implementation code is included.
Key decision points for review:

  1. Whether to define security policy inline in MCPBackend CRD or as a
    separate CRD
    — Approach 1 (inline) is simpler but couples backend and
    security lifecycles. Approach 2 (separate) decouples them at the cost of
    additional reconciliation hops (Section 4).

  2. How to associate MCPBackend with BackendSecurityPolicy — Policy
    Attachment (BSP targets MCPBackend via targetRefs), backend-refs-policy
    (MCPBackend points to BSP), or route-refs-policy (MCPRoute points to BSP
    per backend). Each has different reconciliation and reuse tradeoffs
    (Section 4.2).

  3. Whether to reuse the existing BackendSecurityPolicy CRD or create a new
    MCPBackendSecurityPolicy CRD
    — Extending the existing CRD unifies the
    model but grows the discriminated union; a new CRD avoids bloat but adds
    CRD proliferation (Section 5).

  4. Backward compatibility of MCPRouteBackendRef — Keep the inline
    BackendObjectReference embedding (minimal Go change, dangling fields) or
    switch to explicit Name/Group/Kind fields following the
    AIGatewayRouteRuleBackendRef pattern (cleaner but requires controller
    updates). Both preserve the JSON wire format (Section 6).

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
@aishwaryaraimule21
aishwaryaraimule21 requested a review from a team as a code owner May 18, 2026 14:41
@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label May 18, 2026
Comment on lines +955 to +959

4. **Field indexes**:
- `MCPRoute → MCPBackend names` (for reverse lookup on MCPBackend change)
- `BackendSecurityPolicy → targeted MCPBackend names` (for BSP → MCPBackend → MCPRoute chain)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we would also need a field index for MCPBackend ---> BSP. Because there's no kind discrimination in the index. If an AIServiceBackend and an MCPBackend happen to have the same name in the same namespace, the index would return BSPs targeting both kinds.

ref :

k8sClientIndexAIServiceBackendToTargetingBackendSecurityPolicy = "AIServiceBackendToTargetingBackendSecurityPolicy"

@nacx nacx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed and thought-through proposal. Thanks for showcasing different options!
It LGTM and I agree with the proposed recommendations.

@nacx

nacx commented Jun 2, 2026

Copy link
Copy Markdown
Member

Mind addressing the formatting issues so we can merge this? (You can run make precommit locally).

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Jun 3, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.30%. Comparing base (3509761) to head (497a664).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2144      +/-   ##
==========================================
- Coverage   84.33%   84.30%   -0.03%     
==========================================
  Files         134      134              
  Lines       19352    19313      -39     
==========================================
- Hits        16320    16282      -38     
+ Misses       2033     2032       -1     
  Partials      999      999              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nacx
nacx merged commit 4c1554a into envoyproxy:main Jun 3, 2026
34 checks passed
aabchoo added a commit that referenced this pull request Jun 6, 2026
**Description**
New Features
                  
Multi-Tenant Hostname Routing
- AIGatewayRoute gains a hostnames field enabling hostname-based model
scoping — serve different model catalogs per tenant from a single
Gateway
- /v1/models automatically scopes its response to models matching the
request's Host header
- Wildcard hostnames (*.ai.example.com) supported via Gateway API
hostname matching rules
Provider Translation
- Anthropic → AWS Bedrock Converse — new translator path lets
Anthropic-native clients reach Bedrock without switching protocols
(text, images, tool use, thinking, streaming)
- Anthropic → OpenAI reasoning & image support — thinking/reasoning
blocks and image content no longer silently dropped during translation
- Claude Opus 4.7 reasoning — display parameter (summarized/omitted),
xhigh effort tier, and claude-mythos-preview model recognition
- Anthropic prefix support — VersionedAPISchema.prefix now works for
Anthropic backends (e.g., /{prefix}/messages)
- anthropic-beta header forwarding — mapped into anthropic_beta body
field for AWSAnthropic backends
OpenAI API Compatibility
- Audio transcription & translation — full data-plane support for
/v1/audio/transcriptions and /v1/audio/translations (Whisper endpoints,
multipart/form-data)
- Azure OpenAI Responses API — /v1/responses routes to Azure's
/openai/responses?api-version=... path
- audio_url and video_url content types — multimodal audio/video inputs
for compatible backends (vLLM, phi-4-mm, Qwen 3.5)
Quota-Aware Routing
- Backend rate limit filter injection for QuotaPolicy — first runtime
enforcement: controller injects a backend rate limit filter when a
QuotaPolicy is attached to an AIServiceBackend
MCP Gateway
- Authorization-filtered tools/list — omits tools the caller isn't
authorized to invoke, preventing tool discovery leaks
Observability
- Smarter log redaction — developer-authored metadata (tool
descriptions, function names, JSON schemas) visible in debug logs; user
content and AI-generated text remain redacted
API Changes
- AIGatewayRoute.spec.hostnames — new optional field for hostname-based
request filtering
- AIGatewayRoute.spec.rules capped at 15 (down from 128) to match
Gateway API HTTPRoute limits
- VersionedAPISchema.prefix extended to Anthropic backends
- QuotaPolicy now has runtime enforcement (backend rate limit filter
injection)
Bug Fixes
- SSE parser handles data:{json} (no space after colon)
- Responses API streaming: buffer incomplete SSE events across response
body chunks
- Responses API: capture token usage from response.incomplete and
response.failed events
- Nil-pointer guard in AWS Bedrock response translator (HTTP 200 with no
output field)
- Comprehensive Gemini finish-reason mapping (previously everything fell
through to content_filter)
- GCP Vertex AI streaming: emit empty delta object instead of omitting
it
- Responses API: handle typeless assistant output messages (e.g., from
OpenCode)
Docs
- Proposal: MCPBackend CRD (#2144)
- Proposal: OAuth 2.0 Token Exchange as Upstream Auth for MCP Backends
(#2052)
CI
- contents:write permission declared on Release workflow's release job
(#2139)

---------

Signed-off-by: achoo30 <achoo30@bloomberg.net>
Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
saixso pushed a commit to saixso/ai-gateway that referenced this pull request Jun 21, 2026
**Description**

This proposal introduces a standalone MCPBackend CRD to replace the
inline backend configuration currently embedded in
MCPRoute.spec.backendRefs[]. The inline model hits Kubernetes object
size limits as backends scale, and becomes untenable with the addition
of token exchange (RFC-8693) which adds ~25 lines of nested config per
backend and conflation of concerns.

**The proposal evaluates multiple design approaches — inline security
policy, separate security policy with Policy Attachment,
backend-refs-policy, and route-refs-policy — analyzing each for
reconciliation complexity, use case coverage, backward compatibility,
and consistency with the LLM-side AIServiceBackend +
BackendSecurityPolicy pattern.**

The recommended approach is MCPBackend CRD + extending the existing
BackendSecurityPolicy with Policy Attachment (targetRefs), combined with
explicit Name/Group/Kind fields on MCPRouteBackendRef for backward
compatibility. The existing `securityPolicy` field is reused with
mode-dependent semantics (full definition in legacy mode, per-route
scope override in MCPBackend mode).

**Related Issues/PRs (if applicable)**
-

**Special notes for reviewers (if applicable)**

This is a design proposal document only — no implementation code is
included.
Key decision points for review:

1. **Whether to define security policy inline in MCPBackend CRD or as a
separate CRD** — Approach 1 (inline) is simpler but couples backend and
security lifecycles. Approach 2 (separate) decouples them at the cost of
   additional reconciliation hops (Section 4).

2. **How to associate MCPBackend with BackendSecurityPolicy** — Policy
Attachment (BSP targets MCPBackend via targetRefs), backend-refs-policy
(MCPBackend points to BSP), or route-refs-policy (MCPRoute points to BSP
   per backend). Each has different reconciliation and reuse tradeoffs
   (Section 4.2).

3. **Whether to reuse the existing BackendSecurityPolicy CRD or create a
new
MCPBackendSecurityPolicy CRD** — Extending the existing CRD unifies the
model but grows the discriminated union; a new CRD avoids bloat but adds
   CRD proliferation (Section 5).

4. **Backward compatibility of MCPRouteBackendRef** — Keep the inline
`BackendObjectReference` embedding (minimal Go change, dangling fields)
or
   switch to explicit `Name/Group/Kind` fields following the
`AIGatewayRouteRuleBackendRef` pattern (cleaner but requires controller
   updates). Both preserve the JSON wire format (Section 6).

---------

Signed-off-by: Aishwarya <aishwarya.raimule@nutanix.com>
Co-authored-by: Ignasi Barrera <ignasi@tetrate.io>
Signed-off-by: saixso <sai.soundararajan@spoton.com>
saixso pushed a commit to saixso/ai-gateway that referenced this pull request Jun 21, 2026
**Description**
New Features

Multi-Tenant Hostname Routing
- AIGatewayRoute gains a hostnames field enabling hostname-based model
scoping — serve different model catalogs per tenant from a single
Gateway
- /v1/models automatically scopes its response to models matching the
request's Host header
- Wildcard hostnames (*.ai.example.com) supported via Gateway API
hostname matching rules
Provider Translation
- Anthropic → AWS Bedrock Converse — new translator path lets
Anthropic-native clients reach Bedrock without switching protocols
(text, images, tool use, thinking, streaming)
- Anthropic → OpenAI reasoning & image support — thinking/reasoning
blocks and image content no longer silently dropped during translation
- Claude Opus 4.7 reasoning — display parameter (summarized/omitted),
xhigh effort tier, and claude-mythos-preview model recognition
- Anthropic prefix support — VersionedAPISchema.prefix now works for
Anthropic backends (e.g., /{prefix}/messages)
- anthropic-beta header forwarding — mapped into anthropic_beta body
field for AWSAnthropic backends
OpenAI API Compatibility
- Audio transcription & translation — full data-plane support for
/v1/audio/transcriptions and /v1/audio/translations (Whisper endpoints,
multipart/form-data)
- Azure OpenAI Responses API — /v1/responses routes to Azure's
/openai/responses?api-version=... path
- audio_url and video_url content types — multimodal audio/video inputs
for compatible backends (vLLM, phi-4-mm, Qwen 3.5)
Quota-Aware Routing
- Backend rate limit filter injection for QuotaPolicy — first runtime
enforcement: controller injects a backend rate limit filter when a
QuotaPolicy is attached to an AIServiceBackend
MCP Gateway
- Authorization-filtered tools/list — omits tools the caller isn't
authorized to invoke, preventing tool discovery leaks
Observability
- Smarter log redaction — developer-authored metadata (tool
descriptions, function names, JSON schemas) visible in debug logs; user
content and AI-generated text remain redacted
API Changes
- AIGatewayRoute.spec.hostnames — new optional field for hostname-based
request filtering
- AIGatewayRoute.spec.rules capped at 15 (down from 128) to match
Gateway API HTTPRoute limits
- VersionedAPISchema.prefix extended to Anthropic backends
- QuotaPolicy now has runtime enforcement (backend rate limit filter
injection)
Bug Fixes
- SSE parser handles data:{json} (no space after colon)
- Responses API streaming: buffer incomplete SSE events across response
body chunks
- Responses API: capture token usage from response.incomplete and
response.failed events
- Nil-pointer guard in AWS Bedrock response translator (HTTP 200 with no
output field)
- Comprehensive Gemini finish-reason mapping (previously everything fell
through to content_filter)
- GCP Vertex AI streaming: emit empty delta object instead of omitting
it
- Responses API: handle typeless assistant output messages (e.g., from
OpenCode)
Docs
- Proposal: MCPBackend CRD (envoyproxy#2144)
- Proposal: OAuth 2.0 Token Exchange as Upstream Auth for MCP Backends
(envoyproxy#2052)
CI
- contents:write permission declared on Release workflow's release job
(envoyproxy#2139)

---------

Signed-off-by: achoo30 <achoo30@bloomberg.net>
Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: saixso <sai.soundararajan@spoton.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants