# Enterprise Custom Gateway Configuration in WorkWeave Router: A Deep Dive

> Learn how WorkWeave Router handles enterprise configurations with BYOK, routing traffic through private gateways by filtering requests against tenant-specific providers and model aliases.

- Repository: [Weave/router](https://github.com/workweave/router)
- Tags: deep-dive
- Published: 2026-08-30

---

**WorkWeave Router supports Bring-Your-Own-Key (BYOK) enterprise configurations that force traffic through private gateway endpoints by filtering requests against a tenant-specific set of gateway providers and model aliases.**

The `workweave/router` repository implements enterprise-grade routing logic that allows organizations to replace default vendor APIs with custom, self-hosted gateway endpoints. This capability is anchored in the request model structure and a dedicated resolution policy that ensures only models explicitly supported by the enterprise gateway are considered for routing.

## Request-Level Gateway Configuration

Enterprise routing begins at the request boundary. The `router.Request` struct defined in [`internal/router/router.go`](https://github.com/workweave/router/blob/main/internal/router/router.go) (lines 47–50) contains three critical fields that govern how traffic flows through custom gateways:

- **`EnabledProviders`**: An optional per-request whitelist of providers; when nil, all providers are considered eligible.
- **`CustomBindings`**: A map of catalog model IDs to provider name arrays derived from a key’s `model_aliases`, applied after vendor bindings.
- **`GatewayProviders`**: The enterprise gating field. When non-empty, this signals **gateway-exclusive routing**, restricting candidate models to only those aliased by the gateway key.

Source: [[`internal/router/router.go`](https://github.com/workweave/router/blob/main/internal/router/router.go)](https://github.com/workweave/router/blob/main/internal/router/router.go#L47-L50).

When `GatewayProviders` contains values such as `providers.ProviderOpenAIGateway`, the router enters a restricted mode that ignores standard vendor bindings unless explicitly mapped through the gateway’s alias configuration.

## Gateway-Exclusive Routing Resolution

The `policy.Resolver` component in [`internal/router/policy/resolver.go`](https://github.com/workweave/router/blob/main/internal/router/policy/resolver.go) implements the filtering logic that enforces enterprise gateway constraints. During the resolution phase, the resolver inspects `req.GatewayProviders` (referenced as `gateways` in the source). If this set is non-empty, the resolver executes a strict filtering routine:

1. Invokes `gatewayBindings(id, gateways, req.CustomBindings)` to intersect the catalog model ID with the gateway’s supported provider set.
2. If the intersection is empty, the model is excluded and a diagnostic entry is emitted with the reason `ExclusionGatewayNotServed`.

```go
if len(gateways) > 0 {
    allowedBindings := gatewayBindings(id, gateways, req.CustomBindings)
    if len(allowedBindings) == 0 {
        diagnostics = append(diagnostics,
            Diagnostic{CatalogID: id, RosterID: rosterID,
                       Reason: ExclusionGatewayNotServed})
        continue
    }
    // Candidates appended only for allowed bindings...
}

```

Source: [[`internal/router/policy/resolver.go`](https://github.com/workweave/router/blob/main/internal/router/policy/resolver.go)](https://github.com/workweave/router/blob/main/internal/router/policy/resolver.go#L10-L15).

This mechanism ensures that enterprise installations can **force** traffic through their own infrastructure by populating `GatewayProviders` with their specific provider constants. Any catalog models not explicitly aliased by the gateway key generate a `gateway_not_served` exclusion diagnostic.

### Exclusion Diagnostics

When a model lacks a matching alias in the gateway configuration, the resolver appends a structured diagnostic entry. This provides observability into why specific models were skipped, aiding enterprise administrators in debugging gateway coverage gaps.

## Handling API Version Path Mismatches

Enterprise gateways frequently expose API version paths that deviate from the canonical `/v1` segment expected by standard provider adapters. The `providers.GatewayVersionMemo` helper (located in [`internal/providers/gateway_version.go`](https://github.com/workweave/router/blob/main/internal/providers/gateway_version.go)) automates version path discovery and memoization.

The `URLs(baseURL, suffix)` method returns a prioritized list of endpoint candidates:

```go
func (m *GatewayVersionMemo) URLs(baseURL, suffix string) []string {
    primary := baseURL + suffix
    alt := altVersionedURL(baseURL, suffix)
    if alt == "" { return []string{primary} }
    if _, ok := m.learned.Load(baseURL); ok { return []string{alt, primary} }
    return []string{primary, alt}
}

```

Source: [[`internal/providers/gateway_version.go`](https://github.com/workweave/router/blob/main/internal/providers/gateway_version.go)](https://github.com/workweave/router/blob/main/internal/providers/gateway_version.go#L12-L30).

The logic works as follows:

1. Constructs the primary URL by concatenating `baseURL` and `suffix`.
2. Generates an alternate URL using `altVersionedURL` if the base URL’s version segment conflicts with the suffix.
3. Checks the `learned` sync map; if the base URL has previously exhibited a mismatch, the alternate URL is prioritized.
4. Otherwise, attempts the primary URL first, falling back to the alternate on failure, and records the result via `Learn(baseURL)`.

This adaptive approach allows WorkWeave Router to automatically correct for non-standard version segments (such as `/v2` or `/api/v1`) without requiring manual configuration changes.

## End-to-End Configuration Flow

The complete enterprise custom gateway workflow involves four distinct stages:

1. **Configuration Storage**: An installation administrator persists a BYOK gateway key in the database, populating the `model_aliases` field to define which catalog models the custom endpoint can serve.

2. **Request Enrichment**: Authentication middleware (located in [`internal/server/middleware/auth.go`](https://github.com/workweave/router/blob/main/internal/server/middleware/auth.go)) extracts the gateway key, identifies its provider name, and populates `req.GatewayProviders` and `req.CustomBindings` on the incoming request context.

3. **Policy Resolution**: The `policy.Resolver.Resolve` method filters the catalog using the gateway-exclusive logic described above, producing a `ResolvedCandidates` set containing only gateway-supported models.

4. **Dispatch Adaptation**: The `proxy.Service` selects a model from the resolved candidates and invokes the gateway HTTP client. The client utilizes `GatewayVersionMemo` to determine the correct versioned URL before transmitting the request.

## Summary

- **Gateway-exclusive routing** is triggered by populating `router.Request.GatewayProviders`, forcing the resolver to ignore standard vendor bindings.
- The `policy.Resolver` filters catalog models against gateway aliases, emitting `ExclusionGatewayNotServed` diagnostics for unsupported models.
- `GatewayVersionMemo` automatically detects and caches alternate API version paths for enterprise endpoints that deviate from standard `/v1` segments.
- The configuration flows from database-stored BYOK keys through authentication middleware into the resolution and dispatch pipeline.

## Frequently Asked Questions

### What is BYOK (Bring-Your-Own-Key) configuration in WorkWeave Router?

BYOK configuration allows enterprise tenants to provide their own API keys and endpoint URLs for AI gateways rather than using WorkWeave’s default vendor integrations. The router treats these as first-class routing targets by populating `GatewayProviders` and `CustomBindings` on the request, ensuring traffic flows exclusively through the tenant’s designated infrastructure.

### How does the router handle models not supported by a custom gateway?

When `policy.Resolver` encounters a catalog model with no matching alias in the gateway’s provider set, it excludes the model from the candidate list and appends a diagnostic entry with the reason `gateway_not_served`. This prevents routing attempts to endpoints that cannot fulfill the request while providing visibility into coverage gaps.

### What happens when a gateway uses a non-standard API version path?

The `providers.GatewayVersionMemo` helper detects version segment mismatches between the base URL and expected suffix. It attempts the standard path first, then learns and prioritizes alternate versioned URLs if the initial attempt fails, automatically adapting to endpoints using paths like `/v2` or `/api/v1` instead of the canonical `/v1`.

### Where is the gateway configuration stored and applied?

Gateway configurations are stored as BYOK keys in the database, including the `model_aliases` mapping. The [`internal/server/middleware/auth.go`](https://github.com/workweave/router/blob/main/internal/server/middleware/auth.go) middleware reads these keys during request authentication and populates the `GatewayProviders` and `CustomBindings` fields on the `router.Request` struct, which subsequent resolution and dispatch layers consume to enforce routing policy.