solo enterprise agentgateway · llm plane

One control plane for every model call.

On goose, clients never hold provider keys. AgentGateway is the LLM gateway for every model path — OpenAI, xAI, Anthropic, local DGX — injects secrets, prices tokens from a model catalog, enforces budgets, attributes spend with virtual keys, and emits traces.

agentgateway-proxy + dedicated gateways catalog · budgets · virtual keys openai · xai · claude · dgx · gpt-5.6 · bedrock P2C LB · priority failover

#What AgentGateway does (LLM)

Features exercised in this lab — not a product brochure, the actual CRDs and scripts on goose.

FeatureWhat it doesHow goose uses it
Multi-provider LLM gateway One control plane fronts all LLM providers — cloud and local — with path-based routing, path rewrite, and upstream auth injection. Clients talk to AgentGateway; the gateway speaks each provider’s API (OpenAI, Anthropic, OpenAI-shaped local vLLM, etc.). Dedicated routes/gateways: /openai, /grok, /spark, /anthropic, /gemini, /gpt56, /bedrock (+ budget / virtual-key variants)
Per-provider backends One AgentgatewayBackend (or dedicated Gateway) per provider/model family — not a single “OpenAI-only” hop. OpenAI · xAI · Anthropic · Gemini · DGX Spark (vLLM) · gpt-5.6 gateway · AWS Bedrock
Secret isolation Real API keys live in K8s Secrets (Vault → ESO); clients send no key. openai-secret, xai-secret, anthropic-secret, gemini-secret, bedrock-secret, …
Model cost catalog Per-1M-token USD rates; gateway sets agw.ai.usage.cost.total. model-cost-catalog ConfigMap on parameters
Budgets (USD / tokens) EnterpriseAgentgatewayBudget with Audit or Block + rolling window. /budget-demo trip-to-429 path
Virtual API keys Per-tenant keys + metadata; Strict auth; dimensions on spans. /vk-openai · goose-virtual-keys
Cost hierarchy organization → costCenter → group → user from key metadata / CEL. Solo UI Cost Management · Scope by hierarchy
Tracing & rollups OTel spans → ClickHouse platformdb + Langfuse project. Cost charts, recent traffic, Langfuse
Content guardrails Request/response filters (lab: “batman” guards on some routes). gpt55-batman-guard, qwen-batman-guard
kagent ModelConfigs Agents call in-cluster gateway URLs; throwaway client keys only. default · xai-grok · dgx-spark · gpt-5-6 · aws-bedrock

#Deployed config & policy

Everything below is in the k8s-goose repo and applied by ArgoCD (agentgateway-config + control-plane Helm). Pick an item to see kind, path, and open the file on GitHub.

GitOps path

Edit the YAML in git → push main → Argo self-heals. Live cluster name is usually agentgateway-system/<metadata.name> (UI cost shims live in gloo-system).

#Architecture

Clients and kagent hit NodePorts / in-cluster services. Gateways price and forward; control plane programs XDS; telemetry lands in ClickHouse for Cost Management.

request path · pricing · cost attribution

#Budgets & Cost Management

How goose wires EnterpriseAgentgatewayBudget, virtual keys, multi-provider spend, and the Solo UI Budgets tab (Within vs Exceeding). Manifests live under config/ · full markdown: docs/budgets.md.

Can one budget mix OpenAI + xAI + DGX?

Yes. Budgets are not bound to a single LLM provider. A request counts toward a budget when it (1) hits a route with entBudgetEnforcement and (2) matches the budget subject (or the entry has no subject). provider and model are built-in dimensions — you can scope a budget to one provider, or leave provider out so team spend mixes every enforced backend.

Budget subjectWhat accumulates
group: platform only All providers on enforced routes for that team (OpenAI + xAI + DGX if those routes enforce + emit the same group).
provider: openai OpenAI only
provider: xai or model match Grok path only
(no subject) Every request on every route that attaches that Budget CR
Goose lab today

Team budgets only enforce on /vk-openai (OpenAI). Grok (/grok) and Qwen/DGX (/spark) are priced by the cost catalog (Qwen = $0.15 / $0.25 per 1M) and show on spend dashboards, but they do not increment team-budget-* until those routes also get virtual-key auth + entBudgetEnforcement (or a shared policy). Pricing and budgeting are separate knobs.

ProviderPathPriced (catalog)Team budget enforced?
OpenAI gpt-5.5 /vk-openai Yes Yesopenai-vk-cost + team-budget-*
OpenAI gpt-5.5 /openai Yes No (kagent / open lab)
xAI Grok /grok Yes No (not yet on VK path)
DGX Qwen /spark Yes — $0.15 in / $0.25 out per 1M No (not yet on VK path)
OpenAI /budget-demo Yes Separate Block demo only (ns budget-demo)

Paths & named team budgets

PathAuthBudget CRsPurpose
/budget-demo None (lab) budget-demo/budget-demo Hard Block 429 (2k tokens/day). No virtual keys.
/vk-openai Strict virtual key team-budget-platform · team-budget-sales · team-budget-marketing (+ cost-hierarchy) Three named team budgets in the UI · Within / Exceeding demo.
/openai · /grok · /spark None Priced by catalog; no team budget enforcement yet.
Why budget-demo lives in its own namespace

entBudgetEnforcement discovers budgets in the namespaces it is told to watch. A subject-less budget matches every request on any enforcing route. The old demo-token-block (2000 tokens, Block) in agentgateway-system was 429’ing multi-team VK traffic. Fix: Budget CR lives in ns budget-demo; enforcement uses discovery.namespaces.from: Selector + label goose.maniak.ai/budget-ns=budget-demo. /vk-openai uses from: Same → only team-budget-* + hierarchy.

discovery isolation · three team CRs on /vk-openai

GitOps manifests

FileWhat it deploys
config/policies/budget-demo.yaml Namespace budget-demo + Budget ($5 Audit, 2k tokens Block) + enforcement policy targeting HTTPRoute budget-demo with NS selector.
config/routes/budget-demo-route.yaml HTTPRoute /budget-demo → OpenAI backend on agentgateway-proxy.
config/policies/team-budget-demo.yaml 3 CRs: team-budget-platform, team-budget-sales, team-budget-marketing (team group + one tight user each, Audit tokens/day).
config/policies/cost-hierarchy-budgets.yaml Smaller hierarchy examples (org solo-io, group sales, user alice).
config/policies/model-cost-catalog.yaml Per-1M USD rates for all providers (OpenAI, xAI, Anthropic, DGX Qwen $0.15/$0.25).
config/policies/openai-vk-cost.yaml On /vk-openai: virtual-key auth + entBudgetEnforcement (Same ns).
config/routes/openai-vk-route.yaml HTTPRoute /vk-openai → same OpenAI backend (kagent path untouched).
config/secrets/goose-virtual-keys.yaml 12 keys × 2 namespaces (agentgateway-system for gateway, gloo-system for UI tab).
config/ui-cost-shim/agentgateway-enterprise-budget-dimensions.yaml Hierarchy for UI: organization → costCenter → group → user (+ virtualKey attribute).
scripts/test-budget-teams.sh Burns traffic per persona so some budgets exceed and some stay within.
scripts/test-cost-vk.sh Lighter VK smoke (subset of keys) for hierarchy / dimensions checks.

Three named team budgets (UI list)

Each is a separate EnterpriseAgentgatewayBudget so Solo UI shows three rows. Subjects use virtual-key metadata after Strict auth (apiKey.group / apiKey.user).

Budget CRTeam limitUsers (keys)After full burn
team-budget-platform group=platform · 500 tokens/day (+ alice 200) alice, bob, chris · sk-goose-platform-* Exceeding
team-budget-sales group=sales · 450 tokens/day (+ dave 180) dave, erin, frank · sk-goose-sales-* Exceeding
team-budget-marketing group=marketing · 400 tokens/day (+ grace 160) grace, heidi, ivan · sk-goose-marketing-* Exceeding

All Audit + rolling Day (UI can show Exceeding without 429). Org solo-io on every key.

Authorization
Authorization: Bearer sk-goose-sales-dave
Authorization: Bearer sk-goose-marketing-grace
Authorization: Bearer sk-goose-platform-alice

Run the multi-team demo

  1. Clear live counters (optional but clean)./scripts/reset-budget-demo.sh
  2. Burn traffic./scripts/test-budget-teams.sh · light / status
  3. Open Solo UIHTTPS https://172.16.10.155:30443 (Entra) → AgentGatewayCost ManagementBudgets
  4. Open each team CRteam-budget-platform · team-budget-sales · team-budget-marketing — chips Within / Exceeding
  5. Optional hierarchyDashboard Scope by hierarchy: org → cost center → group → user · spend by model still shows OpenAI / xAI / Qwen from all routes
scripts/test-budget-teams.sh + reset
./scripts/reset-budget-demo.sh          # flush Redis budget counters
./scripts/test-budget-teams.sh status
./scripts/test-budget-teams.sh          # full burn → all 3 teams Exceeding

# single team request (counts toward team-budget-sales)
curl -sS http://172.16.10.155:30160/vk-openai/v1/chat/completions \
  -H "Authorization: Bearer sk-goose-sales-dave" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-5.5","max_tokens":120,"messages":[{"role":"user","content":"budget demo"}]}'

Hard Block demo (/budget-demo)

Separate from teams. No virtual key. After ~2000 tokens in the rolling day window, gateway returns HTTP 429 (onBudgetExceeded: Block).

trip block
for i in 1 2 3 4 5 6 7 8; do
  curl -sS -o /tmp/bd.json -w "try $i → HTTP %{http_code}\n" \
    -X POST http://172.16.10.155:30160/budget-demo/v1/chat/completions \
    -H 'Content-Type: application/json' \
    -d '{"model":"gpt-5.5","max_tokens":200,"messages":[{"role":"user","content":"Write two paragraphs about geese."}]}'
done

Troubleshooting

SymptomFix
All VK calls return 429 / want empty usage bars ./scripts/reset-budget-demo.sh (flush Redis + restart rate-limiter/proxy). Subject-less Block should only live in ns budget-demo.
UI shows 0 budgets / no usage Traffic must hit a route with entBudgetEnforcement (/vk-openai). Wait 15–30s; set time range to 24h. Confirm virtual key (not bare /openai).
401 on /vk-openai Wrong/missing Bearer key, or Secret not loaded — check goose-virtual-keys has 12 data keys; restart proxy after Secret replace.
Exceeding never flips Limits are rolling Day windows and Audit. Run test-budget-teams.sh full; heavy users need enough total tokens (input+output). Raise burn or lower limits in the CR.
Hierarchy empty Dimensions ConfigMap in gloo-system + controller ns; spans need CustomDimensions (VK path + enforcement).
Markdown reference

Same content in-repo: docs/budgets.md. Config picker above lists each file under Configs.

#Test scenarios

From the k8s-goose repo root, on a host that can reach 172.16.10.155. No client API keys. Full budget design is in Budgets.

1 · Multi-provider chat smoke

routing · secrets
What AgentGateway proves

Six providers / models through AgentGateway. One lab, many backends — upstream keys never leave the cluster.

  1. Open a shell in the repoWorker NodePorts must be reachable
  2. Run all LLM smokes./scripts/test-llm-gateways.sh all
  3. Or hit one provider./scripts/test-mcp-security.sh openai (wrapper) or … gpt56|xai|claude|gemini|dgx
run
./scripts/test-llm-gateways.sh all

# single provider
./scripts/test-llm-gateways.sh openai
./scripts/test-llm-gateways.sh xai
./scripts/test-llm-gateways.sh claude
./scripts/test-llm-gateways.sh gemini
./scripts/test-llm-gateways.sh dgx
./scripts/test-llm-gateways.sh gpt56
expected output (abbreviated)
✓ openai   gpt-5.5          HTTP 200  · pong
✓ gpt56    gpt-5.6          HTTP 200
✓ xai      grok-4.5         HTTP 200
✓ claude   claude-fable-5   HTTP 200
✓ gemini   gemini-2.5-flash HTTP 200
✓ dgx      Qwen3.6-35B      HTTP 200  (local)
1b

Load balance + failover

resilience

Prove multi-provider P2C balancing and priority-group failover on agentgateway-proxy.

  1. LB smoke./scripts/test-llm-lb-failover.sh lb — models from OpenAI and xAI
  2. Healthy primary./scripts/test-llm-lb-failover.sh failover — stay on gpt-5.5
  3. Force walk tiers./scripts/test-llm-lb-failover.sh failover-force — gpt → grok → claude
presenter
./scripts/test-llm-lb-failover.sh all
./scripts/test-llm-lb-failover.sh failover-force   # optional deeper demo

2 · Budget enforcement (trip a 429)

budgets · block
What AgentGateway proves

Separate route /budget-demo shares the OpenAI backend but attaches entBudgetEnforcement + a tiny token budget that Blocks. kagent’s /openai stays safe.

  1. Send a few chat completions to the budget routeSame model as /openai, different HTTPRoute
  2. Watch admission fail when the rolling token window is exceededProxy logs: budget exceeded; blocking… outcome=over_limit_block
curl · /budget-demo
# repeat until 429 (demo-token-block = 2000 tokens / day rolling)
for i in 1 2 3 4 5 6 7 8; do
  curl -sS -o /tmp/bd.json -w "try $i → HTTP %{http_code}\n" \
    -X POST http://172.16.10.155:30160/budget-demo/v1/chat/completions \
    -H 'Content-Type: application/json' \
    -d '{"model":"gpt-5.5","max_tokens":200,"messages":[{"role":"user","content":"Write two paragraphs about geese."}]}'
done
cat /tmp/bd.json | head -c 200; echo
expected
try 1 → HTTP 200
try 2 → HTTP 200
…
try N → HTTP 429
# body mentions budget / rate limit; proxy log budget_action=BLOCK

3 · Multi-team budgets (12 users · 5 teams)

budgets · within vs exceeding
What AgentGateway proves

Team (group) and per-user budgets on the same virtual-key path. After traffic, Solo UI Budgets shows usage bars and Within budget vs Exceeding budget counts.

Budget CRUsersTeam limit / dayAfter full run
team-budget-platformalice, bob, chris500EXCEED
team-budget-salesdave, erin, frank450EXCEED
team-budget-marketinggrace, heidi, ivan400EXCEED

Tight user budgets also trip: alice (250), dave (200), grace (180), ivan (220).

  1. Ensure budgets + keys are syncedteam-budget-platform|sales|marketing · goose-virtual-keys
  2. Burn demo traffic./scripts/reset-budget-demo.sh && ./scripts/test-budget-teams.sh
  3. Open Solo UI → Cost Management → BudgetsOpen each of the three team-budget-* CRs · Within vs Exceeding
multi-team budget run
./scripts/test-budget-teams.sh status
./scripts/test-budget-teams.sh          # full burn
# UI: https://172.16.10.155:30443 → AgentGateway → Cost Management → Budgets
expected UI
team-budget-platform    → Exceeding
team-budget-sales       → Exceeding
team-budget-marketing   → Exceeding
# OpenAI /vk-openai only today; xAI + DGX priced but not team-enforced yet
# see #budgets multi-provider section

4 · Virtual keys + cost hierarchy

virtual keys · cost mgmt
What AgentGateway proves

Strict API-key auth on /vk-openai loads metadata (organization, costCenter, group, user) into CEL as apiKey.*, emits agw.llm.custom_dimensions, and feeds Solo UI Scope by hierarchy.

virtual key → dimensions → ClickHouse → UI

sk-goose-platform-alice org=solo-io · group=platform /vk-openai apiKeyAuth + budget custom_dimensions org / cc / group / user Cost Management UI Scope by hierarchy
  1. Generate traffic for every seeded persona./scripts/test-cost-vk.sh all
  2. Open Solo UI Cost Management (24h range)HTTPS UI :30443 · Entra login · AgentGateway → Cost Management
  3. Use Scope by hierarchysolo-io / engineering / platform / alice · sales · acme-corp partners…
virtual key traffic
./scripts/test-cost-vk.sh all

# one persona (3 calls)
./scripts/test-cost-vk.sh platform-alice

# manual
curl -sS http://172.16.10.155:30160/vk-openai/v1/chat/completions \
  -H "Authorization: Bearer sk-goose-platform-alice" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-5.5","max_tokens":16,"messages":[{"role":"user","content":"hi"}]}'
expected · ClickHouse custom_dimensions (sample)
CostUsd 0.00057
CustomDimensions {
  organization: solo-io,
  costCenter:   engineering,
  group:        platform,
  user:         alice,
  virtualKey:   vk-platform-alice,
  provider:     openai,
  model:        gpt-5.5
}
Personas (12 keys · see Budgets)

sk-goose-platform-{alice,bob,chris} · sk-goose-sales-{dave,erin,frank} · sk-goose-research-{grace,heidi} · sk-goose-ops-{ivan,judy} · sk-goose-support-{karen,leo} — full table in Budgets. Prefer ./scripts/test-budget-teams.sh for the UI demo.

5 · Confirm live pricing on /openai

cost catalog
What AgentGateway proves

Even without a virtual key, the catalog prices the response. Proxy access logs show agw.ai.usage.cost.total=…; ClickHouse agw_spans_typed.CostUsd > 0 after the cost MV fix.

  1. Send one unauthenticated chat to /openai
  2. Optional: tail proxy logs for agw.ai.usage.cost.total
priced request
curl -sS http://172.16.10.155:30160/openai/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"gpt-5.5","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}'

kubectl --context maniak-goose -n agentgateway-system logs deploy/agentgateway-proxy --tail=5 \
  | grep -o 'agw.ai.usage.cost.total=[^ ]*'
expected log snippet
gen_ai.request.model=gpt-5.5
gen_ai.usage.input_tokens=11
gen_ai.usage.output_tokens=16
agw.ai.usage.cost.total=0.000535

6 · AWS Bedrock (single provider · LB · failover)

bedrock · resilience
What AgentGateway proves

A dedicated aws-bedrock-gateway fronts AWS Bedrock (region us-east-2) with a long-term Bedrock API key (bearer token)not SigV4 / AWS access keys. Clients send plain OpenAI-compatible JSON, no AWS creds. Same P2C load balancing and priority failover patterns, all Bedrock models.

  1. Single-provider smoke./scripts/test-bedrock.sh — Claude Sonnet 4.5 via /bedrock
  2. LB distribution./scripts/test-bedrock-lb.sh — Nova Pro / Nova Lite / Llama 3.3 70B on /bedrock-lb
  3. Priority walk./scripts/test-bedrock-failover.sh failover-force — Sonnet 4.5 → Nova Pro → Llama
run
./scripts/test-bedrock.sh
./scripts/test-bedrock-lb.sh
./scripts/test-bedrock-failover.sh              # stay on Sonnet 4.5 while healthy
./scripts/test-bedrock-failover.sh failover-force
./scripts/test-bedrock-failover.sh restore

# single call (resolve the NodePort dynamically — currently 30275)
curl -sS http://172.16.10.155:30160/bedrock/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"us.anthropic.claude-sonnet-4-5-20250929-v1:0","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}'
expected output (abbreviated)
✓ bedrock       claude-sonnet-4-5   HTTP 200  · pong
✓ bedrock-lb    nova-pro / nova-lite / llama3-3-70b  HTTP 200
✓ bedrock-failover  Sonnet 4.5 → Nova Pro → Llama 3.3 70B

#Load balancing & model failover

Multi-provider resilience on one path. Same Solo patterns as the docs: P2C load balancing and priority-group failover.

/llm-lb

P2C load balancing

One priority group: OpenAI gpt-5.5 + xAI grok-4.5. Gateway scores health / latency / pending and picks the better of two random candidates — not round-robin.

POST :30160/llm-lb/v1/chat/completions

/llm-failover

Priority failover

Groups in order: gpt-5.5grok-4.5claude-fable-5. Health policy (5xx / 429) evicts; empty group fails over. Within a group, P2C still applies.

POST :30160/llm-failover/v1/chat/completions

/bedrock-lb

Bedrock P2C load balancing

One priority group, all AWS Bedrock: Nova Pro + Nova Lite + Llama 3.3 70B. P2C picks the better of two random candidates; all three share the one Bedrock bearer key.

POST :30160/bedrock-lb/v1/chat/completions

/bedrock-failover

Bedrock priority failover

Groups in order: Claude Sonnet 4.5Nova ProLlama 3.3 70B. Health policy bedrock-failover-health (5xx / 429) evicts 15s; empty group fails over.

POST :30160/bedrock-failover/v1/chat/completions

narrated harness
./scripts/test-llm-lb-failover.sh              # LB + healthy primary
./scripts/test-llm-lb-failover.sh lb           # 8× /llm-lb — watch model field
./scripts/test-llm-lb-failover.sh failover     # stay on gpt-5.5 while healthy
./scripts/test-llm-lb-failover.sh failover-force  # force walk tiers (temp policy)
./scripts/test-llm-lb-failover.sh restore      # production health again

# AWS Bedrock LB + failover (own scripts)
./scripts/test-bedrock-lb.sh                   # P2C across Nova Pro / Nova Lite / Llama 3.3
./scripts/test-bedrock-failover.sh             # stay on Sonnet 4.5 while healthy
./scripts/test-bedrock-failover.sh failover-force  # walk Sonnet → Nova Pro → Llama
./scripts/test-bedrock-failover.sh restore     # production health again
Config

config/backends/llm-lb.yaml · config/backends/llm-failover.yaml · config/routes/llm-lb-route.yaml · config/routes/llm-failover-route.yaml · config/policies/llm-failover-health.yaml · config/backends/bedrock-lb.yaml · config/backends/bedrock-failover.yaml · config/routes/bedrock-lb-route.yaml · config/routes/bedrock-failover-route.yaml · config/policies/bedrock-failover-health.yaml

#Workshop-gap flows Mermaid

Phases A / B / E from the FE enterprise workshop, on dedicated paths (open /openai stays free for kagent). Suite: ./scripts/test-workshop-phases.sh a|b|e · full catalog in docs/flows.md.

A · Guardrails

/guard-demo
  1. Clean prompt → 200
  2. Injection / jailbreak → 403
  3. PII / secrets → 422
sequence · promptGuard
sequenceDiagram
  participant U as Client
  participant G as AGW /guard-demo
  participant O as OpenAI
  U->>G: clean prompt
  G->>O: forward
  O-->>U: 200
  U->>G: ignore previous instructions
  G-->>U: 403 injection
  U->>G: email or API key in prompt
  G-->>U: 422 PII or secret
run
./scripts/test-guardrails.sh

B · Body-based model routing

/route-by-model
  1. PreRouting reads JSON model
  2. Header match selects backend
  3. Missing model → mock fallback
flowchart · body.model → backend
flowchart TB
  C[Client POST /route-by-model] --> PR[PreRouting extract body.model]
  PR --> H{x-gateway-model-name}
  H -->|gpt-5.5| O[openai]
  H -->|grok-4.5| X[xai-grok]
  H -->|gemini-2.5-flash| Ge[google-gemini]
  H -->|mock-gpt or missing| M[mock-gpt]
run
./scripts/test-body-routing.sh
./scripts/test-llm-token-ratelimit.sh

E · Entra JWT on LLM

/secure-openai
  1. Anonymous → 401
  2. az mint token same app as MCP
  3. Bearer → chat 200
sequence · Entra + LLM
sequenceDiagram
  participant U as Client
  participant G as AGW /secure-openai
  participant E as Entra JWKS
  participant O as OpenAI
  U->>G: no Authorization
  G-->>U: 401
  U->>G: Bearer Entra JWT
  G->>E: validate iss/aud
  G->>O: chat/completions
  O-->>U: 200
run
./scripts/test-llm-jwt-entra.sh
./scripts/test-waf.sh

A · Enrichment · stream · embeddings

policy + APIs
enrichment injects system prompt
sequenceDiagram
  participant U as Client
  participant G as AGW /enrich-demo
  participant O as OpenAI
  Note over G: prepend system JSON contract
  U->>G: What is 2+2?
  G->>O: system + user
  O-->>U: answer + source marker
run
./scripts/test-prompt-enrichment.sh
./scripts/test-llm-stream.sh
./scripts/test-embeddings.sh

#Endpoints cheat-sheet

PathPortModelNotes
/openai30160gpt-5.5kagent default; open in lab
/vk-openai30160gpt-5.5Strict virtual keys + hierarchy
/budget-demo30160gpt-5.5Budget block demo
/llm-lb30160gpt-5.5 + grokP2C load balance
/llm-failover30160gpt-5.5→grok→claudepriority failover
/guard-demo30160gpt-5.5built-in promptGuard
/enrich-demo30160gpt-5.5prompt enrichment
/embeddings30160text-embedding-3-smallPassthrough embeddings
/route-by-model30160by body.modelbody-based routing
/token-rl30160gpt-5.5local token rate limit
/secure-openai30160gpt-5.5Entra JWT Strict
/waf-demo30160gpt-5.5WAF injection first-pass
/grok31397grok-4.5xai-grok-gateway · catalog $2/$6 per 1M
/spark31944Qwen3.6-35BDGX local
/anthropic30398claude-fable-5anthropic-claude-gateway
/gemini32637gemini-2.5-flashgoogle-gemini-gateway · Vault agentgateway/Gemini
/gpt5630536gpt-5.6dedicated gateway
/bedrock30275*claude-sonnet-4-5aws-bedrock-gateway · us-east-2 · bearer API key (*resolve NodePort)
/bedrock-lb30160nova-pro + nova-lite + llama3-3-70bBedrock P2C load balance
/bedrock-failover30160sonnet-4-5→nova-pro→llama3-3-70bBedrock priority failover
Related

MCP tool security (Entra JWT, tool RBAC, rate limits) lives on the MCP gateway page — same product, different data plane path.