kayx23 commented on code in PR #14168:
URL: https://github.com/apache/apisix/pull/14168#discussion_r4490583853


##########
CHANGELOG.md:
##########
@@ -87,6 +88,67 @@ title: Changelog
 - [0.7.0](#070)
 - [0.6.0](#060)
 
+## 3.20.0
+
+**The changes marked with :warning: are not backward compatible.**
+
+### Change
+
+- :warning: feat!: remove the `mcp-bridge` plugin, which was deprecated in 
3.18.0 with a note that it would be removed in a future release. A 
configuration that still lists `mcp-bridge` under `plugins` has to drop the 
entry, and `openapi-to-mcp` is the MCP plugin going forward 
[#14019](https://github.com/apache/apisix/pull/14019)
+- :warning: refactor(wolf-rbac): move `header_prefix` to the Route or Service 
configuration, where it defaults to `X-`, so a Route owns its identity headers 
and clears `{prefix}UserId`, `{prefix}Username` and `{prefix}Nickname` before 
any authenticator runs. Move a custom `header_prefix` from each Consumer to 
every Route or Service using `wolf-rbac` (including inside `multi-auth`) before 
upgrading, because a Consumer carrying one is now rejected; `appid` (now 
required), `server` and `ssl_verify` stay on the Consumer 
[#13929](https://github.com/apache/apisix/pull/13929)
+- :warning: fix(oas-validator): verify the TLS certificate of the `spec_url` 
host. `ssl_verify` now defaults to `true`, so an `https` spec served with a 
certificate outside the trust store fails the fetch and the route answers 500; 
set `ssl_verify: false` to keep the old behavior, which is now logged as an 
opt-out [#14146](https://github.com/apache/apisix/pull/14146)
+- :warning: fix(authz-keycloak): require every requested permission to be 
granted. The plugin asks Keycloak for `response_mode=permissions` and checks 
each requested resource and scope against the granted list, so a route listing 
several permissions, a permission with several scopes, or 
`http_method_as_scope` on a scoped permission answers 403 unless all of them 
are granted. Each permission is also sent as `resource#scope1,scope2`, which is 
the form Keycloak splits on 
[#14098](https://github.com/apache/apisix/pull/14098)
+- :warning: feat(openid-connect): upgrade `lua-resty-openidc` to 1.9.3 and 
`lua-resty-session` to 4.2.0, so an introspection failure is reported for what 
it is: a confirmed inactive token returns 401, an endpoint, transport or 
response failure returns 503, and a configuration failure returns 500. An 
introspection response whose `active` claim is missing or is not a boolean is 
now rejected as an invalid upstream response instead of being read as truthy 
[#14088](https://github.com/apache/apisix/pull/14088)
+- :warning: feat(prometheus): add `service` and `service_id` to all four 
stream metrics, so `apisix_stream_connection_total`, 
`apisix_stream_active_connections`, `apisix_stream_status` and 
`apisix_stream_bandwidth` gain two labels. Update PromQL selectors, recording 
rules, dashboards and alerts that match those series exactly; both labels are 
empty for a session that never reached a Stream Route with a Service, so 
summing over `service` reproduces the previous values 
[#13992](https://github.com/apache/apisix/pull/13992)
+- :warning: fix(cli): don't capture openresty stdout in `apisix start`. With 
`access_log: /dev/stdout`, `apisix start` used to block forever while 
swallowing the logs, and it now returns once openresty has daemonized. A 
container whose only command is `apisix start` therefore exits, and should run 
openresty in the foreground with `daemon off;`, the way the official image 
entrypoint does [#14087](https://github.com/apache/apisix/pull/14087)
+- :warning: fix: return 421 for SNI and Host mismatches on mTLS requests, so 
an HTTP/2 client that reused a connection opened for another origin can retry 
on a new connection with the target origin's SNI and client certificate. The 
mismatch check also moves ahead of the client certificate verification result; 
other verification failures keep returning 400 
[#14013](https://github.com/apache/apisix/pull/14013)
+- :warning: fix(router): forward the path the route was matched on whenever 
nginx normalized the request path, so the upstream receives the path the router 
matched rather than the raw request line. A request that differs from `$uri` 
only by percent-encoding or repeated slashes still forwards the original 
request line, and a plugin that sets `$upstream_uri` still takes precedence 
[#14035](https://github.com/apache/apisix/pull/14035)
+- :warning: fix(ssl): match `skip_mtls_uri_regex` against the encoded-slash 
route URI as well, so with `match_uri_encoded_slash: true` an exemption applies 
only when it matches both the decoded URI and the URI that keeps `%2F` inside a 
path segment. An exemption written for the decoded form alone stops applying to 
a path with an encoded slash; extend it to cover the encoded form to keep 
skipping the check [#14108](https://github.com/apache/apisix/pull/14108)
+- :warning: fix(jwe-decrypt, forward-auth): clear the forwarded headers on the 
paths that skip writing them, so `jwe-decrypt`'s `forward_header` on a `strict: 
false` route without a token, and `forward-auth`'s `upstream_headers` while the 
auth service is unavailable with `allow_degradation: true`, reach the upstream 
unset, the way the normal paths already handle a header they have no value for 
[#14096](https://github.com/apache/apisix/pull/14096)
+- :warning: fix(ai-prompt-guard): inspect embeddings string arrays. The 
strings of a batch input are joined and checked together, so `allow_patterns` 
applies to the combined text and a `deny_patterns` match rejects the batch. 
Token-ID arrays are left as they are, and a recognized request with no selected 
text keeps being processed [#14073](https://github.com/apache/apisix/pull/14073)
+- :warning: fix(openapi-to-mcp): tighten what a tool call can put into the 
upstream request. Tool arguments are filtered to the parameters the operation 
declares, so an undeclared header or query key is dropped; the Route's own 
`headers` are applied last and take precedence; and a header name or value that 
cannot appear in a request header is dropped with a warning 
[#13959](https://github.com/apache/apisix/pull/13959)
+  Path parameters are also confined to one path segment: a value containing 
`/` or `\` is rejected unless the Route sets `allow_encoded_path_separators: 
true`, and a filled path segment that resolves to an empty, `.` or `..` segment 
is rejected [#14154](https://github.com/apache/apisix/pull/14154)
+- :warning: perf(forward-auth): send the authorization request through 
`ngx_http_ffi_client`, which is now the default and is selected by 
`plugin_attr.forward-auth.http_client`. The auth service sees a `Connection` 
header, `Content-Length: 0` on a GET auth request and a different default 
`User-Agent`; set `http_client: lua-resty-http` to keep the previous exchange 
[#14144](https://github.com/apache/apisix/pull/14144)
+
+### Core
+
+- feat(core): make the readable request header count configurable through 
`apisix.max_request_headers_readable`, so plugins that read headers via 
`core.request.headers()`, such as `request-validation`, `opa` and 
`forward-auth`, can see past the first 100. The default stays `100`, and `0` 
reads every header [#14136](https://github.com/apache/apisix/pull/14136)
+- feat(kubernetes): select clusters explicitly with 
`discovery_args.cluster_ids`, so an upstream resolves 
`namespace/name:port_name` to the union of the matching endpoints of the listed 
clusters, cached per cluster endpoint version 
[#13991](https://github.com/apache/apisix/pull/13991)
+- feat(consul): support `https` consul server addresses. The scheme is picked 
per address, so one `servers` list can mix `http` and `https`, certificates are 
verified against `apisix.ssl.ssl_trusted_certificate` by default, and the new 
`discovery.consul.ssl_verify` turns verification off for https servers 
[#14018](https://github.com/apache/apisix/pull/14018)
+- chore: bump APISIX-Runtime to 1.4.2, which moves OpenResty to 1.31.8.1 
(nginx 1.31.8), OpenSSL to 3.5.9, apisix-nginx-module to 1.20.3 and 
ngx_multi_upstream_module to 1.4.1. This carries the nginx and OpenSSL security 
fixes released since nginx 1.29.2 and OpenSSL 3.4.1, restores the upstream 
keepalive wrapping order nginx 1.29.7 changed, fixes `gzip` compression when 
the plugin's `buffers.size` is below the page size, fixes 500s on multiplexed 
dubbo upstream connections, and adds the post-quantum hybrid group 
`X25519MLKEM768` to the default TLS 1.3 key shares 
[#14041](https://github.com/apache/apisix/pull/14041) 
[#14126](https://github.com/apache/apisix/pull/14126)
+- chore: bump brotli to 1.2.1 in the CI and dev image install scripts and in 
the `brotli` plugin build steps 
[#14138](https://github.com/apache/apisix/pull/14138)
+- fix(upstream): verify against `ssl_trusted_certificate` when only 
`tls.verify` is set. An upstream with `tls.verify: true` and no `tls.ca_certs` 
was verified against an empty trust store and failed with `unable to get local 
issuer certificate`; the runtime now loads `*_ssl_trusted_certificate` and the 
CRL into the upstream SSL context, and `grpc_ssl_trusted_certificate` is 
rendered so grpcs upstreams get the same trust anchors 
[#14113](https://github.com/apache/apisix/pull/14113)
+- fix(router): keep the query string when `normalize_uri_like_servlet` is on, 
where every proxied request reached the upstream with the path alone. This also 
fixes `proxy-mirror`, which reads the same variable 
[#13982](https://github.com/apache/apisix/pull/13982)
+- fix: preserve the `client-control` body limit for gRPC upstreams, where the 
redirect to `@grpc_pass` dropped the limit the plugin had set 
[#14036](https://github.com/apache/apisix/pull/14036)
+- fix: guard the node version helpers against a resource config that has 
already been deleted, which raised an attempt to index a nil value 
[#13986](https://github.com/apache/apisix/pull/13986)
+- fix(consul): run the catalog and health watchers as independent timers, so a 
watcher is never killed while reading a response body and a whole fetch round 
no longer fails with a bogus `resty.http` error when both indexes change 
together [#14032](https://github.com/apache/apisix/pull/14032)
+- fix(consul): upgrade `lua-resty-consul` to 0.4.0, whose connect puts the 
scheme, SNI and `ssl_verify` into the connection pool name, so a connection is 
reused only by a client configured with the same TLS options 
[#14118](https://github.com/apache/apisix/pull/14118)
+- fix(kubernetes): fail the whole list when a later endpoints page fails, so 
the informer re-lists instead of deleting the endpoints of the pages that never 
loaded and leaving those services on `no valid upstream node` until a restart 
[#14053](https://github.com/apache/apisix/pull/14053)
+- fix(nacos): keep the cached nodes of a service whose refresh failed, where 
its last successful snapshot was deleted as if the service had been removed 
from the configuration [#13971](https://github.com/apache/apisix/pull/13971)
+- fix(secret): report only identifiers when an `aws` or `vault` reference 
cannot be resolved, i.e. the AWS secret name and field and the vault path, so 
the provider's content stays out of `error.log`. A vault request rejected with 
403 no longer carries the response body in the error either 
[#14049](https://github.com/apache/apisix/pull/14049)
+
+### Plugins
+
+- feat: add the `request-decompress` plugin, which inflates a request body 
sent with `Content-Encoding: gzip` or `deflate`, so plugins that read the body, 
such as `oas-validator`, `request-validation`, `chaitin-waf` and 
`body-transformer`, see the plaintext. `core.request.get_body` gains an opt-in 
`opts.decompress`, and the configured size cap bounds the inflated data as well 
as the raw read [#14016](https://github.com/apache/apisix/pull/14016)
+- feat(openid-connect): map verified claims to upstream request headers 
through `upstream_headers`, a list of `{header, path}` mappings. Every declared 
header is reset on each outcome, so it carries the verified claim or nothing 
[#14030](https://github.com/apache/apisix/pull/14030)
+- feat(prometheus): export per-process timers, connection slots and Lua memory 
as `apisix_nginx_timers`, `apisix_nginx_timers_max`, 
`apisix_nginx_process_connections`, `apisix_nginx_process_connections_max` and 
`apisix_nginx_lua_memory_bytes`, so a worker or the privileged agent running 
out of any of them is visible before it turns into errors 
[#14034](https://github.com/apache/apisix/pull/14034)
+- feat(prometheus): configure the expired metric cleanup interval with 
`plugin_attr.prometheus.remove_expired_keys_interval`, default 3600 seconds, 
and upgrade `nginx-lua-prometheus-api7` to 1.1.0 
[#13981](https://github.com/apache/apisix/pull/13981)
+- feat(chaitin-waf): add `allow_degradation`, default `false`, so a request 
passes through when the WAF service is unavailable or its detection fails, 
instead of the service being a single point of failure 
[#13311](https://github.com/apache/apisix/pull/13311)
+- feat(limit-count): report the counting window in `$rate_limiting_info`, with 
the window type and size, the current window (and the previous window for a 
sliding window) in millisecond timestamps, the decision and the cost of the 
request. The four existing fields keep their names and values, and the variable 
is now encoded from a table, so the field order is no longer fixed 
[#13996](https://github.com/apache/apisix/pull/13996)
+- feat(ai-rate-limiting): expose nested usage fields to `cost_expr` under 
names that join the parent and child keys with `__`, for example 
`input_tokens_details__cached_tokens`. Top-level fields keep their plain names, 
so existing expressions behave the same 
[#13984](https://github.com/apache/apisix/pull/13984)
+- fix(limit-count): give each rule of a `rules` configuration its own 
delayed-sync queue, timer and limiter, where all rules shared one queue and 
synced their keys to Redis through whichever rule's `count` and `time_window` 
started the timer [#14064](https://github.com/apache/apisix/pull/14064)
+- fix(limit-count): flush a missing local delta as 0, so a node that only 
rejects keeps refreshing its cached quota instead of rejecting on a stale 
sliding-window weight for the rest of the window 
[#14015](https://github.com/apache/apisix/pull/14015)
+- fix(traffic-split): apply the `tls` and `keepalive_pool` of an inline 
`weighted_upstreams[].upstream`, which were both ignored, so a client 
certificate is sent, `tls.verify` and `tls.ca_certs` take effect, 
`tls.client_cert_id` resolves from that upstream, and the connection pool uses 
the configured settings [#14054](https://github.com/apache/apisix/pull/14054)
+- fix(csrf): validate the shape and the fields of the decoded token, so a 
malformed token is rejected with 401 instead of answering 500 
[#14025](https://github.com/apache/apisix/pull/14025)
+- fix(oas-validator): release a remote spec that no request has used for 
`spec_url_ttl` seconds, through the new `inactive` option of `core.lrucache`, 
so a route whose `spec_url` changes over time stops accumulating compiled specs 
in worker memory [#14061](https://github.com/apache/apisix/pull/14061)

Review Comment:
   No further changelog change needed. The current entry accurately states the 
user-visible memory result; the weak-key cache-lifetime detail is captured in 
the detailed release note. Resolving.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to