iop/apps/edge/internal/openai/principal_routes_test.go

939 lines
36 KiB
Go

package openai
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
"time"
"iop/apps/edge/internal/authprojection"
edgeservice "iop/apps/edge/internal/service"
"iop/packages/go/config"
"iop/packages/go/streamgate"
iop "iop/proto/gen/iop"
)
func makeTestProjection(gen uint64, now time.Time, ttl time.Duration, tokens map[string]string, routes map[string]authprojection.Route) *iop.PrincipalProjection {
proj := &iop.PrincipalProjection{
Generation: gen,
IssuedAtUnixNano: now.UnixNano(),
ExpiresAtUnixNano: now.Add(ttl).UnixNano(),
}
for rawToken, pRef := range tokens {
digest := sha256.Sum256([]byte(rawToken))
proj.Tokens = append(proj.Tokens, &iop.ProjectedPrincipalToken{
TokenDigestSha256: hex.EncodeToString(digest[:]),
PrincipalRef: pRef,
PrincipalAlias: pRef + "-alias",
TokenRef: "tok-" + pRef,
TokenRevision: gen,
})
}
for _, r := range routes {
selector := r.ResourceSelector
if selector == "" {
selector = "default"
}
routeRev := r.RouteRevision
if routeRev == 0 {
routeRev = gen
}
credRev := r.CredentialRevision
if credRev == 0 {
credRev = gen
}
proj.Routes = append(proj.Routes, &iop.ProjectedPrincipalRoute{
RouteId: r.RouteID,
RouteAlias: r.RouteAlias,
PrincipalRef: r.PrincipalRef,
CredentialSlotRef: r.CredentialSlotRef,
ProfileId: r.ProfileID,
UpstreamModel: r.UpstreamModel,
ResourceSelector: selector,
RouteRevision: routeRev,
CredentialRevision: credRev,
})
}
return proj
}
func TestManagedModelsListIsPrincipalScoped(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
"token-p2": "principal-2",
}, map[string]authprojection.Route{
"r1": {RouteID: "route-p1", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
"r2": {RouteID: "route-p2", PrincipalRef: "principal-2", CredentialSlotRef: "slot-2", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{
Models: []string{"global-model"},
}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
// Call for P1
reqP1 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
reqP1.Header.Set("Authorization", "Bearer token-p1")
wP1 := httptest.NewRecorder()
srv.routes().ServeHTTP(wP1, reqP1)
if wP1.Code != http.StatusOK {
t.Fatalf("P1 status: %d body: %s", wP1.Code, wP1.Body.String())
}
var respP1 openAIModelsResponse
if err := json.Unmarshal(wP1.Body.Bytes(), &respP1); err != nil {
t.Fatal(err)
}
if len(respP1.Data) != 1 || respP1.Data[0].ID != "route-p1" {
t.Fatalf("P1 models: expected [route-p1], got %+v", respP1.Data)
}
// Call for P2
reqP2 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
reqP2.Header.Set("Authorization", "Bearer token-p2")
wP2 := httptest.NewRecorder()
srv.routes().ServeHTTP(wP2, reqP2)
if wP2.Code != http.StatusOK {
t.Fatalf("P2 status: %d body: %s", wP2.Code, wP2.Body.String())
}
var respP2 openAIModelsResponse
if err := json.Unmarshal(wP2.Body.Bytes(), &respP2); err != nil {
t.Fatal(err)
}
if len(respP2.Data) != 1 || respP2.Data[0].ID != "route-p2" {
t.Fatalf("P2 models: expected [route-p2], got %+v", respP2.Data)
}
}
func TestManagedAnthropicModelsListUsesRouteIDs(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, map[string]authprojection.Route{
"r1": {RouteID: "claude-route-1", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "anthropic", UpstreamModel: "claude-3-5-sonnet", ResourceSelector: "default"},
})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
req := httptest.NewRequest(http.MethodGet, "/anthropic/v1/models", nil)
req.Header.Set("Authorization", "Bearer token-p1")
req.Header.Set("anthropic-version", "2023-06-01")
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status: %d body: %s", w.Code, w.Body.String())
}
var anthropicResp struct {
Data []struct {
ID string `json:"id"`
} `json:"data"`
}
if err := json.Unmarshal(w.Body.Bytes(), &anthropicResp); err != nil {
t.Fatal(err)
}
if len(anthropicResp.Data) != 1 || anthropicResp.Data[0].ID != "claude-route-1" {
t.Fatalf("expected [claude-route-1], got %+v", anthropicResp.Data)
}
}
func TestManagedModelsOmitInactiveRoutes(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj1 := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, map[string]authprojection.Route{
"r1": {RouteID: "route-1", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
})
if err := cache.Apply(proj1); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
// Gen 2 removes route-1
proj2 := makeTestProjection(2, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, nil)
if err := cache.Apply(proj2); err != nil {
t.Fatal(err)
}
req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
req.Header.Set("Authorization", "Bearer token-p1")
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status: %d body: %s", w.Code, w.Body.String())
}
var resp openAIModelsResponse
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatal(err)
}
if len(resp.Data) != 0 {
t.Fatalf("expected 0 models for omitted route, got %+v", resp.Data)
}
}
func TestUnmanagedModelsRetainGlobalCatalog(t *testing.T) {
srv := NewServer(config.EdgeOpenAIConf{
Models: []string{"global-model-1", "global-model-2"},
}, &fakeRunService{}, nil)
req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status: %d body: %s", w.Code, w.Body.String())
}
var resp openAIModelsResponse
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatal(err)
}
if len(resp.Data) != 2 {
t.Fatalf("expected 2 global models, got %d", len(resp.Data))
}
}
func TestManagedRouteSelectsOnlyBoundSlot(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, map[string]authprojection.Route{
"r1": {
RouteID: "bound-route",
PrincipalRef: "principal-1",
CredentialSlotRef: "slot-bound",
ProfileID: "profile-bound",
UpstreamModel: "model-bound",
ResourceSelector: "default",
},
})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
srv.SetModelCatalog([]config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "model-bound"}}})
req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
req.Header.Set("Authorization", "Bearer token-p1")
principal, view, ok := srv.authenticatePrincipal(req)
if !ok {
t.Fatal("managed authentication failed")
}
ctx := withAuthenticatedProjectionView(withPrincipal(req.Context(), principal), view)
disp, err := srv.resolveRouteDispatchForPrincipal(ctx, "bound-route")
if err != nil {
t.Fatalf("resolveRouteDispatchForPrincipal failed: %v", err)
}
if !disp.Managed || disp.CredentialSlotRef != "slot-bound" || disp.ModelGroupKey != "catalog-internal" {
t.Fatalf("unexpected dispatch: %+v", disp)
}
pred := disp.CandidatePredicate()
if pred == nil {
t.Fatalf("expected non-nil CandidatePredicate")
}
// Correct candidate
validCandidate := edgeservice.ProviderPoolCandidate{
ProviderID: "provider-resource",
ProfileID: "profile-bound",
ActualModel: "model-bound",
ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
}
if !pred(validCandidate) {
t.Fatalf("pred rejected valid candidate")
}
// A default selector does not confuse credential slot identity with a
// provider resource restriction.
otherResource := validCandidate
otherResource.ProviderID = "another-provider"
if !pred(otherResource) {
t.Fatalf("default selector unexpectedly restricted provider resource")
}
// Mismatched profile
badProfile := validCandidate
badProfile.ProfileID = "profile-other"
if pred(badProfile) {
t.Fatalf("pred accepted candidate with bad profile")
}
// Mismatched upstream model
badModel := validCandidate
badModel.ActualModel = "model-other"
if pred(badModel) {
t.Fatalf("pred accepted candidate with bad upstream model")
}
}
func TestManagedRoutePredicateSurvivesRecovery(t *testing.T) {
route := authprojection.Route{
RouteID: "r1",
CredentialSlotRef: "slot-1",
ProfileID: "prof-1",
UpstreamModel: "mod-1",
}
pred := managedRouteCandidatePredicate(route, "provider-1")
streamPred := func(c edgeservice.ProviderPoolCandidate) bool {
return c.ExecutionPath == "provider_tunnel"
}
composed := composeCandidatePredicates(streamPred, pred)
candGood := edgeservice.ProviderPoolCandidate{
ProviderID: "provider-1",
ProfileID: "prof-1",
ActualModel: "mod-1",
ExecutionPath: "provider_tunnel",
}
candBadSlot := candGood
candBadSlot.ProviderID = "provider-2"
if !composed(candGood) {
t.Fatalf("composed predicate rejected valid candidate")
}
if composed(candBadSlot) {
t.Fatalf("composed predicate accepted mismatched slot")
}
}
func TestManagedCatalogBindingExplicitSelectorAndNoFallback(t *testing.T) {
route := authprojection.Route{UpstreamModel: "served", ResourceSelector: "provider-resource"}
catalog := []config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served", "other": "served"}}}
binding, err := resolveManagedCatalogBinding(route, catalog)
if err != nil || binding.ModelGroupKey != "catalog-internal" || binding.ProviderID != "provider-resource" {
t.Fatalf("binding=%+v err=%v", binding, err)
}
route.ResourceSelector = "default"
binding, err = resolveManagedCatalogBinding(route, catalog)
if err != nil || binding.ProviderID != "" {
t.Fatalf("default binding=%+v err=%v", binding, err)
}
route.ResourceSelector = "missing"
if _, err := resolveManagedCatalogBinding(route, catalog); !errors.Is(err, ErrRouteNotFound) {
t.Fatalf("missing selector err=%v", err)
}
route.ResourceSelector = "default"
if _, err := resolveManagedCatalogBinding(route, append(catalog, config.ModelCatalogEntry{ID: "another-group", Providers: map[string]string{"provider-resource": "served"}})); !errors.Is(err, ErrRouteNotFound) {
t.Fatalf("ambiguous catalog err=%v", err)
}
}
func TestMetadataSpoofIsOverwrittenByManagedBinding(t *testing.T) {
route := routeDispatch{Managed: true, RouteID: "route-public", CredentialSlotRef: "credential-slot", RouteRevision: 7, CredentialRevision: 11}
req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
req = req.WithContext(withPrincipal(req.Context(), openAIPrincipal{PrincipalRef: "principal", Source: principalSourceProjection}))
metadata, err := resolveCallerIdentity(req, route, json.RawMessage(`{"iop_route_id":"spoof","iop_route_revision":"0","iop_credential_slot_ref":"spoof","iop_credential_revision":"0"}`))
if err != nil {
t.Fatal(err)
}
if metadata[routeMetaID] != "route-public" || metadata[routeMetaRevision] != "7" || metadata[credentialSlotMeta] != "credential-slot" || metadata[credentialRevisionMeta] != "11" {
t.Fatalf("trusted metadata=%+v", metadata)
}
}
func TestManagedProjectionFixturePreservesBindingFacts(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-1": "principal-1",
}, map[string]authprojection.Route{
"r1": {
RouteID: "route-public",
PrincipalRef: "principal-1",
CredentialSlotRef: "credential-slot",
ProfileID: "openai",
UpstreamModel: "gpt-4o",
ResourceSelector: "provider-resource",
RouteRevision: 4,
CredentialRevision: 9,
},
})
if len(proj.Routes) != 1 {
t.Fatalf("expected 1 route, got %d", len(proj.Routes))
}
r := proj.Routes[0]
if r.ResourceSelector != "provider-resource" {
t.Errorf("ResourceSelector: got %q, want provider-resource", r.ResourceSelector)
}
if r.RouteRevision != 4 {
t.Errorf("RouteRevision: got %d, want 4", r.RouteRevision)
}
if r.CredentialRevision != 9 {
t.Errorf("CredentialRevision: got %d, want 9", r.CredentialRevision)
}
}
func TestManagedSurfacesUseDistinctBinding(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
newManaged := func(route authprojection.Route, catalog config.ModelCatalogEntry, candidate edgeservice.ProviderPoolCandidate) (*Server, *providerFakeRunService) {
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal"}, map[string]authprojection.Route{"route": route})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
fake := &providerFakeRunService{poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), poolSelectedCandidate: candidate}
srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
setManagedPrincipalProjection(srv, cache)
srv.SetModelCatalog([]config.ModelCatalogEntry{catalog})
return srv, fake
}
assertManagedTemplate := func(t *testing.T, group, provider string, meta map[string]string) {
t.Helper()
if group != "catalog-internal" {
t.Fatalf("model group=%q, want catalog-internal", group)
}
if provider != "provider-resource" {
t.Fatalf("provider=%q, want provider-resource", provider)
}
if meta[routeMetaID] != "route-public" || meta[routeMetaRevision] != "4" || meta[credentialSlotMeta] != "credential-slot" || meta[credentialRevisionMeta] != "9" {
t.Fatalf("trusted metadata=%+v", meta)
}
}
assertManagedBinding := func(t *testing.T, fake *providerFakeRunService) {
t.Helper()
run := fake.poolLastRunSnapshot()
tunnels := fake.tunnelReqsSnapshot()
if len(tunnels) != 1 {
t.Fatalf("tunnel requests=%d, want 1", len(tunnels))
}
assertManagedTemplate(t, run.ModelGroupKey, run.ProviderID, run.Metadata)
assertManagedTemplate(t, tunnels[0].ModelGroupKey, tunnels[0].ProviderID, tunnels[0].Metadata)
}
route := authprojection.Route{
RouteID: "route-public",
PrincipalRef: "principal",
CredentialSlotRef: "credential-slot",
ProfileID: "profile-openai",
UpstreamModel: "served-model",
ResourceSelector: "provider-resource",
RouteRevision: 4,
CredentialRevision: 9,
}
t.Run("chat", func(t *testing.T) {
catalog := config.ModelCatalogEntry{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served-model"}}
candidate := edgeservice.ProviderPoolCandidate{ProviderID: "provider-resource", ProfileID: "profile-openai", ActualModel: "served-model", ExecutionPath: string(edgeservice.ProviderPoolPathTunnel)}
srv, fake := newManaged(route, catalog, candidate)
fake.tunnelFrames = staticProviderTunnelFrames(`{"id":"chatcmpl-1","object":"chat.completion","model":"served-model","choices":[{"message":{"role":"assistant","content":"hi"}}]}`)
req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{"model":"route-public","metadata":{"iop_route_id":"spoof","iop_route_revision":"0","iop_credential_slot_ref":"spoof","iop_credential_revision":"0"},"messages":[{"role":"user","content":"hi"}]}`))
req.Header.Set("Authorization", "Bearer managed-token")
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
}
if !strings.Contains(w.Body.String(), `"model":"route-public"`) {
t.Fatalf("body=%s, want model:route-public", w.Body.String())
}
assertManagedBinding(t, fake)
})
t.Run("responses", func(t *testing.T) {
catalog := config.ModelCatalogEntry{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served-model"}}
candidate := edgeservice.ProviderPoolCandidate{ProviderID: "provider-resource", ProfileID: "profile-openai", ActualModel: "served-model", ExecutionPath: string(edgeservice.ProviderPoolPathTunnel)}
srv, fake := newManaged(route, catalog, candidate)
req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{"model":"route-public","metadata":{"iop_route_id":"spoof","iop_route_revision":"0","iop_credential_slot_ref":"spoof","iop_credential_revision":"0"},"input":"hi"}`))
req.Header.Set("Authorization", "Bearer managed-token")
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
}
assertManagedBinding(t, fake)
})
t.Run("messages", func(t *testing.T) {
cand := anthropicTestCandidate(t, "anthropic")
cand.ProviderID = "provider-resource"
mRoute := authprojection.Route{
RouteID: "route-public",
PrincipalRef: "principal",
CredentialSlotRef: "credential-slot",
ProfileID: cand.ProfileID,
UpstreamModel: cand.ActualModel,
ResourceSelector: "provider-resource",
RouteRevision: 4,
CredentialRevision: 9,
}
catalog := config.ModelCatalogEntry{ID: "catalog-internal", Providers: map[string]string{"provider-resource": cand.ActualModel}}
srv, fake := newManaged(mRoute, catalog, cand)
fake.tunnelFrames = anthropicTunnelFrames(http.StatusOK, "application/json", mustReadAnthropicFixture(t, "native_message.json"))
req := httptest.NewRequest(http.MethodPost, "/v1/messages", strings.NewReader(`{"model":"route-public","max_tokens":8,"messages":[{"role":"user","content":"hi"}]}`))
req.Header.Set("Authorization", "Bearer managed-token")
req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
}
assertManagedBinding(t, fake)
})
}
func TestManagedCountTokensLocalAndNativeBinding(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
route := authprojection.Route{
RouteID: "route-public",
PrincipalRef: "principal",
CredentialSlotRef: "credential-slot",
ProfileID: "profile",
UpstreamModel: "served-model",
ResourceSelector: "provider-resource",
RouteRevision: 4,
CredentialRevision: 9,
}
t.Run("local counter", func(t *testing.T) {
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
if err := cache.Apply(makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal"}, map[string]authprojection.Route{"route": route})); err != nil {
t.Fatal(err)
}
fake := &providerFakeRunService{}
srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
setManagedPrincipalProjection(srv, cache)
srv.SetModelCatalog([]config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served-model"}, TokenCounter: &config.TokenCounterConf{Mode: config.TokenCounterDeterministic}}})
req := httptest.NewRequest(http.MethodPost, "/v1/messages/count_tokens", strings.NewReader(`{"model":"route-public","messages":[{"role":"user","content":"hi"}]}`))
req.Header.Set("Authorization", "Bearer managed-token")
req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
}
if fake.poolSubmitCountSnapshot() != 0 {
t.Fatalf("expected 0 pool dispatches for local counter, got %d", fake.poolSubmitCountSnapshot())
}
})
t.Run("native provider-pool fallback", func(t *testing.T) {
cand := anthropicTestCandidate(t, "anthropic")
cand.ProviderID = "provider-resource"
nativeRoute := route
nativeRoute.ProfileID = cand.ProfileID
nativeRoute.UpstreamModel = cand.ActualModel
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
if err := cache.Apply(makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal"}, map[string]authprojection.Route{"route": nativeRoute})); err != nil {
t.Fatal(err)
}
fake := &providerFakeRunService{poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), poolSelectedCandidate: cand}
fake.tunnelFrames = anthropicTunnelFrames(http.StatusOK, "application/json", []byte(`{"input_tokens":10}`))
srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
setManagedPrincipalProjection(srv, cache)
srv.SetModelCatalog([]config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": cand.ActualModel}}})
req := httptest.NewRequest(http.MethodPost, "/v1/messages/count_tokens", strings.NewReader(`{"model":"route-public","messages":[{"role":"user","content":"hi"}]}`))
req.Header.Set("Authorization", "Bearer managed-token")
req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
}
if fake.poolSubmitCountSnapshot() != 1 {
t.Fatalf("expected 1 pool dispatch for native counter, got %d", fake.poolSubmitCountSnapshot())
}
if fake.poolLastRun.ModelGroupKey != "catalog-internal" {
t.Fatalf("model group=%q", fake.poolLastRun.ModelGroupKey)
}
meta := fake.poolLastRun.Metadata
if meta[routeMetaID] != "route-public" || meta[routeMetaRevision] != "4" || meta[credentialSlotMeta] != "credential-slot" || meta[credentialRevisionMeta] != "9" {
t.Fatalf("trusted metadata=%+v", meta)
}
})
}
type managedRecoveryRecorderService struct {
fakeRunService
mu sync.Mutex
submissions []edgeservice.ProviderPoolDispatchRequest
candidateOrder [][]edgeservice.ProviderPoolCandidate
}
func (s *managedRecoveryRecorderService) SubmitProviderPool(ctx context.Context, req edgeservice.ProviderPoolDispatchRequest) (*edgeservice.ProviderPoolDispatchResult, error) {
s.mu.Lock()
defer s.mu.Unlock()
idx := len(s.submissions)
s.submissions = append(s.submissions, req)
var candidates []edgeservice.ProviderPoolCandidate
if idx < len(s.candidateOrder) {
candidates = s.candidateOrder[idx]
}
var accepted *edgeservice.ProviderPoolCandidate
for i := range candidates {
cand := candidates[i]
if req.AcceptCandidate != nil {
if req.AcceptCandidate(cand) {
if accepted != nil {
return nil, errors.New("multiple candidates accepted")
}
accepted = &cand
}
}
}
if accepted == nil {
return nil, edgeservice.ErrProviderPoolCandidateRejected
}
disp := edgeservice.RunDispatch{
RunID: "run-recovery-" + accepted.ProviderID,
NodeID: "node-1",
ModelGroupKey: req.Run.ModelGroupKey,
Adapter: "tunnel",
Target: accepted.ActualModel,
ProviderID: accepted.ProviderID,
ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
}
handle := &fakeTunnelHandle{
dispatch: disp,
frames: staticProviderTunnelFrames(`{"ok":true}`),
}
return &edgeservice.ProviderPoolDispatchResult{
Path: edgeservice.ProviderPoolPathTunnel,
Tunnel: handle,
DispatchInfo: disp,
}, nil
}
func TestManagedRecoveryReentersProviderPoolWithFrozenBinding(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, map[string]authprojection.Route{
"r1": {
RouteID: "bound-route",
PrincipalRef: "principal-1",
CredentialSlotRef: "slot-bound",
ProfileID: "profile-bound",
UpstreamModel: "model-bound",
ResourceSelector: "provider-resource",
RouteRevision: 5,
CredentialRevision: 12,
},
})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
candValid := edgeservice.ProviderPoolCandidate{
ProviderID: "provider-resource",
ProfileID: "profile-bound",
ActualModel: "model-bound",
ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
}
candWrongSlot := edgeservice.ProviderPoolCandidate{
ProviderID: "wrong-provider",
ProfileID: "profile-bound",
ActualModel: "model-bound",
ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
}
candWrongProfile := edgeservice.ProviderPoolCandidate{
ProviderID: "provider-resource",
ProfileID: "wrong-profile",
ActualModel: "model-bound",
ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
}
candWrongModel := edgeservice.ProviderPoolCandidate{
ProviderID: "provider-resource",
ProfileID: "profile-bound",
ActualModel: "wrong-model",
ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
}
initialCandidates := []edgeservice.ProviderPoolCandidate{
candWrongSlot, candWrongProfile, candWrongModel, candValid,
}
recoveryCandidates := []edgeservice.ProviderPoolCandidate{
candWrongModel, candWrongProfile, candWrongSlot, candValid,
}
recorder := &managedRecoveryRecorderService{
candidateOrder: [][]edgeservice.ProviderPoolCandidate{initialCandidates, recoveryCandidates},
}
srv := NewServer(config.EdgeOpenAIConf{}, recorder, nil)
setManagedPrincipalProjection(srv, cache)
srv.SetModelCatalog([]config.ModelCatalogEntry{
{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "model-bound"}},
})
req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{"model":"bound-route","metadata":{"iop_route_id":"spoof"},"messages":[{"role":"user","content":"hi"}]}`))
req.Header.Set("Authorization", "Bearer token-p1")
principal, view, ok := srv.authenticatePrincipal(req)
if !ok {
t.Fatal("authenticatePrincipal failed")
}
ctx := withAuthenticatedProjectionView(withPrincipal(req.Context(), principal), view)
route, err := srv.resolveRouteDispatchForPrincipal(ctx, "bound-route")
if err != nil {
t.Fatalf("resolveRouteDispatchForPrincipal failed: %v", err)
}
runMeta, err := resolveCallerIdentity(req.WithContext(ctx), route, json.RawMessage(`{"iop_route_id":"spoof"}`))
if err != nil {
t.Fatalf("resolveCallerIdentity failed: %v", err)
}
requestCtx := openAIRequestContext{
r: req.WithContext(ctx),
route: route,
callerMetadata: runMeta,
usage: srv.newOpenAIUsageRecorder(ctx, "bound-route", usageEndpointChatCompletions),
}
dc := srv.newChatDispatchContext(requestCtx, chatCompletionRequest{Model: "bound-route"}, "prompt", strictOutputPolicy{})
initialPoolReq := edgeservice.ProviderPoolDispatchRequest{
Run: dc.submitReq,
Tunnel: edgeservice.SubmitProviderTunnelRequest{
ModelGroupKey: dc.route.effectiveModelGroupKey("bound-route"),
ProviderID: dc.route.ProviderID,
Method: http.MethodPost,
Path: "/v1/chat/completions",
Operation: string(config.OperationChatCompletions),
Metadata: dc.runMetadata,
ProviderPool: true,
},
}
if dc.route.Managed {
initialPoolReq.AcceptCandidate = dc.route.CandidatePredicate()
}
res1, err := srv.service.SubmitProviderPool(ctx, initialPoolReq)
if err != nil {
t.Fatalf("initial SubmitProviderPool failed: %v", err)
}
if res1 == nil {
t.Fatal("initial SubmitProviderPool returned nil result")
}
tunnelReq := openAITunnelStreamGateRequest{
route: route,
method: http.MethodPost,
path: "/v1/chat/completions",
operation: string(config.OperationChatCompletions),
modelGroupKey: route.effectiveModelGroupKey("bound-route"),
metadata: dc.runMetadata,
pool: &initialPoolReq,
rewriteBody: func(b []byte, target string) ([]byte, error) {
return b, nil
},
}
admissionBuilder := newOpenAITunnelRecoveryAdmissionBuilder(tunnelReq)
recoveryAdmission, err := admissionBuilder(ctx, streamgate.RebuiltRequest{}, []byte(`{"model":"bound-route"}`))
if err != nil {
t.Fatalf("newOpenAITunnelRecoveryAdmissionBuilder failed: %v", err)
}
if recoveryAdmission.kind != openAIAdmissionPool {
t.Fatalf("expected recovery admission kind openAIAdmissionPool, got %v", recoveryAdmission.kind)
}
res2, err := srv.service.SubmitProviderPool(ctx, recoveryAdmission.pool)
if err != nil {
t.Fatalf("recovery SubmitProviderPool failed: %v", err)
}
if res2 == nil {
t.Fatal("recovery SubmitProviderPool returned nil result")
}
recorder.mu.Lock()
subs := append([]edgeservice.ProviderPoolDispatchRequest(nil), recorder.submissions...)
recorder.mu.Unlock()
if len(subs) != 2 {
t.Fatalf("expected 2 submissions to SubmitProviderPool, got %d", len(subs))
}
for i, sub := range subs {
if sub.Run.ModelGroupKey != "catalog-internal" || sub.Tunnel.ModelGroupKey != "catalog-internal" {
t.Errorf("submission %d: expected ModelGroupKey 'catalog-internal', got run=%q tunnel=%q", i, sub.Run.ModelGroupKey, sub.Tunnel.ModelGroupKey)
}
if sub.Run.Metadata[routeMetaID] != "bound-route" || sub.Run.Metadata[routeMetaRevision] != "5" || sub.Run.Metadata[credentialSlotMeta] != "slot-bound" || sub.Run.Metadata[credentialRevisionMeta] != "12" {
t.Errorf("submission %d: Run trusted metadata mismatched: %+v", i, sub.Run.Metadata)
}
if sub.Tunnel.Metadata[routeMetaID] != "bound-route" || sub.Tunnel.Metadata[routeMetaRevision] != "5" || sub.Tunnel.Metadata[credentialSlotMeta] != "slot-bound" || sub.Tunnel.Metadata[credentialRevisionMeta] != "12" {
t.Errorf("submission %d: Tunnel trusted metadata mismatched: %+v", i, sub.Tunnel.Metadata)
}
if !sub.AcceptCandidate(candValid) {
t.Errorf("submission %d: rejected valid candidate", i)
}
if sub.AcceptCandidate(candWrongSlot) {
t.Errorf("submission %d: accepted candidate with wrong slot/provider", i)
}
if sub.AcceptCandidate(candWrongProfile) {
t.Errorf("submission %d: accepted candidate with wrong profile", i)
}
if sub.AcceptCandidate(candWrongModel) {
t.Errorf("submission %d: accepted candidate with wrong model", i)
}
}
}
func TestGenerationSwapKeepsAuthenticatedRouteView(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
first := makeTestProjection(1, now, time.Hour, map[string]string{"token-p1": "principal-1"}, map[string]authprojection.Route{"r": {RouteID: "route-old", PrincipalRef: "principal-1", CredentialSlotRef: "slot", ProfileID: "profile", UpstreamModel: "served", ResourceSelector: "default"}})
second := makeTestProjection(2, now, time.Hour, map[string]string{"token-p1": "principal-1"}, map[string]authprojection.Route{"r": {RouteID: "route-new", PrincipalRef: "principal-1", CredentialSlotRef: "slot", ProfileID: "profile", UpstreamModel: "served", ResourceSelector: "default"}})
if err := cache.Apply(first); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
handler := srv.withAuth(func(w http.ResponseWriter, r *http.Request) {
if err := cache.Apply(second); err != nil {
t.Fatal(err)
}
models, err := srv.advertisedModelsForPrincipal(r.Context())
if err != nil {
t.Fatal(err)
}
if len(models) != 1 || models[0].ID != "route-old" {
t.Fatalf("models after swap: %+v", models)
}
w.WriteHeader(http.StatusNoContent)
})
req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
req.Header.Set("Authorization", "Bearer token-p1")
w := httptest.NewRecorder()
handler(w, req)
if w.Code != http.StatusNoContent {
t.Fatalf("status=%d", w.Code)
}
}
func TestManagedRouteFailureDoesNotFallback(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, map[string]authprojection.Route{
"r1": {RouteID: "known-route", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "prof-1", UpstreamModel: "mod-1", ResourceSelector: "default"},
})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{
Target: "legacy-fallback-target",
ModelRoutes: []config.OpenAIRouteEntry{
{Model: "unmanaged-model", Target: "unmanaged-target"},
},
}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
req.Header.Set("Authorization", "Bearer token-p1")
ctx := withPrincipal(req.Context(), openAIPrincipal{PrincipalRef: "principal-1", Source: principalSourceProjection})
// Unknown route in managed mode
_, err := srv.resolveRouteDispatchForPrincipal(ctx, "unmanaged-model")
if err == nil {
t.Fatalf("expected error resolving unmanaged-model in managed mode, got nil")
}
// Cross-principal route in managed mode
_, err = srv.resolveRouteDispatchForPrincipal(ctx, "other-principal-route")
if err == nil {
t.Fatalf("expected error resolving cross-principal route, got nil")
}
}
func TestManagedSurfacesTable(t *testing.T) {
now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
proj := makeTestProjection(1, now, time.Hour, map[string]string{
"token-p1": "principal-1",
}, map[string]authprojection.Route{
"r1": {RouteID: "chat-route", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
"r2": {RouteID: "messages-route", PrincipalRef: "principal-1", CredentialSlotRef: "slot-2", ProfileID: "anthropic", UpstreamModel: "claude-3", ResourceSelector: "default"},
})
if err := cache.Apply(proj); err != nil {
t.Fatal(err)
}
srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
setManagedPrincipalProjection(srv, cache)
tests := []struct {
name string
method string
path string
headers map[string]string
body string
wantStatus int
}{
{
name: "chat completion unknown route",
method: http.MethodPost, path: "/v1/chat/completions",
headers: map[string]string{"Authorization": "Bearer token-p1"},
body: `{"model": "unknown-model", "messages": [{"role": "user", "content": "hi"}]}`,
wantStatus: http.StatusBadRequest,
},
{
name: "responses unknown route",
method: http.MethodPost, path: "/v1/responses",
headers: map[string]string{"Authorization": "Bearer token-p1"},
body: `{"model": "unknown-model", "input": "hi"}`,
wantStatus: http.StatusBadRequest,
},
{
name: "anthropic messages unknown route",
method: http.MethodPost, path: "/v1/messages",
headers: map[string]string{"Authorization": "Bearer token-p1", "anthropic-version": "2023-06-01"},
body: `{"model": "unknown-model", "max_tokens": 10, "messages": [{"role": "user", "content": "hi"}]}`,
wantStatus: http.StatusBadRequest,
},
{
name: "anthropic count_tokens unknown route",
method: http.MethodPost, path: "/v1/messages/count_tokens",
headers: map[string]string{"Authorization": "Bearer token-p1", "anthropic-version": "2023-06-01"},
body: `{"model": "unknown-model", "messages": [{"role": "user", "content": "hi"}]}`,
wantStatus: http.StatusBadRequest,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
req := httptest.NewRequest(tc.method, tc.path, strings.NewReader(tc.body))
req.Header.Set("Content-Type", "application/json")
for k, v := range tc.headers {
req.Header.Set(k, v)
}
w := httptest.NewRecorder()
srv.routes().ServeHTTP(w, req)
if w.Code != tc.wantStatus {
t.Fatalf("status: got %d, want %d body: %s", w.Code, tc.wantStatus, w.Body.String())
}
})
}
}