Skip to content

feat(proxy-cache): add consumer_isolation and cache_set_cookie options#13350

Merged
shreemaan-abhishek merged 2 commits into
apache:masterfrom
shreemaan-abhishek:feat/proxy-cache-consumer-isolation
May 14, 2026
Merged

feat(proxy-cache): add consumer_isolation and cache_set_cookie options#13350
shreemaan-abhishek merged 2 commits into
apache:masterfrom
shreemaan-abhishek:feat/proxy-cache-consumer-isolation

Conversation

@shreemaan-abhishek

Copy link
Copy Markdown
Contributor

Description

This PR adds two new options to the proxy-cache plugin and tightens how the in-memory cache strategy treats upstream Cache-Control response directives.

New options

  • consumer_isolation (boolean, default: true). When the request resolves to an APISIX consumer (ctx.consumer_name) or carries a remote user (ctx.var.remote_user), the identity is prepended to the effective cache key so each consumer gets its own cache namespace. The augmentation is skipped when the user-supplied cache_key already references an identity-bearing variable ($consumer_name, $consumer_group_id, $remote_user, or $http_authorization). Set to false for routes where consumers should share cached responses.
  • cache_set_cookie (boolean, default: false). The in-memory and on-disk strategies refuse to cache responses that include a Set-Cookie header unless explicitly opted in. Set-Cookie is per-recipient and not generally safe for a shared cache to store.

Behavior change

The in-memory strategy now always honors upstream Cache-Control: private, no-store, and no-cache directives, regardless of the existing cache_control flag. The cache_control flag continues to govern request-side semantics (client Cache-Control request directives such as max-age / min-fresh / only-if-cached) and TTL derivation from max-age / s-maxage. This matches the behavior of NGINX's native proxy_cache (used by the on-disk strategy) and brings the two strategies into closer agreement.

Backward compatibility

The new defaults change behavior in three ways for users who have proxy-cache enabled today:

  1. Routes that combine proxy-cache with an authentication plugin will start partitioning the cache by consumer. Existing cache entries become unreachable; new entries accumulate per consumer. Set consumer_isolation: false to opt out.
  2. The in-memory strategy will no longer cache responses that include Set-Cookie. Set cache_set_cookie: true to opt back in.
  3. The in-memory strategy will no longer cache responses whose upstream Cache-Control includes private, no-store, or no-cache, irrespective of the route-level cache_control flag.

Each is independent; users can mix and match opt-outs.

Which issue(s) this PR fixes:

N/A

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

- Add `consumer_isolation` (default: true). When an authenticated identity
  is present (`ctx.consumer_name` or `ctx.var.remote_user`), prepend it to
  the effective cache key so each consumer gets its own cache namespace.
  Skipped when the user-supplied `cache_key` already references an
  identity-bearing variable (`$consumer_name`, `$consumer_group_id`,
  `$remote_user`, or `$http_authorization`).
- Add `cache_set_cookie` (default: false). The in-memory and on-disk
  strategies refuse to cache responses that include a `Set-Cookie` header
  unless explicitly opted in.
- Always honor upstream `Cache-Control: private` / `no-store` / `no-cache`
  in the in-memory strategy, regardless of the existing `cache_control`
  flag, which continues to govern request-side semantics and TTL
  derivation from `max-age` / `s-maxage`.
@shreemaan-abhishek
shreemaan-abhishek marked this pull request as ready for review May 12, 2026 04:07
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels May 12, 2026
- Drop the Set-Cookie check in disk_handler. NGINX's native proxy_cache
  already refuses to cache responses that include a Set-Cookie header,
  so the Lua-level check was redundant.
- Document that `cache_set_cookie` only applies to the in-memory
  strategy (the on-disk strategy is governed by NGINX defaults and does
  not consult this flag).
- Rename TEST 37 to reflect that it covers Set-Cookie refusal on an
  authenticated route. The previous title also claimed per-consumer
  isolation, but the assertions could not distinguish that from
  Set-Cookie refusal.
- Add TEST 40 that exercises `consumer_isolation` directly: a cacheable
  upstream endpoint (no Set-Cookie, no Cache-Control: private) is
  fronted by an auth-protected route; two requests from the same
  consumer produce MISS then HIT, and a request from a second consumer
  produces MISS again, proving that the cache key is partitioned by
  identity.
- Add nil/error checks to TEST 38 and TEST 39 so that a request failure
  surfaces a clear message instead of a nil dereference.
Comment thread apisix/plugins/proxy-cache/init.lua
Comment thread apisix/plugins/proxy-cache/memory_handler.lua
@shreemaan-abhishek
shreemaan-abhishek merged commit c7b5618 into apache:master May 14, 2026
34 checks passed
@shreemaan-abhishek shreemaan-abhishek mentioned this pull request Jun 10, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants