API7 Gateway 3.10.8: Upgrade Identity Without Breaking Trust Boundaries
October 19, 2026
Key Takeaways
- API7 Gateway 3.10.8, released on October 9, 2026, changes which OIDC, SAML, Feishu, and DingTalk identity responses are accepted.
- On routes that use remote introspection and configure
claim_validator.issuer.valid_issuers, an introspection response with a missing or disallowedissnow returnsHTTP 401before the request reaches the upstream. - SAML Auth now checks supplied audience, time, recipient, destination, and request-correlation constraints and reads identity only from assertions covered by a verified signature. Proxy-derived callback URLs and non-default audiences may need configuration before rollout.
- Optional SAML replay tracking is per gateway instance, not cluster-wide. If its shared dictionary is full, the login still succeeds without recording that assertion and the gateway logs an error.
- Feishu Auth and DingTalk Auth now bind browser callbacks to the session with
state; theX-Feishu-CodeandX-DingTalk-Codeintegration paths retain their previous handling. - Treat the upgrade as a set of identity contract tests. Validate both accepted and refused cases directly against each 3.10.8 Data Plane before removing old capacity.
An authentication flow can prove a signature or receive an active token and still accept the wrong context. The issuer may be outside the route's policy. A signed SAML assertion may target another audience or callback URL. An authorization code may return through a browser session that did not start the login.
API7 Gateway 3.10.8 makes several of those boundaries enforceable at runtime. That is an important security improvement, but it also changes upgrade behavior. A route that appeared healthy on 3.10.7 can begin returning HTTP 401, and a SAML deployment behind a TLS-terminating proxy can refuse every login if the gateway reconstructs a callback URL that differs from the identity provider's Recipient.
The safest rollout model is therefore not “upgrade and watch the sign-in rate.” It is to write explicit positive and negative tests for every affected identity contract, prepare configuration before the new Data Plane serves production traffic, and keep the limitations next to the protections they qualify.
flowchart LR
input[Token or Browser Response] --> gateway[API7 Gateway 3.10.8]
gateway --> mode{Identity Flow}
mode -->|OIDC introspection| issuer[Issuer Allowlist]
mode -->|SAML login| saml[Audience + Time + ACS + Request]
mode -->|Feishu or DingTalk| state[Browser Session State]
issuer -->|Pass| continue[Continue Intended Flow]
saml -->|Pass| continue
state -->|Pass| continue
issuer -->|Fail| stop[Stop Before Upstream or Authenticated Session]
saml -->|Fail| stop
state -->|Fail| stop
Authentication Success Is a Contract, Not a Status Code
Identity integrations combine several independent contracts:
- Artifact validity: the token, response, or assertion is structurally valid and carries an acceptable signature or introspection result.
- Issuer and audience: the artifact comes from an expected authority and is intended for this service provider or API.
- Endpoint and session binding: the callback names the public endpoint and, when the protocol message carries correlation data, answers the login initiated by this browser session.
- Time: the assertion is used inside its validity window, with only the configured clock tolerance.
- Replay scope: an accepted assertion is not reused inside the scope and retention period that the deployment actually records.
A green-path login proves only the combination that happened to run. It does not show how the gateway handles a missing issuer, an alternate audience, a rewritten host, a full replay dictionary, or an authorization code copied from another browser session.
The 3.10.8 changes are best understood as new or corrected decisions at those boundaries. They are not one generic “more secure authentication” switch, and their failure paths differ by plugin and mode.
OIDC Introspection Now Enforces the Issuer Policy
The OpenID Connect change has a narrow and important scope. It affects routes that configure both introspection_endpoint and claim_validator.issuer.valid_issuers.
On 3.10.7, the remote-introspection path did not apply that issuer allowlist. An introspection response could be active yet omit iss, or carry an issuer outside the configured list, and the request would still be forwarded upstream. On 3.10.8, the same response is rejected with HTTP 401 and:
WWW-Authenticate: Bearer realm="apisix", error="invalid_token", error_description="issuer validation failed"
The request does not reach the upstream. That timing matters: applications should not expect to receive and repair these requests, and operators should distinguish a gateway issuer refusal from an identity-provider outage or an upstream authorization decision.
Before rollout, inventory the routes in this affected configuration shape. For every configured issuer, capture a real introspection response and confirm that iss is present and exactly matches an allowed value. Use the controlled test setup below to compare otherwise valid responses with an allowed issuer, a disallowed issuer, and no iss; verify the issuer-specific failure rather than accepting any authentication error as a passing test.
Do not generalize this release item to every OIDC validation mode. The documented compatibility change is specifically the remote-introspection path with a configured issuer allowlist. Use the OpenID Connect plugin reference to review the rest of each route's validation and session configuration.
Pin the SAML Callback Before the Data Plane Rollout
SAML Auth changes more broadly. In 3.10.8, the Data Plane begins checking the constraints carried by a login response without requiring a new configuration switch:
- every
AudienceRestrictionmust namesp_issuer, or one of the values insp_audienceswhen that option is set; NotBeforeandNotOnOrAfterare enforced withclock_skew, which defaults to60seconds;- a subject confirmation's
Recipient, and the response'sDestinationwhen present, must name the assertion consumer service (ACS) URL; - when the response or signed assertion names an authentication request with
InResponseTo, it must be the request started by the same browser session; and - identity is read only from assertions covered by the verified signature.
The qualifiers are part of the behavior. The gateway enforces constraints that the identity provider supplies; it does not manufacture an omitted AudienceRestriction. The public SAML library used to document this behavior also accepts an assertion that omits InResponseTo, preserving compatibility but leaving that particular request-binding signal absent. A signature establishes where the signed content came from; the audience, time, recipient, and correlation checks establish whether that content is acceptable here and now.
The most likely availability failure is the ACS URL. Unless sp_acs_url is set, the gateway builds the URL from the callback request's scheme and host. Behind a load balancer or ingress that terminates TLS without setting X-Forwarded-Proto, or rewrites the host, the derived URL can differ from the public callback URL written by the identity provider. The stricter Data Plane then refuses the login.
Before upgrading a SAML route, compare all three values directly:
- the public callback URL configured at the identity provider;
- the URL the proxy presents to the gateway through scheme, host, and forwarding headers; and
- the effective
sp_acs_urlused by the plugin.
Set sp_acs_url to the public callback URL when the derived value is not stable. Set sp_audiences when the identity provider issues an audience other than sp_issuer, and keep gateway clocks synchronized. The SAML Auth documentation describes the response checks and configuration boundaries in detail.
Replay Tracking Is Useful, but It Is Not Cluster-Wide
API7 Gateway 3.10.8 also adds optional SAML replay tracking. Setting replay_dict records accepted assertions in an lua_shared_dict so the same gateway instance can refuse a recorded assertion when it is presented again. The gateway declares plugin-saml-auth-replay with 10 MiB for this purpose, and its size can be changed under nginx_config.http.lua_shared_dict.
The protection has three operational limits:
- It is per instance. Workers on one gateway share the dictionary, but other gateway replicas do not. A replay routed to a different instance does not find the first instance's record.
- Capacity failure does not fail the login. If the dictionary is full, the gateway logs an error and accepts the login without recording that assertion. Alerting on this error is part of the control.
- Retention is bounded. An assertion with no usable expiry is recorded for
replay_ttl, which defaults to600seconds. The implementation also caps unusually long assertion-derived retention unless the operator raises that bound.
Treat replay tracking as a bounded defense, not a claim that the cluster makes every SAML assertion globally single-use. Size the dictionary from peak accepted-login rate and assertion lifetime, test a repeated assertion on the same instance, and test the capacity alert. Keep browser-session request binding and identity-provider assertion lifetimes as separate controls.
An in-progress SAML login that crosses the instance upgrade is restarted rather than refused. Include that behavior in user communication and canary expectations; it is different from a permanent configuration mismatch.
Browser State Fixes Have a Documented Integration Boundary
In 3.10.7, Feishu Auth and DingTalk Auth did not bind an authorization code callback to the browser session that started the login. A code obtained elsewhere could be presented on another session.
In 3.10.8, the redirect to the identity provider carries a random state. A callback whose state is missing or does not match the session is rejected with HTTP 401 and:
{"message":"Invalid state"}
A browser login that is already in progress while its gateway instance is upgraded must start again. Test that as an expected transition instead of treating it as a regression.
The release notes also preserve a separate integration path: clients that obtain the authorization code themselves can pass it through X-Feishu-Code or X-DingTalk-Code, and that path is handled as before. The new browser state check must not be described as covering those header-supplied codes. Inventory browser redirects and header-code integrations separately, document who may call the latter, and test the authentication and network controls that protect it.
Turn the Upgrade Into an Identity Canary Matrix
Follow the API7 Gateway upgrade plan. Confirm the supported source-to-target path, rehearse the upgrade and rollback with production-like identity providers, and preserve a restore-tested, immutable source database backup. Record the acceptance criteria, abort thresholds, rollback owner, and rollback deadline before production changes begin.
Build negative cases in an isolated test deployment with a controlled IdP and introspection endpoint. Send bearer tokens to the gateway; let the test introspection endpoint return the chosen response. Use a different token for each case and confirm that the endpoint was actually called, so a cached result cannot mask the change. Keep all fields except the tested condition valid, including active set to true.
For each SAML case, start a fresh unauthenticated browser session, retain its pending-login cookie and RelayState, and obtain the generated authentication request ID. Have the test IdP construct the response and sign it with a key trusted by that test gateway after setting the field under test. Use a new assertion ID for every case except the deliberate replay test. Editing captured signed XML without signing it again tests signature rejection instead of the intended semantic check. Preserve valid binding encoding and all unrelated constraints.
| Contract | Controlled case | Required evidence |
|---|---|---|
| OIDC issuer | Return otherwise valid introspection responses with an allowed iss, a disallowed value, and no iss. | The allowed case reaches the test upstream. Both negative cases return HTTP 401 with issuer validation failed in WWW-Authenticate, and upstream logs show no delivery. |
| SAML acceptance | Issue a valid signed response for the pending request, public ACS URL, audience, and current validity window. | The callback establishes a session; using its returned cookies on the protected route reaches the test upstream, and the gateway authentication context identifies the expected test user. |
| SAML semantic checks | Independently issue correctly signed responses with a wrong audience, expired or not-yet-valid time beyond clock_skew, wrong Recipient, wrong Destination, or wrong InResponseTo. For a recipient or request-binding case, leave no alternative satisfiable subject confirmation. | Each case creates no authenticated session, and the gateway log names the tested constraint. A signature, missing-session, or RelayState error does not count as evidence for that constraint. |
| SAML replay | On the same isolated instance with replay_dict enabled, submit the identical signed assertion in two fresh pending logins, each with its own valid cookie and RelayState. Use a test-only fixture that omits InResponseTo from both the response and assertion to isolate replay from request binding. | The first login succeeds; the second returns HTTP 401 and logs has been presented already. Keep production IdP request binding unchanged. This test does not establish cross-instance protection. |
| Replay capacity | In a separate disposable test deployment, exhaust a deliberately small replay dictionary, then submit an otherwise valid, previously unseen assertion. | Login succeeds without recording that assertion, the capacity error is logged, and the monitoring alert fires. Do not exhaust production storage. |
| Feishu/DingTalk browser state | Start a fresh browser login for each case with a valid, unused authorization code; return matching, missing, or mismatched state without either header-code integration path. | Matching state completes login. Missing or mismatched state returns HTTP 401 with Invalid state. Separately test in-progress login restart across an upgrade and the unchanged header-code integrations. |
After the isolated tests pass, apply the Data Plane rolling-upgrade procedure:
- Inventory the affected route modes, public callback URLs, issuers, audiences, clocks, proxy forwarding behavior, replica counts, and replay settings. Rehearse required identity configuration changes in the target test deployment; coordinate their production application with the supported upgrade path. Do not distribute target-only settings to source Data Planes unless that procedure explicitly permits it.
- Keep production management writes frozen from the final source backup through acceptance or rollback, including writes from Dashboard, Admin API, ADC, and automation. Upgrade and validate the Control Plane first, then deploy a target Data Plane canary outside the production load balancer.
- Require the canary to report Healthy and Compatible with no compatibility errors. Run representative public and authenticated traffic directly against it, and route test traffic through the actual proxy path to verify the public ACS URL without admitting normal production traffic. Validate identity behavior, upstream delivery, logs, metrics, and capacity.
- Add each target node, wait for readiness and traffic checks, then put it in the load balancer and observe authentication errors, callback loops, latency, and upstream health. Drain a source node only after its target replacement passes validation. Repeat the add, validate, and drain sequence.
- Retain sufficient source capacity, source manifests, certificates, images, and the immutable backup to execute the agreed rollback until its deadline. If an abort threshold is reached, remove target nodes from the load balancer and follow the rollback plan; target-only configuration may require path-specific rollback before source nodes can serve traffic again.
- Record acceptance only after the required traffic checks and observation period pass. Resume writes after acceptance or completed rollback. Unreconciled writes end the backup-based rollback window; keeping that option through a later deadline requires a continued write freeze or tested reconciliation.
A test passes only when both its outcome and its reason match the intended control. A rollout passes when target capacity serves the expected identities, invalid contexts stop at their documented boundaries, and the agreed recovery path remains available through its deadline.
Upgrade Trust Boundaries Without Guessing
API7 Gateway 3.10.8 turns previously silent identity assumptions into runtime decisions. OIDC introspection must return an allowed issuer when the route asks for one. SAML assertions must satisfy the audience, time, endpoint, signature, and available request-correlation constraints that make them acceptable to this service provider. Browser callbacks from Feishu and DingTalk must return to the session that started the login.
None of those improvements removes the need to model the exact path. SAML replay storage remains per instance and can run out of room without blocking a login. An IdP that omits InResponseTo provides no request identifier for the gateway to compare. Header-supplied Feishu and DingTalk codes remain outside the new browser-state check.
Read the complete API7 Gateway 3.10.8 release notes, turn every applicable boundary into one passing and one failing canary, and upgrade only when the new Data Plane produces the decision your identity architecture expects.


