Skip to content

feat(ai-rate-limiting): support redis policy for shared counters#13670

Open
shreemaan-abhishek wants to merge 2 commits into
apache:masterfrom
shreemaan-abhishek:feat/ai-rate-limiting-redis
Open

feat(ai-rate-limiting): support redis policy for shared counters#13670
shreemaan-abhishek wants to merge 2 commits into
apache:masterfrom
shreemaan-abhishek:feat/ai-rate-limiting-redis

Conversation

@shreemaan-abhishek

Copy link
Copy Markdown
Contributor

Description

The ai-rate-limiting Plugin currently keeps token counters only in per-worker shared memory (policy = "local"). In a multi-node deployment the counters are not shared across nodes, so the effective quota scales with the number of gateway nodes and over-allows.

This PR adds a Redis-based counter policy to the Plugin, reusing the existing limit-count Redis backends, so counters can be centralized and a single quota is enforced across all nodes.

Changes:

  • Export policy_to_additional_properties from apisix/plugins/limit-count/init.lua so the Plugin can reuse the shared Redis schema branches.
  • Add policy (local / redis / redis-cluster / redis-sentinel) and allow_degradation schema fields, plus the Redis attribute wiring in transform_limit_conf.
  • Document the new attributes and add a Redis example to docs/en/latest/plugins/ai-rate-limiting.md.
  • Add schema-validation and Redis rate-limiting test cases.

The default remains local, so existing configurations are unaffected.

Which issue(s) this PR fixes:

Fixes #

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)

…licy

By default the plugin keeps token counters in per-worker shared memory,
so in a multi-node deployment counters are not shared and the effective
quota scales with the node count. Add a redis-based policy path (reusing
limit-count's redis backends) to centralize counters across nodes.

- export policy_to_additional_properties from limit-count/init.lua
- add policy + allow_degradation schema fields and redis attr wiring
- document the new attributes and a redis example
- add schema and redis rate-limiting tests
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Jul 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the ai-rate-limiting plugin to support Redis-backed counter policies (reusing limit-count’s Redis backends) so token quotas can be enforced consistently across multiple APISIX nodes instead of per-worker local memory.

Changes:

  • Reuses limit-count Redis schema branches by exporting policy_to_additional_properties.
  • Adds policy / allow_degradation and Redis config wiring to ai-rate-limiting (plus schema validation).
  • Updates plugin documentation and adds Redis-focused test coverage.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
t/plugin/ai-rate-limiting.t Adds schema validation and Redis policy integration tests for shared counters.
docs/en/latest/plugins/ai-rate-limiting.md Documents new policy/Redis configuration options and provides a Redis example.
apisix/plugins/limit-count/init.lua Exposes Redis policy schema branches for reuse by other plugins.
apisix/plugins/ai-rate-limiting.lua Adds policy fields + conditional Redis schema and transforms config to use Redis backends.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +163 to 170
["else"] = {
["if"] = {
properties = { policy = { enum = { "redis-sentinel" } } },
},
["then"] = policy_to_additional_properties["redis-sentinel"],
},
},
}
Comment on lines +277 to 287
elseif plugin_conf.policy == "redis-sentinel" then
limit_conf.redis_sentinels = plugin_conf.redis_sentinels
limit_conf.redis_master_name = plugin_conf.redis_master_name
limit_conf.sentinel_username = plugin_conf.sentinel_username
limit_conf.sentinel_password = plugin_conf.sentinel_password
limit_conf.redis_role = plugin_conf.redis_role
limit_conf.redis_connect_timeout = plugin_conf.redis_connect_timeout
limit_conf.redis_read_timeout = plugin_conf.redis_read_timeout
limit_conf.redis_keepalive_timeout = plugin_conf.redis_keepalive_timeout
limit_conf.redis_database = plugin_conf.redis_database
end
Comment thread t/plugin/ai-rate-limiting.t
@membphis

membphis commented Jul 8, 2026

Copy link
Copy Markdown
Member

I think this should be fixed before merge.

ai-rate-limiting now exposes Redis credential fields by reusing the limit-count Redis schemas, but its own plugin schema does not declare those fields in encrypt_fields. APISIX config encryption is driven by each plugin schema's encrypt_fields, so redis_password / sentinel_password would be stored as plain plugin config here, while comparable plugins such as limit-count, limit-req, and ai-cache encrypt Redis passwords.

There is also a sentinel wiring gap: the schema accepts Redis master credentials for redis-sentinel, and the backend uses redis_username / redis_password for the Redis master connection, but transform_limit_conf only forwards the sentinel credentials and does not pass redis_username / redis_password in the sentinel branch. A valid sentinel config with Redis master auth can pass validation but fail at runtime.

Suggested fix: add encrypt_fields = {"redis_password", "sentinel_password"} to the ai-rate-limiting schema, forward redis_username / redis_password for redis-sentinel, and add coverage for encrypted Redis credentials plus sentinel master auth.

… master auth

- declare encrypt_fields for redis_password / sentinel_password so the
  credentials are encrypted at rest, matching limit-count / limit-req
- forward redis_username / redis_password in the redis-sentinel branch so
  a Redis master with ACL/requirepass can be authenticated
- add sentinel master-auth schema coverage and a redis_password encryption test
@shreemaan-abhishek

Copy link
Copy Markdown
Contributor Author

Thanks @membphis, good catches. Fixed in the latest commit:

  • Added `encrypt_fields = {"redis_password", "sentinel_password"}` to the plugin schema so the Redis credentials are encrypted at rest, matching `limit-count` / `limit-req`.
  • Forwarded `redis_username` / `redis_password` in the `redis-sentinel` branch of `transform_limit_conf` so a Redis master with ACL/requirepass can be authenticated.
  • Added a schema test for a sentinel config with Redis master auth, and a test asserting `redis_password` is encrypted at rest.

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.

3 participants