auth0 6.5.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.fern/metadata.json +3 -3
  3. data/.fern/replay.lock +10 -52
  4. data/.version +1 -1
  5. data/CHANGELOG.md +8 -0
  6. data/EXAMPLES.md +20 -0
  7. data/README.md +18 -0
  8. data/examples/ruby-api/Gemfile.lock +1 -1
  9. data/lib/auth0/attack_protection/brute_force_protection/types/update_brute_force_settings_request_content.rb +2 -2
  10. data/lib/auth0/attack_protection/client.rb +0 -5
  11. data/lib/auth0/auth_client.rb +27 -2
  12. data/lib/auth0/client.rb +15 -2
  13. data/lib/auth0/clients/client.rb +3 -0
  14. data/lib/auth0/clients/types/create_client_request_content.rb +2 -0
  15. data/lib/auth0/clients/types/list_clients_request_parameters.rb +2 -0
  16. data/lib/auth0/clients/types/update_client_request_content.rb +2 -0
  17. data/lib/auth0/connections/keys/client.rb +5 -5
  18. data/lib/auth0/experimentation/experiments/client.rb +2 -1
  19. data/lib/auth0/experimentation/experiments/types/create_experiment_request_content.rb +1 -1
  20. data/lib/auth0/experimentation/segments/client.rb +4 -1
  21. data/lib/auth0/experimentation/segments/types/list_segments_request_parameters.rb +2 -0
  22. data/lib/auth0/internal/http/rate_limit.rb +103 -0
  23. data/lib/auth0/internal/http/raw_client.rb +14 -2
  24. data/lib/auth0/mixins/httpproxy.rb +9 -1
  25. data/lib/auth0/mixins/initializer.rb +5 -0
  26. data/lib/auth0/portals/client.rb +198 -0
  27. data/lib/auth0/portals/types/create_portal_request_content.rb +21 -0
  28. data/lib/auth0/portals/types/update_portal_request_content.rb +23 -0
  29. data/lib/auth0/resource_servers/types/create_resource_server_request_content.rb +4 -0
  30. data/lib/auth0/resource_servers/types/update_resource_server_request_content.rb +4 -0
  31. data/lib/auth0/types/client.rb +4 -0
  32. data/lib/auth0/types/client_oidc_support.rb +14 -0
  33. data/lib/auth0/types/client_profile_client_configuration.rb +2 -0
  34. data/lib/auth0/types/client_profile_client_configuration_oidc_support.rb +10 -0
  35. data/lib/auth0/types/client_profile_client_configuration_oidc_support_allowed_scopes_enum.rb +14 -0
  36. data/lib/auth0/types/client_profile_client_configuration_oidc_support_default_value.rb +14 -0
  37. data/lib/auth0/types/client_search_response.rb +4 -0
  38. data/lib/auth0/types/{list_attack_protection_captcha_policies_response_content.rb → connection_client_id_samlxaa_requesting_app.rb} +2 -2
  39. data/lib/auth0/types/connection_client_secret_samlxaa_requesting_app.rb +23 -0
  40. data/lib/auth0/types/connection_options_auth0.rb +2 -0
  41. data/lib/auth0/types/connection_options_saml.rb +10 -0
  42. data/lib/auth0/types/connection_otp_channel_settings.rb +12 -0
  43. data/lib/auth0/types/connection_otp_settings.rb +12 -0
  44. data/lib/auth0/types/connection_properties_options.rb +2 -0
  45. data/lib/auth0/types/connection_response_content_saml.rb +2 -0
  46. data/lib/auth0/types/consent_signing_key.rb +15 -0
  47. data/lib/auth0/types/create_client_response_content.rb +4 -0
  48. data/lib/auth0/types/create_connection_request_content_saml.rb +2 -0
  49. data/lib/auth0/types/create_resource_server_response_content.rb +4 -0
  50. data/lib/auth0/types/event_stream_cloud_event_context.rb +2 -0
  51. data/lib/auth0/types/event_stream_cloud_event_context_transaction.rb +30 -0
  52. data/lib/auth0/types/event_stream_cloud_event_context_transaction_protocol_enum.rb +24 -0
  53. data/lib/auth0/types/event_stream_cloud_event_context_transaction_response_mode_enum.rb +14 -0
  54. data/lib/auth0/types/event_stream_cloud_event_context_transaction_response_type_item_enum.rb +13 -0
  55. data/lib/auth0/types/get_brute_force_settings_response_content.rb +2 -2
  56. data/lib/auth0/types/get_client_response_content.rb +4 -0
  57. data/lib/auth0/types/get_resource_server_response_content.rb +4 -0
  58. data/lib/auth0/types/guardian_factor_name_enum.rb +1 -0
  59. data/lib/auth0/types/internal_server_error_body.rb +13 -0
  60. data/lib/auth0/types/internal_server_error_body_error.rb +11 -0
  61. data/lib/auth0/types/list_portals_response_content.rb +9 -0
  62. data/lib/auth0/types/list_user_consent_signing_keys_response_content.rb +9 -0
  63. data/lib/auth0/types/oauth_scope.rb +4 -0
  64. data/lib/auth0/types/page_component.rb +33 -0
  65. data/lib/auth0/types/page_component_auth0form.rb +9 -0
  66. data/lib/auth0/types/page_component_auth0form_config.rb +11 -0
  67. data/lib/auth0/types/page_component_auth0media_image.rb +9 -0
  68. data/lib/auth0/types/page_component_auth0media_image_config.rb +13 -0
  69. data/lib/auth0/types/page_component_auth0my_account_mfa_management.rb +9 -0
  70. data/lib/auth0/types/page_component_auth0my_account_mfa_management_config.rb +7 -0
  71. data/lib/auth0/types/page_component_auth0my_account_passkey_management.rb +9 -0
  72. data/lib/auth0/types/page_component_auth0my_account_passkey_management_config.rb +7 -0
  73. data/lib/auth0/types/page_component_auth0my_organization_details_edit.rb +9 -0
  74. data/lib/auth0/types/page_component_auth0my_organization_details_edit_config.rb +7 -0
  75. data/lib/auth0/types/page_component_auth0my_organization_domain_table.rb +9 -0
  76. data/lib/auth0/types/page_component_auth0my_organization_domain_table_config.rb +7 -0
  77. data/lib/auth0/types/page_component_auth0my_organization_member_management.rb +9 -0
  78. data/lib/auth0/types/page_component_auth0my_organization_member_management_config.rb +7 -0
  79. data/lib/auth0/types/page_component_auth0structure_section.rb +9 -0
  80. data/lib/auth0/types/page_component_auth0structure_section_config.rb +15 -0
  81. data/lib/auth0/types/page_component_auth0structure_section_variant_enum.rb +12 -0
  82. data/lib/auth0/types/page_component_auth0structure_separator.rb +9 -0
  83. data/lib/auth0/types/page_component_auth0structure_separator_config.rb +11 -0
  84. data/lib/auth0/types/page_component_auth0structure_separator_variant_enum.rb +13 -0
  85. data/lib/auth0/types/page_component_auth0typography_heading.rb +9 -0
  86. data/lib/auth0/types/page_component_auth0typography_heading_config.rb +11 -0
  87. data/lib/auth0/types/page_component_auth0typography_rich_text.rb +9 -0
  88. data/lib/auth0/types/page_component_auth0typography_rich_text_config.rb +9 -0
  89. data/lib/auth0/types/page_component_no_children.rb +31 -0
  90. data/lib/auth0/types/page_slug.rb +23 -0
  91. data/lib/auth0/types/portal.rb +25 -0
  92. data/lib/auth0/types/portal_client_secret_post.rb +11 -0
  93. data/lib/auth0/types/portal_client_secret_post_request.rb +13 -0
  94. data/lib/auth0/types/portal_client_secret_post_request_token_endpoint_auth_method.rb +11 -0
  95. data/lib/auth0/types/portal_client_secret_post_token_endpoint_auth_method.rb +11 -0
  96. data/lib/auth0/types/portal_custom_code.rb +9 -0
  97. data/lib/auth0/types/portal_custom_code_nullable.rb +23 -0
  98. data/lib/auth0/types/portal_date_time.rb +23 -0
  99. data/lib/auth0/types/portal_id.rb +23 -0
  100. data/lib/auth0/types/portal_name.rb +23 -0
  101. data/lib/auth0/types/portal_navigation.rb +9 -0
  102. data/lib/auth0/types/portal_navigation_nullable.rb +23 -0
  103. data/lib/auth0/types/portal_page.rb +13 -0
  104. data/lib/auth0/types/portal_pages_by_type.rb +11 -0
  105. data/lib/auth0/types/portal_pages_by_type_nullable.rb +23 -0
  106. data/lib/auth0/types/portal_slug.rb +23 -0
  107. data/lib/auth0/types/portal_summary.rb +17 -0
  108. data/lib/auth0/types/position.rb +13 -0
  109. data/lib/auth0/types/resource_server.rb +4 -0
  110. data/lib/auth0/types/resource_server_agent_subject_claims_response_enum.rb +12 -0
  111. data/lib/auth0/types/resource_server_agent_subject_claims_schema_enum.rb +12 -0
  112. data/lib/auth0/types/resource_server_search_response.rb +4 -0
  113. data/lib/auth0/types/resource_server_type_enum.rb +11 -0
  114. data/lib/auth0/types/rotate_client_secret_response_content.rb +4 -0
  115. data/lib/auth0/types/sidebar.rb +9 -0
  116. data/lib/auth0/types/sidebar_component.rb +19 -0
  117. data/lib/auth0/types/sidebar_component_auth0external_link.rb +10 -0
  118. data/lib/auth0/types/sidebar_component_auth0external_link_config.rb +13 -0
  119. data/lib/auth0/types/sidebar_component_auth0external_link_v2.rb +9 -0
  120. data/lib/auth0/types/sidebar_component_auth0external_link_v2config.rb +13 -0
  121. data/lib/auth0/types/sidebar_component_auth0internal_link.rb +10 -0
  122. data/lib/auth0/types/sidebar_component_auth0internal_link_config.rb +13 -0
  123. data/lib/auth0/types/sidebar_component_auth0internal_link_v2.rb +9 -0
  124. data/lib/auth0/types/sidebar_component_auth0internal_link_v2config.rb +13 -0
  125. data/lib/auth0/types/update_brute_force_settings_response_content.rb +2 -2
  126. data/lib/auth0/types/update_client_response_content.rb +4 -0
  127. data/lib/auth0/types/update_connection_options.rb +2 -0
  128. data/lib/auth0/types/update_connection_request_content_saml.rb +2 -0
  129. data/lib/auth0/types/update_resource_server_response_content.rb +4 -0
  130. data/lib/auth0/types/update_variation_overrides_map.rb +1 -1
  131. data/lib/auth0/users/client.rb +120 -0
  132. data/lib/auth0/version.rb +1 -1
  133. data/lib/auth0.rb +79 -22
  134. data/wiremock/wiremock-mappings.json +308 -188
  135. metadata +81 -23
  136. data/lib/auth0/attack_protection/captcha_policies/client.rb +0 -210
  137. data/lib/auth0/attack_protection/captcha_policies/types/create_attack_protection_captcha_policy_request_content.rb +0 -21
  138. data/lib/auth0/attack_protection/captcha_policies/types/update_attack_protection_captcha_policy_request_content.rb +0 -23
  139. data/lib/auth0/types/attack_protection_captcha_policy.rb +0 -24
  140. data/lib/auth0/types/attack_protection_captcha_policy_action.rb +0 -24
  141. data/lib/auth0/types/attack_protection_captcha_policy_action_input.rb +0 -24
  142. data/lib/auth0/types/attack_protection_captcha_policy_match.rb +0 -12
  143. data/lib/auth0/types/captcha_active_provider_enum.rb +0 -17
  144. data/lib/auth0/types/captcha_policy_action_arkose.rb +0 -16
  145. data/lib/auth0/types/captcha_policy_action_arkose_input.rb +0 -18
  146. data/lib/auth0/types/captcha_policy_action_auth_challenge.rb +0 -10
  147. data/lib/auth0/types/captcha_policy_action_friendly_captcha.rb +0 -10
  148. data/lib/auth0/types/captcha_policy_action_friendly_captcha_input.rb +0 -12
  149. data/lib/auth0/types/captcha_policy_action_hcaptcha.rb +0 -10
  150. data/lib/auth0/types/captcha_policy_action_hcaptcha_input.rb +0 -12
  151. data/lib/auth0/types/captcha_policy_action_recaptcha_enterprise.rb +0 -12
  152. data/lib/auth0/types/captcha_policy_action_recaptcha_enterprise_input.rb +0 -14
  153. data/lib/auth0/types/captcha_policy_action_recaptcha_v2.rb +0 -10
  154. data/lib/auth0/types/captcha_policy_action_recaptcha_v2input.rb +0 -12
  155. data/lib/auth0/types/captcha_policy_action_simple_captcha.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0aef33bb7fb9dd8990a6f3a39622aba986b7a020907d8525990391d9deb71e0f
4
- data.tar.gz: c90d04eb8ef0023be41b267547320b64ab259d651ddab120a42be278ee193285
3
+ metadata.gz: 7e787d64726dfd6bfb46857e1e1d68df5c06cf088d71c998da367a0e9487be9f
4
+ data.tar.gz: 59a2130de04ac2c65e6129979de443daae5bd0215c4eb4cafb0650b13bde9095
5
5
  SHA512:
6
- metadata.gz: cc5b3db616d82d0dc6619e51da61abbb3455ceae6eec16869122cbfc88b8626aa66d9c57c6549ff5d9a1659691c8379527078d4e5f747e06f3688fbf28c8391c
7
- data.tar.gz: 8d30725488a0cd575d8bc6fff7e740a8f17d8170e6871fade8e83a584e0b3f72b78b0059c83d2ba6e52901a4210bc1d1078f14c7e75baee87f7696e87a413701
6
+ metadata.gz: ed27130d281f1ff2cac53fa12d0eb1bb810b3f07c0ff73d89ef073725af9fbcb5e8796f4fabec90798e4aa23fefb94f96211551d5dc7d64aae8f72b3398d14f3
7
+ data.tar.gz: 184e6c27433b16e4e0fcbba7193ff3a758c0e2aaa5843d98495529394e1105267e369ef2b526b9c2135ab9e05e5778701cd9ab6bd4aab36bed58ab60bec3d470
data/.fern/metadata.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "cliVersion": "5.144.3",
2
+ "cliVersion": "5.166.0",
3
3
  "generatorName": "fernapi/fern-ruby-sdk",
4
4
  "generatorVersion": "1.24.1",
5
5
  "generatorConfig": {
@@ -10,9 +10,9 @@
10
10
  "offsetSemantics": "page-index",
11
11
  "useDefaultRequestParameterValues": true
12
12
  },
13
- "originGitCommit": "275ad23d02d33d550693bc23ebae86dfa8ee7101",
13
+ "originGitCommit": "30874f917fa5eed3526d32a3bfd2ff024d36a4f4",
14
14
  "originGitCommitIsDirty": false,
15
15
  "invokedBy": "ci",
16
16
  "ciProvider": "github",
17
- "sdkVersion": "6.4.1"
17
+ "sdkVersion": "6.5.1"
18
18
  }
data/.fern/replay.lock CHANGED
@@ -1,64 +1,22 @@
1
1
  # DO NOT EDIT MANUALLY - Managed by Fern Replay
2
2
  version: "1.0"
3
3
  generations:
4
- - commit_sha: 78ff190749feb3803b4e9629d57294e4b09d3ead
5
- tree_hash: c3e180060dcea59de5c4290a242c66639e5cecff
6
- timestamp: 2026-07-14T04:31:08.668Z
4
+ - commit_sha: 1af018d42213a5a5a4a5857b8ee326c968405184
5
+ tree_hash: 26cc3589bfbfef3bd26972743969ea67451c2a23
6
+ timestamp: 2026-10-27T11:22:31.372Z
7
7
  cli_version: unknown
8
8
  generator_versions: {}
9
- - commit_sha: 6caf043a4469185ba0f690eb2da7c6889138f4d7
10
- tree_hash: dbc1a9fac4f5566751f2760dc8e1191d47892bd5
11
- timestamp: 2026-07-14T04:31:09.152Z
12
- cli_version: unknown
13
- generator_versions:
14
- fernapi/fern-ruby-sdk: 1.13.1
15
- - commit_sha: 428032101d1791fe97573af36427e664fe4e1e88
16
- tree_hash: 231d5c443ba4120855bd439d858060fc178043cd
17
- timestamp: 2026-07-15T09:11:13.405Z
18
- cli_version: unknown
19
- generator_versions:
20
- fernapi/fern-ruby-sdk: 1.13.1
21
- - commit_sha: d8a88028849ce519e8fdc20765c78e367f372110
22
- tree_hash: 3e4eff170915344776a2c1e921a378a13c54afd1
23
- timestamp: 2026-07-21T07:06:12.329Z
24
- cli_version: unknown
25
- generator_versions:
26
- fernapi/fern-ruby-sdk: 1.17.8
27
- - commit_sha: ff82f16a518e8ee51b23570ed1a303f3c070ff02
28
- tree_hash: 6b4ba82c8dbe3556b6c8e7dd4f7c4d32671aa12a
29
- timestamp: 2026-08-04T06:22:44.311Z
30
- cli_version: unknown
31
- generator_versions:
32
- fernapi/fern-ruby-sdk: 1.17.8
33
- - commit_sha: 1cfe82c679b6122773317ebd41bff24b09388b3d
34
- tree_hash: a7034ef350a9bfaa17781b64316723f688b91e18
35
- timestamp: 2026-08-19T06:07:50.024Z
36
- cli_version: unknown
37
- generator_versions:
38
- fernapi/fern-ruby-sdk: 1.17.8
39
- - commit_sha: 78116dc530cd08317c9323863f3127c2fdec29ee
40
- tree_hash: d0d935e417bf22e33c1c1eb9c6c43371d35907c0
41
- timestamp: 2026-09-02T09:27:17.154Z
42
- cli_version: unknown
43
- generator_versions:
44
- fernapi/fern-ruby-sdk: 1.17.8
45
- - commit_sha: 83074ed870797568e512cc7f0fb71dc679cdd7f4
46
- tree_hash: cbc5c6ccd2dfd5be3b5d68f7bc45a51e62fa6704
47
- timestamp: 2026-09-15T12:33:08.051Z
48
- cli_version: unknown
49
- generator_versions:
50
- fernapi/fern-ruby-sdk: 1.24.1
51
- - commit_sha: ddd12c1ca38e6c93db2c1d30e4194a2ecbca03ba
52
- tree_hash: fa2bf11afbbd64aff874ac158dfaf67412ee73d7
53
- timestamp: 2026-09-29T05:46:29.187Z
9
+ - commit_sha: 1f0cde99ca7fdddcfc5635a1f41bf51a7efe863c
10
+ tree_hash: 781e4e5affb287da31d3713a3f16811228a7ada7
11
+ timestamp: 2026-10-27T11:30:28.609Z
54
12
  cli_version: unknown
55
13
  generator_versions:
56
14
  fernapi/fern-ruby-sdk: 1.24.1
57
- - commit_sha: 3ee763815dcd7a7a39f5c3c7c6bd40d4de0014d6
58
- tree_hash: 0ce0997d753141426376e5ff1dcc183ea138c84e
59
- timestamp: 2026-10-13T10:24:06.305Z
15
+ - commit_sha: c4b1c95e4e0668d2c42aaa0a4c5c5ab1e8a642f8
16
+ tree_hash: d37708b9770790ac5501ab5c8a3a038868cd45d1
17
+ timestamp: 2026-11-04T03:49:40.588Z
60
18
  cli_version: unknown
61
19
  generator_versions:
62
20
  fernapi/fern-ruby-sdk: 1.24.1
63
- current_generation: 3ee763815dcd7a7a39f5c3c7c6bd40d4de0014d6
21
+ current_generation: c4b1c95e4e0668d2c42aaa0a4c5c5ab1e8a642f8
64
22
  patches: []
data/.version CHANGED
@@ -1 +1 @@
1
- v6.5.0
1
+ v6.6.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## [v6.6.0](https://github.com/auth0/ruby-auth0/tree/v6.6.0) (2026-11-04)
4
+ [Full Changelog](https://github.com/auth0/ruby-auth0/compare/v6.5.0...v6.6.0)
5
+
6
+ **Added**
7
+ - feat!: add Portals, Client agent_id and agent subject claims, and wrap Consent Signing Keys list response [\#824](https://github.com/auth0/ruby-auth0/pull/824) ([fern-api[bot]](https://github.com/apps/fern-api))
8
+ - feat: add Consent Signing Keys, OTP Settings, Resource Server type and Management tenant_domain, and remove Captcha Policies [\#821](https://github.com/auth0/ruby-auth0/pull/821) ([fern-api[bot]](https://github.com/apps/fern-api))
9
+ - feat: expose Management API rate limit info via a client callback [\#774](https://github.com/auth0/ruby-auth0/pull/774) ([ProdigyTom](https://github.com/ProdigyTom))
10
+
3
11
  ## [v6.5.0](https://github.com/auth0/ruby-auth0/tree/v6.5.0) (2026-10-14)
4
12
  [Full Changelog](https://github.com/auth0/ruby-auth0/compare/v6.4.0...v6.5.0)
5
13
 
data/EXAMPLES.md CHANGED
@@ -166,6 +166,26 @@ management.roles.create(name: 'admin', description: 'Administrator')
166
166
  management.organizations.list(take: 20)
167
167
  ```
168
168
 
169
+ ## Rate Limit Monitoring
170
+
171
+ Pass a `rate_limit_handler` when building an `Auth0::Client` to observe Auth0's `x-ratelimit-*` headers, without changing the return value of your calls. It covers Management API calls and the Authentication API calls made through the client's HTTP layer (it is not available on `Auth0::Management` directly):
172
+
173
+ ```ruby
174
+ client = Auth0::Client.new(
175
+ domain: ENV['AUTH0_RUBY_DOMAIN'],
176
+ client_id: ENV['AUTH0_RUBY_CLIENT_ID'],
177
+ client_secret: ENV['AUTH0_RUBY_CLIENT_SECRET'],
178
+ rate_limit_handler: lambda do |rate_limit|
179
+ # rate_limit.limit / rate_limit.remaining (Integers), rate_limit.reset (UTC Time)
180
+ Rails.logger.info("Auth0 rate limit: #{rate_limit.remaining}/#{rate_limit.limit}, resets at #{rate_limit.reset}")
181
+ end
182
+ )
183
+
184
+ client.users.get(id: 'auth0|123456') # handler fires with this response's rate limit
185
+ ```
186
+
187
+ The handler is invoked on every response, including the `429`s that trigger an automatic retry. An error raised inside the handler is caught (and warned) so it never breaks the request.
188
+
169
189
  ## Organizations
170
190
 
171
191
  [Organizations](https://auth0.com/docs/organizations) is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications.
data/README.md CHANGED
@@ -104,6 +104,7 @@ client = Auth0::Client.new(
104
104
  | `management_timeout` | Float | Timeout in seconds for Management API calls. | `60` |
105
105
  | `management_max_retries` | Integer | Maximum retries for Management API calls. | `2` |
106
106
  | `management_additional_headers` | Hash | Additional HTTP headers for Management API calls. | `nil` |
107
+ | `rate_limit_handler` | `#call` | Callback for [rate-limit monitoring](#rate-limit-monitoring). | `nil` |
107
108
 
108
109
  #### Accessing the Management Client Directly
109
110
 
@@ -283,6 +284,23 @@ client.users.list(
283
284
  )
284
285
  ```
285
286
 
287
+ ### Rate Limit Monitoring
288
+
289
+ Auth0 returns `x-ratelimit-limit`, `x-ratelimit-remaining`, and `x-ratelimit-reset` headers on API responses. Pass a `rate_limit_handler` when building an `Auth0::Client` to be notified of this data, so you can monitor how close you are to the limit (for example, emit a metric and alert before you run out). It covers Management API calls and the Authentication API calls made through the client's HTTP layer (the JWKS fetch used by `validate_id_token` goes through a separate object and is not reported). It is not available on `Auth0::Management` directly.
290
+
291
+ ```ruby
292
+ client = Auth0::Client.new(
293
+ domain: ENV['AUTH0_RUBY_DOMAIN'],
294
+ client_id: ENV['AUTH0_RUBY_CLIENT_ID'],
295
+ client_secret: ENV['AUTH0_RUBY_CLIENT_SECRET'],
296
+ rate_limit_handler: lambda do |rate_limit|
297
+ StatsD.gauge('auth0.rate_limit.remaining', rate_limit.remaining) if rate_limit.remaining
298
+ end
299
+ )
300
+ ```
301
+
302
+ The handler receives an object with `#limit`, `#remaining` (Integers), and `#reset` (a UTC `Time`). Each is `nil` when the corresponding header is absent or non-numeric. It is invoked on every response, including the `429`s that trigger an automatic retry, so you can observe the point at which the limit was reached. The return value of your API call is unchanged, and an exception raised inside the handler is caught (and warned) so it can never break a request.
303
+
286
304
  ### Errors
287
305
 
288
306
  Management API errors use the `Auth0::Errors` namespace:
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- auth0 (6.5.0)
4
+ auth0 (6.6.0)
5
5
  addressable (~> 2.8)
6
6
  jwt (>= 2.7, < 4.0)
7
7
  rest-client (~> 2.1)
@@ -13,9 +13,9 @@ module Auth0
13
13
 
14
14
  field :mode, -> { Auth0::Types::BruteForceProtectionModeEnum }, optional: true, nullable: false
15
15
 
16
- field :max_attempts, -> { Integer }, optional: true, nullable: false
17
-
18
16
  field :form_submission_mode, -> { Auth0::Types::BruteForceProtectionFormSubmissionModeEnum }, optional: true, nullable: false
17
+
18
+ field :max_attempts, -> { Integer }, optional: true, nullable: false
19
19
  end
20
20
  end
21
21
  end
@@ -30,11 +30,6 @@ module Auth0
30
30
  @captcha ||= Auth0::AttackProtection::Captcha::Client.new(client: @client)
31
31
  end
32
32
 
33
- # @return [Auth0::CaptchaPolicies::Client]
34
- def captcha_policies
35
- @captcha_policies ||= Auth0::AttackProtection::CaptchaPolicies::Client.new(client: @client)
36
- end
37
-
38
33
  # @return [Auth0::PhoneProviderProtection::Client]
39
34
  def phone_provider_protection
40
35
  @phone_provider_protection ||= Auth0::AttackProtection::PhoneProviderProtection::Client.new(client: @client)
@@ -85,14 +85,39 @@ module Auth0
85
85
  def management
86
86
  current_token = get_token
87
87
  if @_management.nil? || @_management_token != current_token
88
- @_management_token = current_token
89
88
  opts = { token: current_token, base_url: "#{@base_uri}/api/v2" }
90
89
  opts[:timeout] = @management_timeout if @management_timeout
91
90
  opts[:max_retries] = @management_max_retries if @management_max_retries
92
91
  opts[:headers] = @management_additional_headers if @management_additional_headers
93
- @_management = Auth0::Management.new(**opts)
92
+ management = Auth0::Management.new(**opts)
93
+ # Attach before caching so a failed attach doesn't leave a handler-less
94
+ # management cached (the next call would then skip the rebuild).
95
+ attach_rate_limit_handler(management)
96
+ @_management = management
97
+ @_management_token = current_token
94
98
  end
95
99
  @_management
96
100
  end
101
+
102
+ private
103
+
104
+ # Attaches the configured rate limit handler to the management client's raw
105
+ # client. Fails loudly rather than silently skipping, so a future change to
106
+ # the generated client's internals surfaces instead of quietly disabling it.
107
+ # @param management [Auth0::Management]
108
+ # @return [void]
109
+ # @raise [Auth0::Exception] if the management client exposes no compatible raw client
110
+ def attach_rate_limit_handler(management)
111
+ return if @rate_limit_handler.nil?
112
+
113
+ raw_client = management.instance_variable_get(:@raw_client)
114
+ unless raw_client.respond_to?(:rate_limit_handler=)
115
+ raise Auth0::Exception,
116
+ "Unable to attach rate_limit_handler: the management client does not expose a compatible raw client. " \
117
+ "This likely means the ruby-auth0 internals changed. Please report it."
118
+ end
119
+
120
+ raw_client.rate_limit_handler = @rate_limit_handler
121
+ end
97
122
  end
98
123
  end
data/lib/auth0/client.rb CHANGED
@@ -4,12 +4,20 @@ module Auth0
4
4
  class Management
5
5
  # @param token [String]
6
6
  # @param base_url [String, nil]
7
+ # @param tenant_domain [String, nil] Tenant domain, such as "example.auth0.com", used to build the base URL.
7
8
  # @param timeout [Float, nil] Request timeout in seconds.
8
- # @param max_retries [Integer, nil] Maximum number of request retries.
9
+ # @param max_retries [Integer] Maximum number of request retries, defaults to 2.
9
10
  # @param headers [Hash, nil] Additional headers to include in requests.
10
11
  #
11
12
  # @return [void]
12
- def initialize(token:, base_url: nil, timeout: nil, max_retries: nil, headers: nil)
13
+ def initialize(token:, base_url: nil, tenant_domain: nil, timeout: nil, max_retries: 2, headers: nil)
14
+ unless tenant_domain.nil?
15
+ environment_url_templates = {
16
+ Auth0::Environment::DEFAULT => "https://#{tenant_domain}/api/v2"
17
+ }
18
+ base_url = base_url.nil? ? "https://#{tenant_domain}/api/v2" : environment_url_templates.fetch(base_url, base_url)
19
+ end
20
+
13
21
  raw_client_opts = {
14
22
  base_url: base_url || Auth0::Environment::DEFAULT,
15
23
  headers: {
@@ -143,6 +151,11 @@ module Auth0
143
151
  @organizations ||= Auth0::Organizations::Client.new(client: @raw_client)
144
152
  end
145
153
 
154
+ # @return [Auth0::Portals::Client]
155
+ def portals
156
+ @portals ||= Auth0::Portals::Client.new(client: @raw_client)
157
+ end
158
+
146
159
  # @return [Auth0::Prompts::Client]
147
160
  def prompts
148
161
  @prompts ||= Auth0::Prompts::Client.new(client: @raw_client)
@@ -54,6 +54,7 @@ module Auth0
54
54
  # @option params [Boolean, nil] :is_first_party
55
55
  # @option params [String, nil] :app_type
56
56
  # @option params [String, nil] :external_client_id
57
+ # @option params [String, nil] :agent_id
57
58
  # @option params [String, nil] :q
58
59
  #
59
60
  # @example
@@ -67,6 +68,7 @@ module Auth0
67
68
  # is_first_party: true,
68
69
  # app_type: "app_type",
69
70
  # external_client_id: "external_client_id",
71
+ # agent_id: "agent_id",
70
72
  # q: "q"
71
73
  # )
72
74
  #
@@ -83,6 +85,7 @@ module Auth0
83
85
  query_params["is_first_party"] = params[:is_first_party] if params.key?(:is_first_party)
84
86
  query_params["app_type"] = params[:app_type] if params.key?(:app_type)
85
87
  query_params["external_client_id"] = params[:external_client_id] if params.key?(:external_client_id)
88
+ query_params["agent_id"] = params[:agent_id] if params.key?(:agent_id)
86
89
  query_params["q"] = params[:q] if params.key?(:q)
87
90
 
88
91
  Auth0::Internal::OffsetItemIterator.new(
@@ -122,6 +122,8 @@ module Auth0
122
122
 
123
123
  field :async_approval_notification_channels, -> { Internal::Types::Array[Auth0::Types::AsyncApprovalNotificationsChannelsEnum] }, optional: true, nullable: false
124
124
 
125
+ field :agent_id, -> { String }, optional: true, nullable: false
126
+
125
127
  field :oidc_support, -> { Auth0::Types::ClientOidcSupportPost }, optional: true, nullable: false
126
128
  end
127
129
  end
@@ -22,6 +22,8 @@ module Auth0
22
22
 
23
23
  field :external_client_id, -> { String }, optional: true, nullable: false
24
24
 
25
+ field :agent_id, -> { String }, optional: true, nullable: false
26
+
25
27
  field :q, -> { String }, optional: true, nullable: false
26
28
  end
27
29
  end
@@ -124,6 +124,8 @@ module Auth0
124
124
 
125
125
  field :redirection_policy, -> { Auth0::Types::ClientRedirectionPolicyEnum }, optional: true, nullable: false
126
126
 
127
+ field :agent_id, -> { String }, optional: true, nullable: false
128
+
127
129
  field :oidc_support, -> { Auth0::Types::ClientOidcSupportPatch }, optional: true, nullable: false
128
130
  end
129
131
  end
@@ -11,7 +11,7 @@ module Auth0
11
11
  @client = client
12
12
  end
13
13
 
14
- # Gets the connection keys for the Okta or OIDC connection strategy.
14
+ # Gets the connection keys for the Okta, OIDC, or SAML (samlp) connection strategy.
15
15
  #
16
16
  # @param request_options [Hash]
17
17
  # @param params [Hash]
@@ -48,9 +48,9 @@ module Auth0
48
48
  end
49
49
  end
50
50
 
51
- # Provision initial connection keys for Okta or OIDC connection strategies. This endpoint allows you to create
52
- # keys before configuring the connection to use Private Key JWT authentication, enabling zero-downtime
53
- # transitions.
51
+ # Provision initial connection keys for Okta, OIDC, or SAML (samlp) connection strategies. This endpoint allows
52
+ # you to create keys before configuring the connection to use Private Key JWT authentication, enabling
53
+ # zero-downtime transitions.
54
54
  #
55
55
  # @param request_options [Hash]
56
56
  # @param params [Hash]
@@ -94,7 +94,7 @@ module Auth0
94
94
  end
95
95
  end
96
96
 
97
- # Rotates the connection keys for the Okta or OIDC connection strategies.
97
+ # Rotates the connection keys for the Okta, OIDC, or SAML (samlp) connection strategies.
98
98
  #
99
99
  # @param request_options [Hash]
100
100
  # @param params [Hash]
@@ -88,7 +88,8 @@ module Auth0
88
88
  # client.experimentation.experiments.create(
89
89
  # name: "name",
90
90
  # feature_flag_id: "feature_flag_id",
91
- # authentication_flow: "authentication"
91
+ # authentication_flow: "authentication",
92
+ # allocation_strategy: "percentage"
92
93
  # )
93
94
  #
94
95
  # @return [Auth0::Types::CreateExperimentResponseContent]
@@ -15,7 +15,7 @@ module Auth0
15
15
 
16
16
  field :default_config, -> { Auth0::Types::DefaultConfigEnum }, optional: true, nullable: false
17
17
 
18
- field :allocation_strategy, -> { Auth0::Types::AllocationStrategyEnum }, optional: true, nullable: false
18
+ field :allocation_strategy, -> { Auth0::Types::AllocationStrategyEnum }, optional: false, nullable: false
19
19
 
20
20
  field :allocations, -> { Internal::Types::Array[Auth0::Types::AllocationRequestItem] }, optional: true, nullable: false
21
21
 
@@ -23,12 +23,14 @@ module Auth0
23
23
  # @option params [String, nil] :from
24
24
  # @option params [Integer, nil] :take
25
25
  # @option params [Auth0::Types::SegmentTypeFilterEnum, nil] :type
26
+ # @option params [Auth0::Types::SegmentStatusEnum, nil] :status
26
27
  #
27
28
  # @example
28
29
  # client.experimentation.segments.list(
29
30
  # from: "from",
30
31
  # take: 1,
31
- # type: "auth0"
32
+ # type: "auth0",
33
+ # status: "active"
32
34
  # )
33
35
  #
34
36
  # @return [Auth0::Types::ListSegmentsResponseContent]
@@ -38,6 +40,7 @@ module Auth0
38
40
  query_params["from"] = params[:from] if params.key?(:from)
39
41
  query_params["take"] = params.fetch(:take, 50)
40
42
  query_params["type"] = params[:type] if params.key?(:type)
43
+ query_params["status"] = params[:status] if params.key?(:status)
41
44
 
42
45
  Auth0::Internal::CursorItemIterator.new(
43
46
  cursor_field: :next_,
@@ -10,6 +10,8 @@ module Auth0
10
10
  field :take, -> { Integer }, optional: true, nullable: false
11
11
 
12
12
  field :type, -> { Auth0::Types::SegmentTypeFilterEnum }, optional: true, nullable: false
13
+
14
+ field :status, -> { Auth0::Types::SegmentStatusEnum }, optional: true, nullable: false
13
15
  end
14
16
  end
15
17
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Auth0
4
+ module Internal
5
+ module Http
6
+ # Rate limit information parsed from the `x-ratelimit-*` headers Auth0
7
+ # returns on API responses.
8
+ #
9
+ # @see https://auth0.com/docs/troubleshoot/customer-support/operational-policies/rate-limit-policy
10
+ class RateLimit
11
+ # @return [Integer, nil] the maximum number of requests allowed in the current window
12
+ attr_reader :limit
13
+ # @return [Integer, nil] the number of requests remaining in the current window
14
+ attr_reader :remaining
15
+ # @return [Time, nil] the UTC time at which the current window resets
16
+ attr_reader :reset
17
+
18
+ # @param limit [Integer, nil]
19
+ # @param remaining [Integer, nil]
20
+ # @param reset [Time, nil]
21
+ def initialize(limit:, remaining:, reset:)
22
+ @limit = limit
23
+ @remaining = remaining
24
+ @reset = reset
25
+ end
26
+
27
+ # Build from an object that exposes headers via `#[]` using the HTTP
28
+ # header name (e.g. a `Net::HTTPResponse`, whose `#[]` is
29
+ # case-insensitive). Used by the Management API (RawClient) path.
30
+ #
31
+ # @param response [#[]] responds to `[]` with header access
32
+ # @return [Auth0::Internal::Http::RateLimit]
33
+ def self.from_http_response(response)
34
+ build(
35
+ response["x-ratelimit-limit"],
36
+ response["x-ratelimit-remaining"],
37
+ response["x-ratelimit-reset"]
38
+ )
39
+ end
40
+
41
+ # Build from a plain headers hash (e.g. RestClient's, whose keys are
42
+ # symbols like `:x_ratelimit_remaining`). Keys are matched
43
+ # case-insensitively and dash/underscore-agnostically. Used by the
44
+ # Authentication API (HTTPProxy) path.
45
+ #
46
+ # @param headers [Hash, nil]
47
+ # @return [Auth0::Internal::Http::RateLimit]
48
+ def self.from_headers(headers)
49
+ normalized = (headers || {}).each_with_object({}) do |(key, value), acc|
50
+ acc[key.to_s.downcase.tr("-", "_")] = value
51
+ end
52
+
53
+ build(
54
+ normalized["x_ratelimit_limit"],
55
+ normalized["x_ratelimit_remaining"],
56
+ normalized["x_ratelimit_reset"]
57
+ )
58
+ end
59
+
60
+ # Invokes the handler with the given rate limit. A handler error must
61
+ # never break the caller's request, so it is rescued and warned rather
62
+ # than raised. Parsing happens before this call, so a parsing bug is not
63
+ # misattributed to the handler.
64
+ #
65
+ # @param handler [#call, nil] the configured rate limit handler
66
+ # @param rate_limit [Auth0::Internal::Http::RateLimit]
67
+ # @return [void]
68
+ def self.deliver(handler, rate_limit)
69
+ return if handler.nil?
70
+
71
+ handler.call(rate_limit)
72
+ rescue StandardError => e
73
+ warn "[auth0] rate_limit_handler raised #{e.class}: #{e.message}"
74
+ end
75
+
76
+ # @param limit [String, nil] raw `x-ratelimit-limit` value
77
+ # @param remaining [String, nil] raw `x-ratelimit-remaining` value
78
+ # @param reset [String, nil] raw `x-ratelimit-reset` value
79
+ # @return [Auth0::Internal::Http::RateLimit]
80
+ def self.build(limit, remaining, reset)
81
+ reset_epoch = to_integer(reset)
82
+
83
+ new(
84
+ limit: to_integer(limit),
85
+ remaining: to_integer(remaining),
86
+ reset: reset_epoch.nil? ? nil : Time.at(reset_epoch).utc
87
+ )
88
+ end
89
+ private_class_method :build
90
+
91
+ # Parse an integer header value, returning nil for blank or non-numeric
92
+ # input (so a malformed header is never silently reported as 0).
93
+ #
94
+ # @param value [String, nil] the raw header value
95
+ # @return [Integer, nil]
96
+ def self.to_integer(value)
97
+ Integer(value.to_s.strip, exception: false)
98
+ end
99
+ private_class_method :to_integer
100
+ end
101
+ end
102
+ end
103
+ end
@@ -3,6 +3,8 @@
3
3
  # This file was auto-generated by Fern from our API Definition.
4
4
  # Modified by Auth0 to use Auth0 telemetry format with dynamic versioning.
5
5
 
6
+ require_relative "rate_limit"
7
+
6
8
  module Auth0
7
9
  module Internal
8
10
  module Http
@@ -20,14 +22,21 @@ module Auth0
20
22
  # @return [String] The base URL for requests
21
23
  attr_reader :base_url
22
24
 
25
+ # @return [#call, nil] Optional callback invoked with an
26
+ # {Auth0::Internal::Http::RateLimit} after every response.
27
+ attr_accessor :rate_limit_handler
28
+
23
29
  # @param base_url [String] The base url for the request.
24
30
  # @param max_retries [Integer] The number of times to retry a failed request, defaults to 2.
25
31
  # @param timeout [Float] The timeout for the request, defaults to 60.0 seconds.
26
32
  # @param headers [Hash] The headers for the request.
27
- def initialize(base_url:, max_retries: 2, timeout: 60.0, headers: {})
33
+ # @param rate_limit_handler [#call, nil] Optional callback invoked with the
34
+ # parsed rate limit (from the `x-ratelimit-*` headers) after every response.
35
+ def initialize(base_url:, max_retries: 2, timeout: 60.0, headers: {}, rate_limit_handler: nil)
28
36
  @base_url = base_url
29
37
  @max_retries = max_retries
30
38
  @timeout = timeout
39
+ @rate_limit_handler = rate_limit_handler
31
40
 
32
41
  # Auth0 telemetry in standard format
33
42
  telemetry = {
@@ -45,7 +54,7 @@ module Auth0
45
54
  end
46
55
 
47
56
  # @param request [Auth0::Internal::Http::BaseRequest] The HTTP request.
48
- # @return [HTTP::Response] The HTTP response.
57
+ # @return [Net::HTTPResponse] The HTTP response.
49
58
  def send(request)
50
59
  url = build_url(request)
51
60
  attempt = 0
@@ -67,6 +76,9 @@ module Auth0
67
76
 
68
77
  response = conn.request(http_request)
69
78
 
79
+ # Report rate limit on every response, including retried 429s.
80
+ RateLimit.deliver(@rate_limit_handler, RateLimit.from_http_response(response)) if @rate_limit_handler
81
+
70
82
  break unless should_retry?(response, attempt)
71
83
 
72
84
  delay = retry_delay(response, attempt)
@@ -1,13 +1,14 @@
1
1
  require "addressable/uri"
2
2
  require "retryable"
3
3
  require_relative "../exception.rb"
4
+ require_relative "../internal/http/rate_limit"
4
5
 
5
6
  module Auth0
6
7
  module Mixins
7
8
  # here's the proxy for Rest calls based on rest-client, we're building all request on that gem
8
9
  # for now, if you want to feel free to use your own http client
9
10
  module HTTPProxy
10
- attr_accessor :headers, :base_uri, :timeout, :retry_count
11
+ attr_accessor :headers, :base_uri, :timeout, :retry_count, :rate_limit_handler
11
12
  DEFAULT_RETRIES = 3
12
13
  MAX_ALLOWED_RETRIES = 10
13
14
  MAX_REQUEST_RETRY_JITTER = 250
@@ -95,6 +96,13 @@ module Auth0
95
96
  call(method, encode_uri(uri), timeout, headers, body.to_json)
96
97
  end
97
98
 
99
+ # Surface rate limit for each response, including 429 retries. `call`
100
+ # returns nil for some errors (e.g. a dropped connection), so skip it then.
101
+ if @rate_limit_handler && !result.nil?
102
+ rate_limit = Auth0::Internal::Http::RateLimit.from_headers(result.headers)
103
+ Auth0::Internal::Http::RateLimit.deliver(@rate_limit_handler, rate_limit)
104
+ end
105
+
98
106
  case result.code
99
107
  when 200...226 then safe_parse_json(result.body)
100
108
  when 400 then raise Auth0::BadRequest.new(result.body, code: result.code, headers: result.headers)
@@ -21,6 +21,11 @@ module Auth0
21
21
  @management_timeout = options[:management_timeout]
22
22
  @management_max_retries = options[:management_max_retries]
23
23
  @management_additional_headers = options[:management_additional_headers]
24
+ handler = options[:rate_limit_handler]
25
+ raise ArgumentError, "rate_limit_handler must respond to #call" if handler && !handler.respond_to?(:call)
26
+
27
+ @rate_limit_handler = handler
28
+
24
29
  extend Auth0::Api::AuthenticationEndpoints
25
30
 
26
31
  @client_id = options[:client_id]