Skip to content

Feature/multi provider routing policy changes#2244

Open
Aakashwije wants to merge 8 commits into
wso2:mainfrom
Aakashwije:feature/Multi_Provider_Routing_Policy_changes
Open

Feature/multi provider routing policy changes#2244
Aakashwije wants to merge 8 commits into
wso2:mainfrom
Aakashwije:feature/Multi_Provider_Routing_Policy_changes

Conversation

@Aakashwije

Copy link
Copy Markdown

Purpose

LLM Gateway users are increasingly building AI applications that need to target
multiple LLM providers (OpenAI, Anthropic, Azure OpenAI, Mistral, Gemini) through
a single, OpenAI-compatible endpoint. Previously, each LLMProxy was hard-wired
to a single upstream provider, which forced users to deploy separate proxies or
handle provider selection in their application code.

This PR introduces multi-provider routing for LLM proxies together with a set
of built-in OpenAI-format translation policies that convert outgoing requests
and incoming responses between the OpenAI Chat Completions format and each
provider's native API.

Goals

  • Allow a single LLMProxy to declare multiple LLM backend providers as named
    selectable upstreams (additionalProviders).
  • Ship a header-driven routing policy (openai-header-router) that selects the
    target provider per request and publishes the selection into shared metadata.
  • Ship per-provider translation policies that transparently convert between the
    OpenAI Chat Completions schema and each provider's native wire format:
    • openai-to-anthropic → Anthropic Messages API
    • openai-to-azure-openai → Azure OpenAI REST API
    • openai-to-mistral → Mistral AI API
    • openai-to-gemini → Google Gemini generateContent API
  • Ensure per-provider API key credentials are injected only for the selected
    provider via conditional execution (ExecutionCondition).

Approach

additionalProviders field on LLMProxy

A new optional additionalProviders list is added to LLMProxyConfigData across
all layers (Kubernetes CRD, management API, platform API). Each entry references
a deployed LlmProvider by id, with an optional as alias used by downstream
policies to address the upstream cluster, and an optional auth block for
provider-level API key injection.

Transformer changes (llm_transformer.go)

The gateway controller transformer now:

  1. Resolves each additional provider's loopback URL and registers it as a named
    UpstreamDefinition.
  2. Generates a conditional upstream-auth policy per provider (using
    ExecutionCondition) so that each provider's Authorization/X-Api-Key
    header is only injected when request.Metadata['selected_provider'] matches
    that provider's name. The primary provider's auth policy fires when the
    metadata key is absent (default) or matches the primary id.

Validator changes (llm_validator.go)

Validates additionalProviders for:

  • Non-empty, valid id values
  • Unique upstream names (no collision between primary provider id, as aliases,
    or id values)
  • Auth fields (type, header, value) when auth is set

Routing and translation policy architecture

Client (OpenAI format)


openai-header-router ← reads X-Provider header, sets selected_provider

├── openai-to-anthropic ← runs only when selected_provider == "anthropic-"
├── openai-to-azure-openai ← runs only when selected_provider == "azure-"
├── openai-to-mistral ← runs only when selected_provider == "mistral-"
└── openai-to-gemini ← runs only when selected_provider == "gemini-"

Each translator policy operates in two modes:

  • Routed (multi-provider proxy): the provider parameter is set; the policy
    evaluates the selected_provider metadata and is a no-op for non-matching
    requests.
  • Unconditional (single-provider proxy): provider is omitted; the translator
    runs on every request.

Translation policies handle:

  • System/developer message extraction
  • Message role/content block conversion (including tool calls and tool results)
  • Sampling parameter mapping (temperature, top_p, max_tokens, etc.)
  • Request path rewriting (e.g. /v1/messages for Anthropic,
    /{apiVersion}/models/{model}:generateContent for Gemini)
  • Response body rewriting into OpenAI ChatCompletion shape
  • Error envelope normalisation

Example multi-provider proxy manifest

# gateway/examples/openai-multi-provider-proxy.yaml
spec:
  provider:
    id: openai-provider
    auth:
      type: api-key
      header: Authorization
      value: Bearer $OPENAI_API_KEY
  additionalProviders:
    - id: anthropic-provider
      auth:
        type: api-key
        header: X-Api-Key
        value: $ANTHROPIC_API_KEY
    - id: gemini-provider
      as: gemini
      auth:
        type: api-key
        header: X-Goog-Api-Key
        value: $GEMINI_API_KEY
  policies:
    - name: openai-header-router
      version: v1.0.0
      params:
        headerName: x-provider
        defaultProvider: openai-provider
        mappings:
          - headerValue: anthropic
            provider: anthropic-provider
          - headerValue: gemini
            provider: gemini
    - name: openai-to-anthropic
      version: v1.0.0
      params:
        provider: anthropic-provider
        model: claude-sonnet-4-20250514
        upstreamName: anthropic-provider
    - name: openai-to-gemini
      version: v1.0.0
      params:
        provider: gemini
        model: gemini-2.5-pro
        upstreamName: gemini

User stories

  • As an API consumer, I can send OpenAI-format requests to a single gateway endpoint and have the gateway route to Anthropic, Azure OpenAI, Mistral, or Gemini by setting an X-Provider header, without any client-side changes
  • As a developer building failover or A/B testing flows, I can attach multiple providers to one proxy and use custom header-routing logic to split traffic across backends.
  • As an API platform administrator, I can configure a single LLMProxy with multiple providers and assign per-provider API keys that are injected by the gateway rather than exposed to clients.

Documentation

  • N/A — inline policy YAML descriptions and example manifests in
    gateway/examples/ serve as the primary reference for this feature.
  • Full documentation update is tracked separately.

Automation tests

  • Unit tests

    • gateway/gateway-controller/pkg/utils/llm_transformer_test.go - TestLLMProviderTransformer_TransformProxy_AdditionalProviderAuthIsConditional verifies that:
      - Each additional provider is registered as a named UpstreamDefinition.
      - Two upstream-auth policies are emitted for the two providers.
      - Each policy's ExecutionCondition references only its own provider name.
      - API key values are not crossed between providers.
  • gateway/gateway-controller/pkg/config/llm_validator_test.go (existing suite) — additional additionalProviders validation paths covered.

  • Integration tests

    • The existing LLM proxy integration test suite exercises the core proxy transformer path. A dedicated multi-provider integration test is planned as a follow-up.

Security checks

Samples

gateway/examples/ contains ready-to-deploy YAML manifests for each provider combination:

File Description
openai-multi-provider-proxy.yaml Full multi-provider proxy with header routing
anthropic-openai-proxy.yaml Single-provider OpenAI → Anthropic proxy
azure-openai-proxy.yaml Single-provider OpenAI → Azure OpenAI proxy
mistral-openai-proxy.yaml Single-provider OpenAI → Mistral proxy
anthropic-provider.yaml Example LlmProvider for Anthropic
azure-openai-provider.yaml Example LlmProvider for Azure OpenAI
gemini-provider.yaml Example LlmProvider for Google Gemini
mistral-provider.yaml Example LlmProvider for Mistral
openai-provider.yaml Example LlmProvider for OpenAI
llm-provider.yaml / llm-proxy.yaml Minimal baseline examples

Note: mistral-proxy.yaml at the repository root provides a complete working Mistral proxy reference configuration.

Related PRs

  • N/A

Test Environment

Component Version / Details
Go 1.22+
Kubernetes 1.29+ (operator CRD)
OS macOS 14 (Darwin 24.6.0), Ubuntu 22.04
Browser N/A (no UI changes)
Database SQLite (unit tests), PostgreSQL (integration test suite)

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Added multi-provider routing for LLM proxies, allowing a single proxy to select between multiple upstream LLM providers.

Key updates include:

  • New additionalProviders support across CRDs, management API, platform API, and deployment models.
  • Validation and deep-copy support for additional provider definitions.
  • Proxy transformation and controller logic updated to register multiple upstreams and apply provider-specific auth handling.
  • A new header-based router policy was added to select the active provider for each request.
  • New translation policies were added for Anthropic, Azure OpenAI, Mistral, and Gemini.
  • Example manifests were added/updated to demonstrate single-provider and multi-provider proxy setups for the supported providers.
  • Tests were expanded to cover additional provider routing and auth propagation.

Walkthrough

This PR adds additionalProviders support for LlmProxy across the API, CRD, controller, and deployment layers. It also adds multi-provider routing policies, including a header-based router and OpenAI-to-provider translators for Anthropic, Azure OpenAI, Gemini, and Mistral. Example provider and proxy manifests were added or updated to exercise the new routing and auth flows.

Suggested reviewers

  • RakhithaRR
  • Tharsanan1
  • Arshardh
  • Krishanx92
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly refers to the main change: multi-provider routing and policy updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feature/Multi_Provider_Routing_Policy_changes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CLAassistant

CLAassistant commented Jun 22, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 13

🧹 Nitpick comments (3)
gateway/examples/llm-proxy.yaml (1)

29-32: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use safer credential placeholders in proxy examples.

Line 32 hardcodes a provider loopback key. Prefer an explicit placeholder (or a secret-backed reference) so this manifest is less likely to be reused with fixed credentials.

Suggested update
-      value: provider_loopback_key_1234567890abcdef1234567890
+      value: REPLACE_WITH_PROVIDER_LOOPBACK_KEY
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/examples/llm-proxy.yaml` around lines 29 - 32, The auth section in
the llm-proxy.yaml example file contains a hardcoded provider loopback key in
the value field that should not be used as-is in production. Replace this
hardcoded credential value with an explicit placeholder string (such as
${PROVIDER_LOOPBACK_KEY} or similar reference syntax) that makes it obvious this
is an example requiring substitution with actual credentials, preventing
accidental reuse of the example manifest with fixed credentials.
gateway/examples/openai-multi-provider-proxy.yaml (1)

29-48: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use secret-backed or placeholder auth values in the multi-provider example.

The primary and additional provider auth blocks embed fixed loopback keys. Prefer secret references or explicit placeholders to promote safer defaults when users copy this manifest.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/examples/openai-multi-provider-proxy.yaml` around lines 29 - 48,
Replace the hardcoded loopback key values in the auth blocks for the primary
provider and all additionalProviders (anthropic-provider, azure-openai-provider,
and mistral-provider) with either secret references (e.g.,
valueFrom.secretKeyRef or environment variable references) or explicit
placeholder values (e.g., "${PROVIDER_API_KEY}" or "YOUR_API_KEY_HERE") that
clearly indicate users must substitute their own credentials before deploying
the manifest.
gateway/gateway-controller/pkg/utils/llm_transformer_test.go (1)

307-313: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Make auth-policy assertions order-independent.

The test currently ties provider checks to fixed slice indexes. Please match by ExecutionCondition (or provider key) before asserting header values so valid reorderings don't create false failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/pkg/utils/llm_transformer_test.go` around lines
307 - 313, The test assertions in the diff are order-dependent, checking fixed
indexes [0] and [1] for specific providers which will fail if the authPolicies
slice is reordered. Instead of relying on index positions, iterate through the
authPolicies slice and match each policy by its ExecutionCondition content
(looking for "openai-provider" and "anthropic-provider"), then assert the
corresponding header value using firstRequestHeaderValue against the matched
policy's Params. This makes the test resilient to any reordering of the
authPolicies slice.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@gateway/examples/anthropic-openai-proxy.yaml`:
- Around line 9-12: The header comment in the Single-provider mode section
contains outdated parameter references. Update the comment to accurately reflect
that the configuration uses provider.id (set at line 30) and the translator
policy parameters are provider/upstreamName, rather than referring to omitting
"id" and metadata["selected_provider"]. This clarifies the actual configuration
pattern being used and removes the ambiguity in the parameter naming.

In `@gateway/examples/azure-openai-provider.yaml`:
- Around line 32-50: The api-key-auth authentication plugin is currently
configured to only protect the /openai/deployments/{deployment}/chat/completions
endpoint, but the accessControl.exceptions section allows four different paths.
To align these, add the three missing paths to the api-key-auth paths array:
/openai/deployments/{deployment}/completions (POST),
/openai/deployments/{deployment}/embeddings (POST), and /openai/models (GET).
This ensures all allowed endpoints enforce the same authentication rule.
- Line 26: The upstream.url field on line 26 is missing a value and only
contains a comment, which causes it to parse as null and makes the YAML
structurally invalid for users. Replace the empty value with a concrete
placeholder string (such as a sample URL or a descriptive placeholder text) so
the configuration file remains valid YAML before users edit it with their actual
endpoint URL.

In `@gateway/examples/azure-openai-proxy.yaml`:
- Around line 27-29: The proxy configuration references the
`azure-openai-provider` but is missing the `provider.auth` configuration
required for upstream authorization. Add `provider.auth` configuration to the
provider section that specifies the appropriate authentication method to satisfy
the `X-API-Key` requirement of the target provider, ensuring the proxy can
properly authenticate requests to the upstream service.

In `@gateway/examples/gemini-provider.yaml`:
- Around line 26-41: The api-key-auth policy in the policies section only
protects the /v1beta/models/{model}:generateContent endpoint, but the
accessControl.exceptions section allows both
/v1beta/models/{model}:generateContent and
/v1beta/models/{model}:streamGenerateContent endpoints. Add a second entry in
the api-key-auth policy paths array to also protect the
/v1beta/models/{model}:streamGenerateContent endpoint with the same
authentication requirement (key: X-API-Key in header), ensuring consistent auth
coverage across all allowed endpoints.

In `@gateway/examples/mistral-provider.yaml`:
- Around line 25-28: In the mistral-provider.yaml file's auth section, the value
for the Authorization header should follow the Bearer token format instead of
the plain placeholder currently shown. Replace the value field (currently set to
$dxxxd) with a Bearer-formatted placeholder that clearly demonstrates proper
authentication format for API key authentication, such as using "Bearer" prefix
with an appropriate token placeholder to make the example valid and immediately
usable.
- Around line 29-46: The api-key-auth policy only covers the
/v1/chat/completions endpoint in the policies section, but the
accessControl.exceptions configuration allows unauthenticated access to
/v1/embeddings and /v1/models as well. To fix this inconsistency, add the
missing /v1/embeddings and /v1/models paths to the api-key-auth policy's paths
list with appropriate methods (POST for /v1/embeddings and GET for /v1/models),
ensuring all endpoints listed in accessControl.exceptions have matching
authentication policy coverage.

In `@gateway/examples/openai-provider.yaml`:
- Around line 30-50: The api-key-auth plugin only protects the /chat/completions
endpoint, but accessControl.exceptions allows access to five endpoints:
/chat/completions, /completions, /embeddings, /models, and /models/{modelId}.
Add all four additional paths (/completions, /embeddings, /models, and
/models/{modelId}) to the api-key-auth plugin's paths section with their
respective HTTP methods (POST for /completions and /embeddings, GET for /models
and /models/{modelId}) to ensure consistent authentication protection across all
allowed endpoints.

In `@mistral-proxy.yaml`:
- Around line 217-233: The translator parameter definitions in the
openai-to-mistral and openai-to-anthropic translator blocks use `id` but should
use `provider` to match the translation policy contract. In both translator
blocks (identified by their name fields), replace the `id` parameter with
`provider` in the params section. Additionally, add an explicit `upstreamName`
parameter to the openai-to-anthropic translator block to prevent falling back to
the default upstream, ensuring correct routing behavior as intended by the
configuration.

In `@platform-api/src/api/generated.go`:
- Around line 1868-1876: The LLMProxyAdditionalProvider struct is missing an
`auth` field that is needed to represent provider-level authentication
configuration in the multi-provider payload. Add an `auth` field to the
LLMProxyAdditionalProvider struct with appropriate JSON and YAML tags (likely
omitempty) to enable end-to-end representation of auth configuration through the
platform API types, maintaining parity with the full provider specification.

In `@platform-api/src/internal/model/llm.go`:
- Around line 221-227: The LLMProxyAdditionalProvider struct definition is
missing an Auth field which prevents per-provider authentication configuration
from being represented and propagated through deployment mapping. Add an Auth
field to the LLMProxyAdditionalProvider struct to capture optional
authentication details, and then wire this field through the corresponding DTO
layer and mapper functions to ensure the auth configuration is properly
serialized, transferred, and applied throughout the system.

In `@platform-api/src/internal/service/llm.go`:
- Around line 633-639: The Create and Update methods in the llm.go service
validate only the primary provider ID (req.Provider.Id) but fail to validate the
provider IDs referenced in AdditionalProviders before mapping them with
mapAdditionalProvidersAPIToModel. Add validation logic before the mapping that
checks each provider ID in req.AdditionalProviders exists in the system, similar
to how the primary provider is validated. This validation should occur in both
the Create and Update methods (referenced around lines 633-639 and 846-852) to
prevent invalid provider references from being persisted to the database.

In `@platform-api/src/resources/openapi.yaml`:
- Around line 10382-10403: The LLMProxyAdditionalProvider schema definition is
missing an auth property that is required to keep the API contract aligned with
other layers in this PR. Add an optional auth property to the
LLMProxyAdditionalProvider object schema in openapi.yaml that allows
configuration of authentication for additional providers. This property should
follow the same pattern and structure used for auth configuration in related
provider schemas to maintain consistency across the API contract.

---

Nitpick comments:
In `@gateway/examples/llm-proxy.yaml`:
- Around line 29-32: The auth section in the llm-proxy.yaml example file
contains a hardcoded provider loopback key in the value field that should not be
used as-is in production. Replace this hardcoded credential value with an
explicit placeholder string (such as ${PROVIDER_LOOPBACK_KEY} or similar
reference syntax) that makes it obvious this is an example requiring
substitution with actual credentials, preventing accidental reuse of the example
manifest with fixed credentials.

In `@gateway/examples/openai-multi-provider-proxy.yaml`:
- Around line 29-48: Replace the hardcoded loopback key values in the auth
blocks for the primary provider and all additionalProviders (anthropic-provider,
azure-openai-provider, and mistral-provider) with either secret references
(e.g., valueFrom.secretKeyRef or environment variable references) or explicit
placeholder values (e.g., "${PROVIDER_API_KEY}" or "YOUR_API_KEY_HERE") that
clearly indicate users must substitute their own credentials before deploying
the manifest.

In `@gateway/gateway-controller/pkg/utils/llm_transformer_test.go`:
- Around line 307-313: The test assertions in the diff are order-dependent,
checking fixed indexes [0] and [1] for specific providers which will fail if the
authPolicies slice is reordered. Instead of relying on index positions, iterate
through the authPolicies slice and match each policy by its ExecutionCondition
content (looking for "openai-provider" and "anthropic-provider"), then assert
the corresponding header value using firstRequestHeaderValue against the matched
policy's Params. This makes the test resilient to any reordering of the
authPolicies slice.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 164d0672-ed28-4b5e-986a-d90317dec193

📥 Commits

Reviewing files that changed from the base of the PR and between 58e813e and f871799.

📒 Files selected for processing (41)
  • event-gateway/default-policies/openai-header-router.yaml
  • event-gateway/default-policies/openai-to-anthropic.yaml
  • event-gateway/default-policies/openai-to-azure-openai.yaml
  • event-gateway/default-policies/openai-to-gemini.yaml
  • event-gateway/default-policies/openai-to-mistral.yaml
  • gateway/build-manifest.yaml
  • gateway/build.yaml
  • gateway/examples/anthropic-openai-proxy.yaml
  • gateway/examples/anthropic-provider.yaml
  • gateway/examples/azure-openai-provider.yaml
  • gateway/examples/azure-openai-proxy.yaml
  • gateway/examples/gemini-provider.yaml
  • gateway/examples/llm-provider.yaml
  • gateway/examples/llm-proxy.yaml
  • gateway/examples/mistral-openai-proxy.yaml
  • gateway/examples/mistral-provider.yaml
  • gateway/examples/openai-multi-provider-proxy.yaml
  • gateway/examples/openai-provider.yaml
  • gateway/gateway-controller/api/management-openapi.yaml
  • gateway/gateway-controller/pkg/api/management/generated.go
  • gateway/gateway-controller/pkg/config/llm_validator.go
  • gateway/gateway-controller/pkg/utils/llm_transformer.go
  • gateway/gateway-controller/pkg/utils/llm_transformer_test.go
  • gateway/sample-policies/slugify-body/policy-definition.yaml
  • gateway/system-policies/analytics/policy-definition.yaml
  • kubernetes/gateway-operator/api/v1alpha1/llmproxy_types.go
  • kubernetes/gateway-operator/api/v1alpha1/zz_generated.deepcopy.go
  • kubernetes/gateway-operator/config/crd/bases/gateway.api-platform.wso2.com_llmproxies.yaml
  • kubernetes/gateway-operator/internal/controller/llmproxy_controller.go
  • kubernetes/gateway-operator/internal/controller/llmproxy_controller_test.go
  • kubernetes/gateway-operator/internal/controller/management_upstream_auth_payload.go
  • kubernetes/gateway-operator/internal/controller/management_valuefrom_enqueue.go
  • kubernetes/gateway-operator/internal/controller/management_valuefrom_fingerprint.go
  • kubernetes/helm/operator-helm-chart/crds/gateway.api-platform.wso2.com_llmproxies.yaml
  • mistral-proxy.yaml
  • platform-api/src/api/generated.go
  • platform-api/src/internal/dto/llm_deployment.go
  • platform-api/src/internal/model/llm.go
  • platform-api/src/internal/service/llm.go
  • platform-api/src/internal/service/llm_deployment.go
  • platform-api/src/resources/openapi.yaml

Comment thread gateway/examples/anthropic-openai-proxy.yaml
Comment thread gateway/examples/azure-openai-provider.yaml Outdated
Comment thread gateway/examples/azure-openai-provider.yaml
Comment thread gateway/examples/azure-openai-proxy.yaml
Comment thread gateway/examples/gemini-provider.yaml
Comment thread mistral-proxy.yaml
Comment thread platform-api/src/api/generated.go
Comment thread platform-api/src/internal/model/llm.go
Comment thread platform-api/src/internal/service/llm.go
Comment thread platform-api/src/resources/openapi.yaml
… in provider examples

All allowed paths in accessControl.exceptions now have matching api-key-auth
entries so loopback callers must present an API key for every exposed endpoint,
not just chat/completions.
…access control exceptions

- azure-openai-proxy: add provider.auth so the proxy can authenticate
  against the provider's api-key-auth policy on the loopback hop
- gemini-provider: add streamGenerateContent to api-key-auth paths to
  match the accessControl exceptions list
… auth, align gemini api-key-auth paths

- azure-openai-provider: replace null url comment with a valid placeholder
- azure-openai-proxy: add missing provider.auth for loopback authentication
- gemini-provider: add streamGenerateContent to api-key-auth to match accessControl exceptions

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
gateway/examples/openai-multi-provider-proxy.yaml (1)

33-43: 🎯 Functional Correctness | 🟠 Major

Remove the unsupported transformer block.

The transformer field is not defined in the additionalProviders schema; valid fields are limited to id, as, and auth. This block will likely cause a validation error or be ignored. The intended translation logic is already defined in the openai-to-anthropic policy further down in the file.

Incorrect snippet to remove
      transformer:
        type: openai-to-anthropic
        version: v1
        params:
          model: claude-sonnet-4-5-20250929
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/examples/openai-multi-provider-proxy.yaml` around lines 33 - 43, The
additionalProviders entry for anthropic-provider includes an unsupported
transformer block that is not part of the schema. Remove the transformer section
from this provider and keep only the allowed fields on the additionalProviders
item (such as id, as, and auth); the openai-to-anthropic logic should remain in
the separate policy definition later in the file.
🧹 Nitpick comments (1)
gateway/examples/openai-multi-provider-proxy.yaml (1)

102-139: 🎯 Functional Correctness | 🔵 Trivial

Remove redundant executionCondition from openai-to-anthropic translator.

The openai-to-anthropic translator (lines 102-111) includes an explicit executionCondition, while openai-to-azure-openai, openai-to-mistral, and openai-to-gemini rely solely on the id parameter in their params (lines 120, 129, 138). Per the translator policy schema, setting the provider (mapped to the id here) automatically gates execution when metadata["selected_provider"] matches. Remove line 103 to ensure consistency across all translators.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/examples/openai-multi-provider-proxy.yaml` around lines 102 - 139,
Remove the redundant executionCondition from the openai-to-anthropic translator
so it follows the same provider-gated behavior as openai-to-azure-openai,
openai-to-mistral, and openai-to-gemini. In the openai-to-anthropic block, keep
the id value in params as the provider selector and delete the explicit
metadata["selected_provider"] check; the translator policy schema already uses
the provider/id field to gate execution consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@gateway/examples/openai-multi-provider-proxy.yaml`:
- Around line 33-43: The additionalProviders entry for anthropic-provider
includes an unsupported transformer block that is not part of the schema. Remove
the transformer section from this provider and keep only the allowed fields on
the additionalProviders item (such as id, as, and auth); the openai-to-anthropic
logic should remain in the separate policy definition later in the file.

---

Nitpick comments:
In `@gateway/examples/openai-multi-provider-proxy.yaml`:
- Around line 102-139: Remove the redundant executionCondition from the
openai-to-anthropic translator so it follows the same provider-gated behavior as
openai-to-azure-openai, openai-to-mistral, and openai-to-gemini. In the
openai-to-anthropic block, keep the id value in params as the provider selector
and delete the explicit metadata["selected_provider"] check; the translator
policy schema already uses the provider/id field to gate execution consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 54dfde27-92bb-460e-b570-e74a36f4340f

📥 Commits

Reviewing files that changed from the base of the PR and between a8ca552 and 0698cbc.

📒 Files selected for processing (2)
  • gateway/examples/mistral-provider.yaml
  • gateway/examples/openai-multi-provider-proxy.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • gateway/examples/mistral-provider.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants