Docs

AISIX 0.10.0

This release is about agent traffic.

Release date: August 20, 2026

This release is about agent traffic. Forward-proxy traffic — an IDE or coding agent pointed at the gateway — is now carried by an explicit route resource you can audit instead of an implicit tunnel that guessed which credential to borrow. MCP gains the 2026-07-28 revision of the protocol, anonymous access for clients that carry no credential, OAuth 2.1 discovery, and a single coherent rule for which tools a caller may reach. Model groups gain consistent hashing and priority tiers. The gateway keeps serving through a drain window instead of refusing connections a load balancer has not yet stopped sending, and traces exported over OTLP form a real hierarchy.

Behavior Changes

  • The implicit passthrough tunnel is replaced by explicit routes. /passthrough/<provider>/<rest> no longer resolves by provider name; an unclaimed /passthrough/* path answers 410 Gone with endpoint_removed and logs a warning naming the caller, so un-migrated clients are findable. To migrate, create a passthrough route with path_prefix: /passthrough/<provider>, target_url set to the old API base, and provider_key_id set to the key it used to borrow — client URLs then keep working byte for byte. Two behaviors differ from the old tunnel: a route is a single-attempt relay, so upstream 5xx and transport retries are gone, and because a route resolves no model, model cooldown is no longer cross-marked from this traffic. Access is an explicit grant on the caller key (allowed_routes); a key without one reaches no route.
  • MCP tool access is now one rule across three layers. The environment policy, the caller's team policy, and the key's own mcp_access block each carry allow and deny lists. Allow lists intersect and deny lists combine, so no layer can widen what another restricts; a layer that is not set imposes no constraint, and a caller with no layer at all has no MCP access. mode is gone from both policies and keys, allowed_tools is gone from the key — the key's layer is mcp_access.allow — and the legacy-key migration flow is removed. If you have configured MCP tool policies, re-check them after upgrading: the resulting access is recomputed under these rules and can differ from what the old settings produced. Two changes matter most: a team policy now narrows the environment grant instead of replacing it, so it can no longer grant a tool the environment does not; and a key with no mcp_access block now follows the policy layers instead of standing outside them. allow is required on every layer, so a layer that only means to subtract must spell its allow side ["*"].
  • A guardrail that blocks an MCP tool call now answers as a tool error. The call returns success at the protocol level with isError: true on the result and a message naming the guardrail — never the matched content — instead of a JSON-RPC -32600. A calling agent sees the refusal as tool output it can adapt to, rather than a broken transport. A client matching on error.code == -32600 must read result.isError instead.
  • The weighted routing strategy and the sticky flag are gone. Weight is now a per-target attribute available under every strategy: round_robin is smooth weighted round robin, so equal or absent weights reproduce the previous declaration-order cycle exactly and unequal weights hold exact proportions. Session affinity is now its own strategy, consistent_hash. Deployments managed through AISIX Cloud are migrated automatically. Declarative configurations must be updated: weighted becomes round_robin with weights kept, and weighted with sticky becomes consistent_hash. A stored configuration still naming weighted fails to load rather than changing meaning silently. Cohort assignments reshuffle once when moving to consistent hashing, since it builds its ring differently.
  • An unsupported MCP protocol version is now refused inside the JSON-RPC envelope. A request whose MCP-Protocol-Version header names a revision the endpoint does not serve gets 400 with a JSON-RPC error carrying the supported list, instead of a bare text/plain response outside every gateway envelope. The endpoint serves 2025-03-26, 2025-06-18, 2025-11-25 and 2026-07-28; it no longer advertises 2024-11-05, which only existed for the HTTP+SSE transport.
  • Traces exported over OTLP now form a hierarchy. A model request that reaches an upstream produces an HTTP SERVER span, a logical client span covering every retry and failover, and one child span per upstream attempt, replacing one flat span per usage event. An exported request trace with no upstream dispatch has only the SERVER span; protocols without per-attempt tracking have the SERVER span and one client span. Anything keyed on "one span per request" — span-count alerts, name-based counts — will see structural spans appear. The attempt span carries the full attribute set and is identifiable by aisix.attempt_index; structural spans carry a smaller correlation attribute set that includes aisix.request_id, and the SERVER span is span kind 2. Separately, the caller's traceparent and tracestate are no longer forwarded to model providers; an operator's explicit default_headers entry for a trusted upstream still works.
  • Text-to-speech latency is now measured to the first byte. /v1/audio/speech streams the synthesized audio as it arrives instead of buffering it, so a player can start on the first bytes and the reported latency is time to first byte rather than time to last byte. This is the convention every other streaming surface here already follows.

New Features

  • Passthrough routes. A route binds a gateway entry — a path prefix, an inbound Host allowlist, or both — to one upstream target, so an IDE or coding agent can be pointed at the gateway and have its traffic audited without changing the client. Host matching runs before routing, so forward-proxy traffic delivered with its original Host can claim a path the gateway also uses; path matching runs as the router's fallback, so a route can never shadow the gateway's own API. Callers authenticate with a gateway key, with the key in a header you name so Authorization stays free for the upstream credential, or anonymously as a bound principal gated by a source-CIDR allowlist. The upstream credential is either injected from a provider key or forwarded from the caller after the route removes its gateway credential and fixed header set. An optional device-injected identity header is recorded as the request's end-user identity for per-employee attribution. The request envelope is detected per request — chat, Responses, completions, or opaque — and drives guardrail text extraction, audit capture and token accounting; traffic that is not an LLM call records no phantom tokens. SSE responses relay incrementally. See Passthrough Routes and Forward Proxy for IDE AI Traffic.
  • Consistent hashing and priority tiers for model groups. strategy: consistent_hash pins each session to one target by hashing a request key over a ring of targets: the same key keeps landing on the same target, weights scale each target's share, and when a target fails only its own sessions move to their ring successors — every other key keeps its mapping. The key comes from a source chain you configure (hash_on: a header, a cookie, the caller's API key, or the client IP), defaulting to the routing-key header falling back to the API key. Independently, every target takes a priority: targets partition into tiers, higher is preferred, and a lower tier only receives traffic once every target above it has failed or been taken out by health tracking — so a backup pool can sit idle behind an active one and a request that discovers a fully dead tier still succeeds by spilling within itself.
  • MCP 2026-07-28. /mcp and /mcp/{server} serve the final revision of the specification, including the handshake-free discovery lifecycle and the stateless transport. A registered MCP server takes an optional protocol_version to pin the revision the gateway uses to open its upstream session, which is the only way to reach a server that no longer answers the older handshake; omitted, the gateway keeps negotiating as before, so existing configurations are unchanged. Selection is explicit in both directions — the gateway never probes or silently falls back, so a mismatch fails visibly instead of quietly negotiating something you ruled out.
  • Anonymous MCP access. An environment can let MCP clients that present no credential reach chosen entries, running as an API key you nominate — that key's tool grant, rate limits, budget and usage attribution all apply. It is gated by a mandatory source-CIDR allowlist, names the entries it opens, and treats the aggregate /mcp entry as opt-in. A client that does present a credential is still authenticated normally; an invalid one is rejected rather than served anonymously.
  • OAuth 2.1 resource-server discovery for /mcp. With a canonical resource URL configured and an identity provider enabled, the gateway publishes protected-resource metadata and answers unauthenticated MCP requests with a WWW-Authenticate challenge pointing at it, so a standard MCP client can discover where to get a token. Bearer tokens must carry that URL in their audience.
  • Guardrails can be scoped to one MCP server, so a rule can guard a single registered server instead of all MCP traffic in the environment. Guardrails now also scan a tool's structured output, not only its text blocks.
  • A drain window on shutdown. On SIGTERM the gateway reports itself not-ready immediately, then keeps accepting new connections for at least shutdown.min_drain_secs (default 30s) before closing its listener, so connections a load balancer routes inside its own detection window are still served. HTTP/1.1 responses carry Connection: close during the window so pooling clients retire connections as they use them. The window is a minimum, not a deadline: the listener closes only once it has elapsed and nothing is in flight.
  • W3C trace context is now honored. A valid inbound traceparent makes the gateway's spans children of the caller's trace; a malformed or duplicated header is ignored in favor of a local root rather than failing the request. Span and trace ids are minted once per request, so a delivery retry re-sends byte-identical ids instead of fresh ones. Usage events carry the trace id for correlation.
  • Streamed audio transcription is relayed live. /v1/audio/transcriptions with stream=true now forwards frames as they arrive instead of answering from a fully read body, while still recording the request's token usage. A blocking or masking output guardrail keeps the buffered path, since it must see the whole transcript before any of it reaches the caller.
  • Role management in the Cloud Admin API. Custom role CRUD, organization-role assignment, and environment-scoped role bindings are now part of the published API contract, with generated bindings and request validation.

Improvements

  • Release images are now built with profile-guided optimization, and the allocator runs a background purge thread that returns freed memory to the operating system after load subsides.
  • Strict validation now names the offending setting when it rejects configuration a model kind never reads, instead of reporting only that the document failed.
  • Passthrough traffic records every usage dimension its detected envelope carries.

Fixes

  • Streamed audio transcription was billed as free. The gateway's SSE decoder ended an event only on a bare line-feed pair, while providers frame transcription streams with carriage returns, so the terminal event carrying the token counts was never decoded and every streamed transcription recorded zero tokens. Events now end on any pair of line terminators. The decoder is shared by every streaming bridge, so any upstream framing with carriage returns was affected, not only audio.
  • Caller API keys whose MCP access was written before the layered rule keep loading rather than being dropped.
  • The deployment and fallback counters are now emitted; pre-dispatch failures no longer count toward them, and failed requests are attributed to the caller that was resolved.
  • Passthrough traffic is attributed correctly in traces and on rejected-request events, and a 401 from header-based authentication names the header it expected.
  • Forward-proxy routes matched on host may claim path prefixes the gateway reserves, and mirror the whole request path.
  • Audio metadata parsing no longer logs warnings about ordinary uploads.
  • In the Dashboard: the create-model picker no longer reads as "unsupported," the Dimensions field is no longer mislabelled optional, route transitions show a loading boundary, and the MCP authentication settings live on the MCP Access page with the rest of the MCP configuration.

Upgrade Notes

  • Upgrade the control plane first, then your gateways. This is the supported order, and the mixed-version window can be as long as you need. While it lasts, a gateway still on 0.9.x will stop serving a model group that used weighted with sticky (its migrated configuration names a strategy that release does not know) and will not apply MCP tool policies (their stored shape changed). Caller API keys keep authenticating throughout — their MCP access is simply off on the older gateway until it is upgraded. Both are visible in the Dashboard's data-plane compatibility view.
  • Deployments managed through AISIX Cloud migrate stored routing configurations automatically on the first control-plane start after the upgrade. Declarative configurations are not migrated and must be updated by hand, as described under Behavior Changes.