Skip to content

Expose Management API rate limit info via a client callback - #774

Open
ProdigyTom wants to merge 11 commits into
auth0:masterfrom
ProdigyTom:feat/expose-rate-limit-data
Open

ProdigyTom wants to merge 11 commits into
auth0:masterfrom
ProdigyTom:feat/expose-rate-limit-data

Conversation

@ProdigyTom

@ProdigyTom ProdigyTom commented Jul 27, 2026 •

Copy link
Copy Markdown

Changes

Exposes Auth0's rate-limit information (x-ratelimit-limit / -remaining / -reset) from every Management and Authentication API response, via an opt-in handler, so callers can monitor how close they are to the limit (the ask in #606).

  • Auth0::Internal::Http::RateLimit — value object (limit, remaining as Integers; reset as a UTC Time). Blank/non-numeric header values become nil (never a misleading 0). Two builders: from_http_response (Management/RawClient, Net::HTTP) and from_headers (Authentication/HTTPProxy, RestClient).
  • rate_limit_handler option on Auth0::Client, invoked with the parsed RateLimit after every response on both API paths.
  • Every response is reported, including the 429s that trigger an automatic retry, so a handler watching remaining sees the point where it ran out.
  • Non-breaking: the return value of API calls is unchanged. A handler error is caught and warned (so broken monitoring is visible) but never breaks a request.
  • Management wiring attaches the handler to the generated client's raw client and raises if it can't (so a future internals change fails loudly rather than silently disabling the feature).
  • All changes live in fernignored files (lib/auth0/internal/**, lib/auth0/mixins/**, lib/auth0/auth_client.rb), so they survive regeneration.
  • README + EXAMPLES documentation and unit tests (value object, retried-request notification, token-rebuild re-attach, Authentication path, client wiring).
client = Auth0::Client.new(
  domain: ENV["AUTH0_DOMAIN"],
  client_id: ENV["AUTH0_CLIENT_ID"],
  client_secret: ENV["AUTH0_CLIENT_SECRET"],
  rate_limit_handler: ->(rl) { StatsD.gauge("auth0.rate_limit.remaining", rl.remaining) if rl.remaining }
)
client.users.get(id: "auth0|123") # handler fires with the response's rate limit

References

Testing

Unit tests under test/unit/ cover header parsing (symbol/dashed/mixed-case keys, 0 vs blank/non-numeric, reset + whitespace), notification on every response across a retried request, the handler error being swallowed, the Authentication-API path, and the client wiring (including re-attach after a token-triggered rebuild). Full rake test passes locally with no failures.

  • This change adds unit test coverage
  • This change adds integration test coverage
  • This change has been tested on the latest version of Ruby

Checklist

  • I have read the Auth0 general contribution guidelines
  • I have read the Auth0 Code of Conduct
  • All existing and new tests complete without errors
  • Rubocop passes on all added/modified files
  • All active GitHub checks have passed

@ProdigyTom
ProdigyTom requested a review from a team as a code owner July 27, 2026 18:57
@kishore7snehil

Copy link
Copy Markdown
Contributor

@ProdigyTom I can see some merge conflicts. Can you please resolve them? Post that I can take a look

@ProdigyTom
ProdigyTom force-pushed the feat/expose-rate-limit-data branch from 1943366 to f119645 Compare September 2, 2026 13:39
@ProdigyTom ProdigyTom changed the title Expose rate limit data via optional block on API responses Expose Management API rate limit info via a client callback Sep 2, 2026
@ProdigyTom

Copy link
Copy Markdown
Author

@kishore7snehil my original change was against v5 and after the change to v6 I wasn't really able to resolve my merge conflicts in a way that still solved our problem. The rate limiting information gets dropped earlier in some generated code. So I wound up going a slightly different direction. let me know if it makes sense

Exposes Auth0's rate limit info (x-ratelimit-limit / -remaining / -reset) from
every Management API response via an opt-in callback, so callers can monitor how
close they are to the limit (per auth0#606).

- Add Auth0::Internal::Http::RateLimit (limit/remaining/reset; blank and
  non-numeric header values become nil rather than 0)
- RawClient gains a rate_limit_handler, invoked in #send after retries on every
  response; handler errors are swallowed so they can't break a request. #send's
  return value is unchanged, so generated callers are unaffected.
- Wire it through the custom client: Auth0::Client.new(management_rate_limit_handler:)
  attaches the handler to the management raw client
- Unit tests for RateLimit, RawClient#send handler behavior, and client wiring

All changes live in fernignored files, so they survive regeneration. Refs auth0#606.
@ProdigyTom
ProdigyTom force-pushed the feat/expose-rate-limit-data branch from f119645 to df19130 Compare September 23, 2026 20:35
Comment thread lib/auth0/auth_client.rb
Comment thread lib/auth0/internal/http/raw_client.rb Outdated
Comment thread lib/auth0/internal/http/raw_client.rb Outdated
Comment thread test/unit/internal/http/test_raw_client.rb Outdated
Comment thread test/unit/test_auth_client_rate_limit.rb Outdated
Comment thread lib/auth0/internal/http/rate_limit.rb Outdated
Comment thread test/unit/internal/http/test_rate_limit.rb Outdated
Comment thread test/unit/internal/http/test_rate_limit.rb Outdated
Comment thread lib/auth0/mixins/initializer.rb Outdated
Comment thread lib/auth0/mixins/initializer.rb Outdated
ProdigyTom and others added 3 commits October 5, 2026 09:46
- Notify on every response (inside the retry loop) so intermediate 429s reach
  the handler, not just the final response
- Fail loud if the handler can't be attached to the management raw client
  (raise) instead of silently no-opping if internals drift
- Warn (but still swallow) when a handler raises, so broken monitoring is visible
- Extend support to the Authentication API path (HTTPProxy), via a single
  rate_limit_handler option covering both APIs
- RateLimit gains from_http_response (Net::HTTP) and from_headers (RestClient)
  builders; reset/whitespace parsing pinned
- Tests: retried-request notification, token-rebuild re-attach, case-insensitive
  header lookup, reset garbage/whitespace, Authentication-path handler
- Docs: README options row + Rate Limit Monitoring section, EXAMPLES snippet
Auth0::Unsupported is part of the HTTP error family; a failure to attach the
rate limit handler is a configuration/internals issue, not an HTTP failure, so
a plain Auth0::Exception is a better fit.
Comment thread lib/auth0/auth_client.rb Outdated
Comment thread test/unit/test_auth_client_rate_limit.rb
Comment thread test/unit/mixins/test_httpproxy_rate_limit.rb Outdated
Comment thread test/unit/internal/http/test_raw_client.rb Outdated
Comment thread lib/auth0/mixins/httpproxy.rb Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread test/unit/mixins/test_httpproxy_rate_limit.rb Outdated
Comment thread test/unit/mixins/test_httpproxy_rate_limit.rb Outdated
Comment thread test/unit/internal/http/test_rate_limit.rb
kishore7snehil and others added 6 commits October 14, 2026 16:05
- Validate rate_limit_handler responds to #call at build time (fail once up
  front instead of warning on every response)
- Extract RateLimit.deliver so header parsing happens outside the handler
  rescue (a parsing bug is no longer misattributed to the handler) and the
  notify logic/comment is no longer duplicated across the two HTTP paths
- Stop advertising the internal RateLimit class in docs; document the contract
  (responds to #limit/#remaining/#reset) instead
- Note the handler is Auth0::Client-only and that validate_id_token's JWKS
  fetch is not reported; give Rate Limit Monitoring its own EXAMPLES section
- Docs/style: trim comments, split run-on sentences, add @raise/@param/@return,
  shorten the README options row, unbold mid-sentence text
- Tests: Authentication path now uses webmock with a real response; add
  from_headers(nil), RateLimit.deliver, and non-callable-handler cases; move
  the proxy test out of test/unit/mixins into test/unit
- Attach the handler before caching the management client, so a failed attach
  doesn't leave a handler-less management cached (next call re-attempts)
- Guard the Authentication-path notify against a nil response (call returns nil
  on e.g. a dropped connection)
- Split a remaining semicolon-joined sentence in the README
- Tests: cover the incompatible-raw-client raise and the no-cache-on-failure
  behavior; add Authentication-path retry (429s) and handler-raises cases;
  assert the warning (and stop leaking "boom" into test output)
Matches the reviewer's suggestion and names the actual failure mode (call
returns nil for some errors) rather than a broader respond_to? guard.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants