legate 0.1.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 (317) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +345 -0
  4. data/bin/legate +13 -0
  5. data/examples/00_quickstart.rb +51 -0
  6. data/examples/01_simple_agent.rb +105 -0
  7. data/examples/02_multi_tool_agent.rb +140 -0
  8. data/examples/03_custom_tool.rb +93 -0
  9. data/examples/04_agent_instructions.rb +84 -0
  10. data/examples/05_state_and_sessions.rb +91 -0
  11. data/examples/06_callbacks.rb +186 -0
  12. data/examples/07_async_jobs.rb +112 -0
  13. data/examples/08_loop_agent.rb +197 -0
  14. data/examples/09_sequential_workflow.rb +40 -0
  15. data/examples/10_parallel_workflow.rb +34 -0
  16. data/examples/11_agent_delegation.rb +24 -0
  17. data/examples/12_http_client_tool.rb +156 -0
  18. data/examples/13_authentication.rb +220 -0
  19. data/examples/14_mcp_client.rb +154 -0
  20. data/examples/15_mcp_server.rb +79 -0
  21. data/examples/16_webhooks.rb +91 -0
  22. data/examples/README_sequential_agents.md +164 -0
  23. data/examples/advanced/auth/cookie_auth_tool.rb +146 -0
  24. data/examples/advanced/auth/custom_auth_flows_example.rb +626 -0
  25. data/examples/advanced/auth/excon_middleware.rb +317 -0
  26. data/examples/advanced/auth/excon_middleware_auth.rb +399 -0
  27. data/examples/advanced/auth/fiber_auth_example.rb +281 -0
  28. data/examples/advanced/auth/fiber_oidc_example.rb +403 -0
  29. data/examples/advanced/auth/httpbin_bearer_tool.rb +159 -0
  30. data/examples/advanced/auth/oauth2_auth.rb +419 -0
  31. data/examples/advanced/auth/oidc_auth.rb +514 -0
  32. data/examples/advanced/auth/openweather_api.rb +251 -0
  33. data/examples/advanced/auth/openweather_tool.rb +153 -0
  34. data/examples/advanced/auth/query_param_middleware_test.rb +138 -0
  35. data/examples/advanced/auth/service_account.rb +135 -0
  36. data/examples/advanced/auth/test_with_httpbin.rb +202 -0
  37. data/examples/advanced/auth/token_lifecycle_example.rb +428 -0
  38. data/examples/advanced/callback_monitoring.rb +679 -0
  39. data/examples/advanced/mas/fixed_delegation_example.rb +191 -0
  40. data/examples/advanced/mas/loop_workflow.rb +28 -0
  41. data/examples/advanced/mas/mock_planner.rb +77 -0
  42. data/examples/advanced/mas/proper_delegation_example.rb +276 -0
  43. data/examples/advanced/mcp/legate_mcp_server_resource_example.rb +182 -0
  44. data/examples/advanced/mcp/mcp_resource_server_example.rb +309 -0
  45. data/examples/advanced/mcp/mcp_server_async.rb +76 -0
  46. data/examples/advanced/mcp/mcp_server_async_tools.rb +122 -0
  47. data/examples/advanced/mcp/mcp_server_legate_agent.rb +95 -0
  48. data/examples/advanced/mcp/mcp_server_rack.rb +89 -0
  49. data/examples/advanced/random_calculator.rb +104 -0
  50. data/examples/advanced/sleep_agent.rb +153 -0
  51. data/examples/advanced/webhooks/webhook_e2e_runner.rb +110 -0
  52. data/examples/advanced/webhooks/webhook_receiver_agent.rb +58 -0
  53. data/examples/advanced/workflows/task_refinement_loop_agent.rb +278 -0
  54. data/examples/advanced/workflows/travel_planner_auto_sequential.rb +444 -0
  55. data/examples/advanced/workflows/travel_planner_parallel.rb +656 -0
  56. data/examples/advanced/workflows/travel_planner_sequential.rb +512 -0
  57. data/examples/tools/oauth2_example.rb +136 -0
  58. data/examples/tools/sleepy_tool.rb +42 -0
  59. data/lib/legate/activity_log.rb +71 -0
  60. data/lib/legate/agent.rb +959 -0
  61. data/lib/legate/agent_code_generator.rb +185 -0
  62. data/lib/legate/agent_definition.rb +812 -0
  63. data/lib/legate/agentic/decision.rb +49 -0
  64. data/lib/legate/agentic/loop.rb +134 -0
  65. data/lib/legate/agentic.rb +5 -0
  66. data/lib/legate/agents/loop_agent.rb +248 -0
  67. data/lib/legate/agents/parallel_agent.rb +163 -0
  68. data/lib/legate/agents/sequential_agent.rb +190 -0
  69. data/lib/legate/agents.rb +14 -0
  70. data/lib/legate/auth/config.rb +148 -0
  71. data/lib/legate/auth/coordinator.rb +218 -0
  72. data/lib/legate/auth/coordinators/oauth2_coordinator.rb +99 -0
  73. data/lib/legate/auth/coordinators/oidc_coordinator.rb +68 -0
  74. data/lib/legate/auth/coordinators/service_account_coordinator.rb +122 -0
  75. data/lib/legate/auth/credential.rb +157 -0
  76. data/lib/legate/auth/encryption.rb +108 -0
  77. data/lib/legate/auth/error.rb +94 -0
  78. data/lib/legate/auth/exchanged_credential.rb +180 -0
  79. data/lib/legate/auth/excon_middleware.rb +285 -0
  80. data/lib/legate/auth/http_client_utils.rb +364 -0
  81. data/lib/legate/auth/manager.rb +531 -0
  82. data/lib/legate/auth/manager_store.rb +394 -0
  83. data/lib/legate/auth/middleware_factory.rb +290 -0
  84. data/lib/legate/auth/runner.rb +279 -0
  85. data/lib/legate/auth/scheme.rb +125 -0
  86. data/lib/legate/auth/schemes/api_key.rb +212 -0
  87. data/lib/legate/auth/schemes/google_service_account.rb +108 -0
  88. data/lib/legate/auth/schemes/http_bearer.rb +98 -0
  89. data/lib/legate/auth/schemes/oauth2.rb +396 -0
  90. data/lib/legate/auth/schemes/openid_connect.rb +346 -0
  91. data/lib/legate/auth/schemes/service_account.rb +388 -0
  92. data/lib/legate/auth/schemes.rb +40 -0
  93. data/lib/legate/auth/token_manager.rb +362 -0
  94. data/lib/legate/auth/token_store.rb +86 -0
  95. data/lib/legate/auth/tool_context_extension.rb +97 -0
  96. data/lib/legate/auth/tool_integration.rb +188 -0
  97. data/lib/legate/auth/url_guard.rb +81 -0
  98. data/lib/legate/auth.rb +453 -0
  99. data/lib/legate/callbacks/callback_context.rb +71 -0
  100. data/lib/legate/cli/agent_commands.rb +950 -0
  101. data/lib/legate/cli/auth_commands.rb +520 -0
  102. data/lib/legate/cli/base_command.rb +24 -0
  103. data/lib/legate/cli/deployment_commands.rb +934 -0
  104. data/lib/legate/cli/output_helper.rb +108 -0
  105. data/lib/legate/cli/session_commands.rb +138 -0
  106. data/lib/legate/cli/skaffold_commands.rb +223 -0
  107. data/lib/legate/cli/tool_commands.rb +261 -0
  108. data/lib/legate/cli/web_commands.rb +182 -0
  109. data/lib/legate/cli.rb +40 -0
  110. data/lib/legate/configuration/webhooks.rb +113 -0
  111. data/lib/legate/configuration.rb +39 -0
  112. data/lib/legate/definition_store.rb +23 -0
  113. data/lib/legate/errors.rb +118 -0
  114. data/lib/legate/event.rb +161 -0
  115. data/lib/legate/gemini_ai_beta_patch.rb +39 -0
  116. data/lib/legate/generators/agent_generator.rb +412 -0
  117. data/lib/legate/generators/code_validator.rb +48 -0
  118. data/lib/legate/generators/legate/install_generator.rb +35 -0
  119. data/lib/legate/generators/legate/templates/create_legate_tables.rb.tt +36 -0
  120. data/lib/legate/generators/legate/templates/initializer.rb +18 -0
  121. data/lib/legate/generators/runtime_tool_loader.rb +76 -0
  122. data/lib/legate/generators/tool_generator.rb +408 -0
  123. data/lib/legate/generators.rb +11 -0
  124. data/lib/legate/global_definition_registry.rb +506 -0
  125. data/lib/legate/global_tool_manager.rb +135 -0
  126. data/lib/legate/llm/adapter.rb +69 -0
  127. data/lib/legate/llm/gemini.rb +172 -0
  128. data/lib/legate/llm/ollama.rb +80 -0
  129. data/lib/legate/llm.rb +34 -0
  130. data/lib/legate/mcp/client.rb +320 -0
  131. data/lib/legate/mcp/connection/sse.rb +292 -0
  132. data/lib/legate/mcp/connection/stdio.rb +273 -0
  133. data/lib/legate/mcp/connection_manager.rb +103 -0
  134. data/lib/legate/mcp/server/legate_agent_adapter.rb +170 -0
  135. data/lib/legate/mcp/server/legate_direct_agent_adapter.rb +140 -0
  136. data/lib/legate/mcp/server/legate_tool_adapter.rb +119 -0
  137. data/lib/legate/mcp/tool_wrapper.rb +138 -0
  138. data/lib/legate/mcp/util/schema_converter.rb +134 -0
  139. data/lib/legate/mcp.rb +23 -0
  140. data/lib/legate/plan_executor.rb +375 -0
  141. data/lib/legate/planner.rb +839 -0
  142. data/lib/legate/rails/railtie.rb +43 -0
  143. data/lib/legate/rails.rb +9 -0
  144. data/lib/legate/redaction.rb +32 -0
  145. data/lib/legate/session.rb +299 -0
  146. data/lib/legate/session_service/active_record.rb +300 -0
  147. data/lib/legate/session_service/base.rb +68 -0
  148. data/lib/legate/session_service/event_broadcast.rb +74 -0
  149. data/lib/legate/session_service/in_memory.rb +188 -0
  150. data/lib/legate/tool/metadata_dsl.rb +122 -0
  151. data/lib/legate/tool.rb +276 -0
  152. data/lib/legate/tool_code_generator.rb +103 -0
  153. data/lib/legate/tool_context.rb +350 -0
  154. data/lib/legate/tool_loader.rb +39 -0
  155. data/lib/legate/tool_registry.rb +73 -0
  156. data/lib/legate/tool_result.rb +61 -0
  157. data/lib/legate/tools/agent_tool.rb +187 -0
  158. data/lib/legate/tools/base/http_client.rb +319 -0
  159. data/lib/legate/tools/base/safe_url.rb +56 -0
  160. data/lib/legate/tools/base_async_job_tool.rb +91 -0
  161. data/lib/legate/tools/calculator.rb +89 -0
  162. data/lib/legate/tools/cat_facts.rb +81 -0
  163. data/lib/legate/tools/check_job_status_tool.rb +48 -0
  164. data/lib/legate/tools/current_time_tool.rb +64 -0
  165. data/lib/legate/tools/echo.rb +43 -0
  166. data/lib/legate/tools/http_request_tool.rb +105 -0
  167. data/lib/legate/tools/random_number_tool.rb +64 -0
  168. data/lib/legate/tools/read_webpage_tool.rb +92 -0
  169. data/lib/legate/tools/sleepy_tool.rb +74 -0
  170. data/lib/legate/tools/webhook_tool.rb +146 -0
  171. data/lib/legate/version.rb +5 -0
  172. data/lib/legate/web/app.rb +984 -0
  173. data/lib/legate/web/public/css/main.css +4980 -0
  174. data/lib/legate/web/public/images/favicon-256.png +0 -0
  175. data/lib/legate/web/public/images/favicon-32.png +0 -0
  176. data/lib/legate/web/public/images/legate-logo-dark.png +0 -0
  177. data/lib/legate/web/public/images/legate-logo-light.png +0 -0
  178. data/lib/legate/web/public/js/legate.js +616 -0
  179. data/lib/legate/web/public/styles/main.scss +4402 -0
  180. data/lib/legate/web/routes/agent_authentication_routes.rb +530 -0
  181. data/lib/legate/web/routes/agent_definition_routes.rb +803 -0
  182. data/lib/legate/web/routes/agent_generator_routes.rb +80 -0
  183. data/lib/legate/web/routes/agent_interaction_routes.rb +734 -0
  184. data/lib/legate/web/routes/agent_runtime_routes.rb +323 -0
  185. data/lib/legate/web/routes/api_routes.rb +56 -0
  186. data/lib/legate/web/routes/authentication_routes.rb +1541 -0
  187. data/lib/legate/web/routes/core_routes.rb +111 -0
  188. data/lib/legate/web/routes/documentation_routes.rb +220 -0
  189. data/lib/legate/web/routes/tool_generator_routes.rb +81 -0
  190. data/lib/legate/web/routes/tools_ui_routes.rb +207 -0
  191. data/lib/legate/web/sass_compiler.rb +73 -0
  192. data/lib/legate/web/views/_active_session_info.slim +25 -0
  193. data/lib/legate/web/views/_activity_list.slim +55 -0
  194. data/lib/legate/web/views/_agent_card.slim +56 -0
  195. data/lib/legate/web/views/_agent_generator_modal.slim +382 -0
  196. data/lib/legate/web/views/_agent_status_controls.slim +71 -0
  197. data/lib/legate/web/views/_agent_tool_table.slim +74 -0
  198. data/lib/legate/web/views/_chat_message.slim +95 -0
  199. data/lib/legate/web/views/_display_agent_configuration.slim +26 -0
  200. data/lib/legate/web/views/_display_agent_description.slim +11 -0
  201. data/lib/legate/web/views/_display_agent_fallback.slim +15 -0
  202. data/lib/legate/web/views/_display_agent_hierarchy.slim +93 -0
  203. data/lib/legate/web/views/_display_agent_instruction.slim +17 -0
  204. data/lib/legate/web/views/_display_agent_mcp.slim +13 -0
  205. data/lib/legate/web/views/_display_agent_model.slim +17 -0
  206. data/lib/legate/web/views/_display_agent_name.slim +42 -0
  207. data/lib/legate/web/views/_display_agent_output_key.slim +26 -0
  208. data/lib/legate/web/views/_display_agent_type.slim +65 -0
  209. data/lib/legate/web/views/_edit_agent_configuration.slim +74 -0
  210. data/lib/legate/web/views/_edit_agent_description.slim +16 -0
  211. data/lib/legate/web/views/_edit_agent_fallback.slim +25 -0
  212. data/lib/legate/web/views/_edit_agent_hierarchy.slim +98 -0
  213. data/lib/legate/web/views/_edit_agent_instruction.slim +49 -0
  214. data/lib/legate/web/views/_edit_agent_mcp.slim +33 -0
  215. data/lib/legate/web/views/_edit_agent_model.slim +23 -0
  216. data/lib/legate/web/views/_edit_agent_output_key.slim +36 -0
  217. data/lib/legate/web/views/_edit_agent_tools.slim +40 -0
  218. data/lib/legate/web/views/_edit_agent_type.slim +67 -0
  219. data/lib/legate/web/views/_session_error.slim +4 -0
  220. data/lib/legate/web/views/_skeleton.slim +69 -0
  221. data/lib/legate/web/views/_tool_card.slim +9 -0
  222. data/lib/legate/web/views/_tool_generator_modal.slim +311 -0
  223. data/lib/legate/web/views/agent.slim +436 -0
  224. data/lib/legate/web/views/agent_auth.slim +562 -0
  225. data/lib/legate/web/views/agents.slim +369 -0
  226. data/lib/legate/web/views/auth.slim +112 -0
  227. data/lib/legate/web/views/auth_credential_detail.slim +327 -0
  228. data/lib/legate/web/views/auth_credentials.slim +261 -0
  229. data/lib/legate/web/views/auth_debug.slim +94 -0
  230. data/lib/legate/web/views/auth_mapping_detail.slim +151 -0
  231. data/lib/legate/web/views/auth_mapping_new.slim +123 -0
  232. data/lib/legate/web/views/auth_mappings.slim +120 -0
  233. data/lib/legate/web/views/auth_scheme_detail.slim +274 -0
  234. data/lib/legate/web/views/auth_schemes.slim +259 -0
  235. data/lib/legate/web/views/auth_test.slim +418 -0
  236. data/lib/legate/web/views/chat.slim +192 -0
  237. data/lib/legate/web/views/docs_index.slim +105 -0
  238. data/lib/legate/web/views/docs_show.slim +105 -0
  239. data/lib/legate/web/views/error_404.slim +5 -0
  240. data/lib/legate/web/views/index.slim +148 -0
  241. data/lib/legate/web/views/layout.slim +144 -0
  242. data/lib/legate/web/views/tool_detail.slim +87 -0
  243. data/lib/legate/web/views/tools.slim +50 -0
  244. data/lib/legate/web/webhook_listener.rb +367 -0
  245. data/lib/legate/web.rb +9 -0
  246. data/lib/legate.rb +220 -0
  247. data/public/docs/advanced/callbacks.md +828 -0
  248. data/public/docs/advanced/mcp_schema_conversion.md +59 -0
  249. data/public/docs/authentication/api_reference/config.md +210 -0
  250. data/public/docs/authentication/api_reference/credential.md +246 -0
  251. data/public/docs/authentication/api_reference/encryption.md +218 -0
  252. data/public/docs/authentication/api_reference/exchanged_credential.md +271 -0
  253. data/public/docs/authentication/api_reference/excon_middleware.md +175 -0
  254. data/public/docs/authentication/api_reference/index.md +30 -0
  255. data/public/docs/authentication/api_reference/scheme.md +250 -0
  256. data/public/docs/authentication/api_reference/schemes/api_key.md +175 -0
  257. data/public/docs/authentication/api_reference/schemes/google_service_account.md +221 -0
  258. data/public/docs/authentication/api_reference/schemes/http_bearer.md +169 -0
  259. data/public/docs/authentication/api_reference/schemes/oauth2.md +343 -0
  260. data/public/docs/authentication/api_reference/schemes/oidc.md +73 -0
  261. data/public/docs/authentication/api_reference/schemes/openid_connect.md +311 -0
  262. data/public/docs/authentication/api_reference/schemes/service_account.md +287 -0
  263. data/public/docs/authentication/api_reference/token_manager.md +221 -0
  264. data/public/docs/authentication/api_reference/token_store.md +146 -0
  265. data/public/docs/authentication/api_reference/tool_context_extension.md +166 -0
  266. data/public/docs/authentication/guides/api_key.md +190 -0
  267. data/public/docs/authentication/guides/bearer.md +172 -0
  268. data/public/docs/authentication/guides/configuration.md +255 -0
  269. data/public/docs/authentication/guides/custom_flow.md +523 -0
  270. data/public/docs/authentication/guides/index.md +24 -0
  271. data/public/docs/authentication/guides/migration.md +435 -0
  272. data/public/docs/authentication/guides/oauth2.md +252 -0
  273. data/public/docs/authentication/guides/oidc.md +241 -0
  274. data/public/docs/authentication/guides/overview.md +155 -0
  275. data/public/docs/authentication/guides/secure_storage.md +301 -0
  276. data/public/docs/authentication/guides/service_account.md +228 -0
  277. data/public/docs/authentication/guides/token_lifecycle.md +295 -0
  278. data/public/docs/authentication/guides/web_ui_integration.md +504 -0
  279. data/public/docs/authentication/index.md +58 -0
  280. data/public/docs/authentication/troubleshooting/credential_storage.md +550 -0
  281. data/public/docs/authentication/troubleshooting/environment_variables.md +540 -0
  282. data/public/docs/authentication/troubleshooting/index.md +11 -0
  283. data/public/docs/authentication/troubleshooting/oauth2_issues.md +220 -0
  284. data/public/docs/authentication/troubleshooting/oidc_issues.md +412 -0
  285. data/public/docs/authentication/troubleshooting/token_refresh.md +338 -0
  286. data/public/docs/cli/legate_cli_usage.md +363 -0
  287. data/public/docs/core_concepts/legate_agent_lifecycle.md +124 -0
  288. data/public/docs/core_concepts/legate_architecture_overview.md +110 -0
  289. data/public/docs/core_concepts/legate_configuration.md +116 -0
  290. data/public/docs/core_concepts/legate_definition_store.md +102 -0
  291. data/public/docs/core_concepts/legate_planner.md +94 -0
  292. data/public/docs/core_concepts/legate_session_service.md +104 -0
  293. data/public/docs/error_handling/legate_error_handling.md +122 -0
  294. data/public/docs/examples.md +199 -0
  295. data/public/docs/getting_started.md +111 -0
  296. data/public/docs/guides/agentic_agents.md +137 -0
  297. data/public/docs/guides/ai_code_generators.md +437 -0
  298. data/public/docs/guides/auto_loading.md +326 -0
  299. data/public/docs/guides/configuring_agent_webhooks.md +219 -0
  300. data/public/docs/guides/http_client_usage.md +264 -0
  301. data/public/docs/guides/llm_providers.md +137 -0
  302. data/public/docs/guides/mcp_client_integration.md +232 -0
  303. data/public/docs/guides/mcp_server_exposure.md +206 -0
  304. data/public/docs/guides/rails_integration.md +128 -0
  305. data/public/docs/guides/sending_outbound_webhooks.md +227 -0
  306. data/public/docs/guides/streaming.md +112 -0
  307. data/public/docs/guides/webhooks.md +288 -0
  308. data/public/docs/introduction.md +51 -0
  309. data/public/docs/multi_agent_systems/advanced_features.md +57 -0
  310. data/public/docs/multi_agent_systems/agent_delegation.md +190 -0
  311. data/public/docs/multi_agent_systems/agent_hierarchy.md +49 -0
  312. data/public/docs/multi_agent_systems/state_management.md +47 -0
  313. data/public/docs/multi_agent_systems/workflow_agents.md +72 -0
  314. data/public/docs/tools/legate_built_in_tools.md +332 -0
  315. data/public/docs/tools/legate_tools_and_registry.md +263 -0
  316. data/public/docs/web_ui/legate_web_ui.md +137 -0
  317. metadata +823 -0
@@ -0,0 +1,169 @@
1
+ # Legate::Auth::Schemes::HTTPBearer
2
+
3
+ The `HTTPBearer` class implements the HTTP Bearer authentication scheme, which uses a bearer token to authenticate API requests. This is one of the simpler authentication schemes, used when you already have a bearer token. It is also available via the `HttpBearer` alias.
4
+
5
+ ## Overview
6
+
7
+ The HTTP Bearer authentication scheme is specified in [RFC 6750](https://tools.ietf.org/html/rfc6750) and is a widely used method for API authentication. It works by including an access token in the `Authorization` header of HTTP requests with the prefix `Bearer`.
8
+
9
+ ## Class Methods
10
+
11
+ ### `new`
12
+
13
+ Creates a new HTTP Bearer authentication scheme.
14
+
15
+ **Parameters:**
16
+ - None required
17
+
18
+ **Examples:**
19
+
20
+ ```ruby
21
+ # Create a basic HTTP Bearer scheme
22
+ scheme = Legate::Auth::Schemes::HTTPBearer.new
23
+ ```
24
+
25
+ ## Instance Methods
26
+
27
+ ### `scheme_type`
28
+
29
+ Returns the type of the authentication scheme.
30
+
31
+ **Returns:**
32
+ - Symbol: `:http_bearer`
33
+
34
+ **Examples:**
35
+
36
+ ```ruby
37
+ scheme = Legate::Auth::Schemes::HTTPBearer.new
38
+ scheme.scheme_type # => :http_bearer
39
+ ```
40
+
41
+ ### `apply_to_request`
42
+
43
+ Applies bearer token authentication to a request by adding the token to the Authorization header.
44
+
45
+ **Parameters:**
46
+ - `request` (Hash): The request to authenticate
47
+ - `credential` (Legate::Auth::ExchangedCredential): The exchanged credential containing the bearer token
48
+
49
+ **Returns:**
50
+ - Hash: The authenticated request with bearer token in the Authorization header
51
+
52
+ **Examples:**
53
+
54
+ ```ruby
55
+ # Create a bearer token credential and exchange it
56
+ credential = Legate::Auth::Credential.new(
57
+ auth_type: :http_bearer,
58
+ bearer_token: 'my-bearer-token'
59
+ )
60
+
61
+ scheme = Legate::Auth::Schemes::HTTPBearer.new
62
+ token = scheme.exchange_token(credential)
63
+
64
+ # Apply to a request
65
+ request = { headers: {} }
66
+ authenticated = scheme.apply_to_request(request, token)
67
+ puts authenticated[:headers]['Authorization'] # => "Bearer my-bearer-token"
68
+ ```
69
+
70
+ ### `exchange_token`
71
+
72
+ Exchanges a credential for an authentication token. For HTTP Bearer, this simply wraps the bearer token in an ExchangedCredential.
73
+
74
+ **Parameters:**
75
+ - `credential` (Legate::Auth::Credential): The credential to exchange
76
+
77
+ **Returns:**
78
+ - Legate::Auth::ExchangedCredential: The exchanged token
79
+
80
+ **Examples:**
81
+
82
+ ```ruby
83
+ # Create a bearer token credential
84
+ credential = Legate::Auth::Credential.new(
85
+ auth_type: :http_bearer,
86
+ bearer_token: 'my-bearer-token'
87
+ )
88
+
89
+ # Exchange for a token
90
+ scheme = Legate::Auth::Schemes::HTTPBearer.new
91
+ token = scheme.exchange_token(credential)
92
+
93
+ # The token is a wrapped version of the bearer token
94
+ puts token[:access_token] # => "my-bearer-token"
95
+ ```
96
+
97
+ ### `to_h`
98
+
99
+ Converts the scheme to a hash representation.
100
+
101
+ **Returns:**
102
+ - Hash: A hash representation of the scheme configuration
103
+
104
+ ## Usage Examples
105
+
106
+ ### Basic Authentication
107
+
108
+ ```ruby
109
+ # Create an HTTP Bearer scheme
110
+ scheme = Legate::Auth::Schemes::HTTPBearer.new
111
+
112
+ # Create a credential with the bearer token
113
+ credential = Legate::Auth::Credential.new(
114
+ auth_type: :http_bearer,
115
+ bearer_token: 'my-bearer-token'
116
+ )
117
+
118
+ # Exchange for a token
119
+ token = scheme.exchange_token(credential)
120
+
121
+ # Apply to a request
122
+ request = { headers: {} }
123
+ authenticated = scheme.apply_to_request(request, token)
124
+ puts authenticated[:headers]['Authorization'] # => "Bearer my-bearer-token"
125
+ ```
126
+
127
+ ### With Token Manager
128
+
129
+ ```ruby
130
+ # Create an HTTP Bearer scheme
131
+ scheme = Legate::Auth::Schemes::HTTPBearer.new
132
+
133
+ # Create a credential with the bearer token
134
+ credential = Legate::Auth::Credential.new(
135
+ auth_type: :http_bearer,
136
+ bearer_token: 'my-bearer-token'
137
+ )
138
+
139
+ # Use with token manager
140
+ token_store = Legate::Auth::TokenStore.new(session_service)
141
+ token_manager = Legate::Auth::TokenManager.new(token_store)
142
+
143
+ # Get a token (this will create and store the ExchangedCredential)
144
+ token = token_manager.get_token(scheme, credential)
145
+ ```
146
+
147
+ ### With Environment Variables
148
+
149
+ ```ruby
150
+ # Create a credential with the bearer token from environment
151
+ credential = Legate::Auth::Credential.new(
152
+ auth_type: :http_bearer,
153
+ bearer_token: ENV['API_BEARER_TOKEN']
154
+ )
155
+ ```
156
+
157
+ ## Security Considerations
158
+
159
+ - Bearer tokens should be treated like passwords and kept secure
160
+ - Always use HTTPS when transmitting bearer tokens
161
+ - Implement proper token lifecycle management, including expiration and revocation
162
+ - Consider using short-lived tokens to minimize the risk of token leakage
163
+
164
+ ## See Also
165
+
166
+ - [Legate::Auth::Credential](../credential)
167
+ - [Legate::Auth::ExchangedCredential](../exchanged_credential)
168
+ - [Legate::Auth::Scheme](../scheme)
169
+ - [Legate::Auth::TokenManager](../token_manager)
@@ -0,0 +1,343 @@
1
+ # Legate::Auth::Schemes::OAuth2
2
+
3
+ The `OAuth2` class implements the OAuth 2.0 authentication scheme, which is a widely adopted industry-standard protocol for authorization. This scheme handles the complex token exchange flows between your application, users, and OAuth 2.0 providers.
4
+
5
+ ## Overview
6
+
7
+ OAuth 2.0 is an authorization framework that enables third-party applications to obtain limited access to a user's account on an HTTP service. It works by delegating user authentication to the service that hosts the user's account and authorizing third-party applications to access that account.
8
+
9
+ ## Class Methods
10
+
11
+ ### `new`
12
+
13
+ Creates a new OAuth 2.0 authentication scheme.
14
+
15
+ **Parameters:**
16
+ - `authorization_url` (String, optional keyword): The authorization endpoint URL
17
+ - `token_url` (String, optional keyword): The token endpoint URL
18
+ - `scopes` (Array<String>, optional keyword): The OAuth scopes to request
19
+ - `use_pkce` (Boolean, optional keyword): Whether to use PKCE (default: true)
20
+ - `additional_params` (Hash, optional keyword): Additional parameters for the authorization request
21
+ - `revocation_url` (String, optional keyword): The token revocation endpoint URL
22
+ - `**kwargs` (Hash): Additional parameters for the authentication scheme
23
+
24
+ **Examples:**
25
+
26
+ ```ruby
27
+ # Create a basic OAuth2 scheme for authorization code flow
28
+ scheme = Legate::Auth::Schemes::OAuth2.new(
29
+ authorization_url: 'https://provider.com/oauth2/authorize',
30
+ token_url: 'https://provider.com/oauth2/token',
31
+ scopes: ['profile', 'email']
32
+ )
33
+
34
+ # Create an OAuth2 scheme with PKCE disabled
35
+ scheme = Legate::Auth::Schemes::OAuth2.new(
36
+ authorization_url: 'https://provider.com/oauth2/authorize',
37
+ token_url: 'https://provider.com/oauth2/token',
38
+ use_pkce: false
39
+ )
40
+
41
+ # Create an OAuth2 scheme for client credentials
42
+ scheme = Legate::Auth::Schemes::OAuth2.new(
43
+ token_url: 'https://provider.com/oauth2/token'
44
+ )
45
+ ```
46
+
47
+ ## Instance Methods
48
+
49
+ ### `scheme_type`
50
+
51
+ Returns the type of the authentication scheme.
52
+
53
+ **Returns:**
54
+ - Symbol: `:oauth2`
55
+
56
+ **Examples:**
57
+
58
+ ```ruby
59
+ scheme = Legate::Auth::Schemes::OAuth2.new
60
+ scheme.scheme_type # => :oauth2
61
+ ```
62
+
63
+ ### `validate!`
64
+
65
+ Validates the scheme configuration. Raises an error if required fields (like `token_url`) are missing.
66
+
67
+ **Raises:**
68
+ - `Legate::Auth::SchemeValidationError`: If the scheme configuration is invalid (e.g. missing `authorization_url` or `token_url`)
69
+
70
+ **Examples:**
71
+
72
+ ```ruby
73
+ scheme = Legate::Auth::Schemes::OAuth2.new(
74
+ authorization_url: 'https://provider.com/oauth2/authorize',
75
+ token_url: 'https://provider.com/oauth2/token'
76
+ )
77
+ scheme.validate! # Passes validation
78
+ ```
79
+
80
+ ### `build_authorization_uri`
81
+
82
+ Builds the authorization URL for the OAuth 2.0 flow.
83
+
84
+ **Parameters:**
85
+ - `config` (Legate::Auth::Config): The authentication configuration
86
+ - `redirect_uri` (String, optional): The redirect URI for the callback
87
+ - `state` (String, optional): The state parameter for CSRF protection
88
+
89
+ **Returns:**
90
+ - String: The authorization URL for the OAuth 2.0 flow
91
+
92
+ **Examples:**
93
+
94
+ ```ruby
95
+ scheme = Legate::Auth::Schemes::OAuth2.new(
96
+ authorization_url: 'https://provider.com/oauth2/authorize',
97
+ token_url: 'https://provider.com/oauth2/token',
98
+ scopes: ['profile', 'email']
99
+ )
100
+
101
+ config = Legate::Auth::Config.new(scheme: scheme, credential: credential)
102
+ auth_url = scheme.build_authorization_uri(
103
+ config,
104
+ 'http://localhost:3000/oauth2/callback',
105
+ SecureRandom.hex(16)
106
+ )
107
+ ```
108
+
109
+ ### `apply_to_request`
110
+
111
+ Applies OAuth 2.0 authentication to a request by adding the access token to the Authorization header.
112
+
113
+ **Parameters:**
114
+ - `request` (Hash): The request to authenticate
115
+ - `credential` (Legate::Auth::ExchangedCredential): The exchanged credential containing the access token
116
+
117
+ **Returns:**
118
+ - Hash: The authenticated request with access token in the Authorization header
119
+
120
+ **Examples:**
121
+
122
+ ```ruby
123
+ # Apply authentication to a request
124
+ request = { headers: {} }
125
+ authenticated = scheme.apply_to_request(request, exchanged_credential)
126
+ puts authenticated[:headers]['Authorization'] # => "Bearer access-token"
127
+ ```
128
+
129
+ ### `exchange_token`
130
+
131
+ Exchanges an authorization code or config for access and refresh tokens.
132
+
133
+ **Parameters:**
134
+ - `config` (Legate::Auth::Config): The authentication configuration (with response_uri set)
135
+ - `credential` (Legate::Auth::Credential): The credential containing client information
136
+
137
+ **Returns:**
138
+ - Legate::Auth::ExchangedCredential: The exchanged tokens
139
+
140
+ **Examples:**
141
+
142
+ ```ruby
143
+ # Exchange authorization code for tokens
144
+ token = scheme.exchange_token(config, credential)
145
+
146
+ puts token[:access_token] # => "access-token"
147
+ puts token[:refresh_token] # => "refresh-token" (if granted)
148
+ puts token[:expires_in] # => 3600 (seconds until expiration)
149
+ ```
150
+
151
+ ### `refresh_token`
152
+
153
+ Refreshes an expired OAuth 2.0 access token using the refresh token.
154
+
155
+ **Parameters:**
156
+ - `exchanged_credential` (Legate::Auth::ExchangedCredential): The token to refresh
157
+ - `credential` (Legate::Auth::Credential): The original credential
158
+
159
+ **Returns:**
160
+ - Legate::Auth::ExchangedCredential: The refreshed token
161
+
162
+ **Examples:**
163
+
164
+ ```ruby
165
+ refreshed_token = scheme.refresh_token(expired_token, credential)
166
+ puts refreshed_token[:access_token] # => "new-access-token"
167
+ ```
168
+
169
+ ### `client_credentials_token`
170
+
171
+ Obtains a token using the client credentials grant type.
172
+
173
+ **Parameters:**
174
+ - `credential` (Legate::Auth::Credential): The credential containing client_id and client_secret
175
+
176
+ **Returns:**
177
+ - Legate::Auth::ExchangedCredential: The token
178
+
179
+ **Examples:**
180
+
181
+ ```ruby
182
+ token = scheme.client_credentials_token(credential)
183
+ ```
184
+
185
+ ### `password_token`
186
+
187
+ Obtains a token using the resource owner password credentials grant type.
188
+
189
+ **Parameters:**
190
+ - `credential` (Legate::Auth::Credential): The credential containing client information
191
+ - `username` (String): The resource owner's username
192
+ - `password` (String): The resource owner's password
193
+
194
+ **Returns:**
195
+ - Legate::Auth::ExchangedCredential: The token
196
+
197
+ **Examples:**
198
+
199
+ ```ruby
200
+ token = scheme.password_token(credential, 'user@example.com', 'password')
201
+ ```
202
+
203
+ ### `to_h`
204
+
205
+ Converts the scheme to a hash representation.
206
+
207
+ **Returns:**
208
+ - Hash: A hash representation of the scheme configuration
209
+
210
+ ## Usage Examples
211
+
212
+ ### Authorization Code Flow
213
+
214
+ ```ruby
215
+ require 'securerandom'
216
+
217
+ # Step 1: Create the OAuth2 scheme
218
+ scheme = Legate::Auth::Schemes::OAuth2.new(
219
+ authorization_url: 'https://provider.com/oauth2/authorize',
220
+ token_url: 'https://provider.com/oauth2/token',
221
+ scopes: ['profile', 'email']
222
+ )
223
+
224
+ # Step 2: Set up credential with client details
225
+ credential = Legate::Auth::Credential.new(
226
+ auth_type: :oauth2,
227
+ client_id: ENV['OAUTH_CLIENT_ID'],
228
+ client_secret: ENV['OAUTH_CLIENT_SECRET']
229
+ )
230
+
231
+ # Step 3: Create config and build authorization URI
232
+ config = Legate::Auth::Config.new(scheme: scheme, credential: credential)
233
+ state = SecureRandom.hex(16)
234
+ auth_url = config.build_authorization_uri(
235
+ 'http://localhost:3000/oauth2/callback',
236
+ state
237
+ )
238
+
239
+ # Step 4: Redirect user to auth_url
240
+ # redirect_to auth_url
241
+
242
+ # Step 5: Handle the callback
243
+ config.response_uri = "http://localhost:3000/oauth2/callback?code=12345&state=#{state}"
244
+ token = scheme.exchange_token(config, credential)
245
+
246
+ # Step 6: Store tokens for future API calls
247
+ token_store = Legate::Auth::TokenStore.new(session_service)
248
+ token_store.store('oauth2_token', token)
249
+ ```
250
+
251
+ ### Client Credentials Flow
252
+
253
+ ```ruby
254
+ # Create an OAuth2 scheme for client credentials
255
+ scheme = Legate::Auth::Schemes::OAuth2.new(
256
+ token_url: 'https://provider.com/oauth2/token',
257
+ scopes: ['api:read', 'api:write']
258
+ )
259
+
260
+ # Create a credential with client details
261
+ credential = Legate::Auth::Credential.new(
262
+ auth_type: :oauth2,
263
+ client_id: ENV['API_CLIENT_ID'],
264
+ client_secret: ENV['API_CLIENT_SECRET']
265
+ )
266
+
267
+ # Get token via client credentials (no user interaction required)
268
+ token = scheme.client_credentials_token(credential)
269
+ ```
270
+
271
+ ### Using with Token Manager
272
+
273
+ ```ruby
274
+ # Create OAuth2 scheme and credential
275
+ scheme = Legate::Auth::Schemes::OAuth2.new(
276
+ authorization_url: 'https://provider.com/oauth2/authorize',
277
+ token_url: 'https://provider.com/oauth2/token'
278
+ )
279
+
280
+ credential = Legate::Auth::Credential.new(
281
+ auth_type: :oauth2,
282
+ client_id: 'ENV:OAUTH_CLIENT_ID',
283
+ client_secret: 'ENV:OAUTH_CLIENT_SECRET'
284
+ )
285
+
286
+ # Use with token manager for automatic token management
287
+ token_store = Legate::Auth::TokenStore.new(session_service)
288
+ token_manager = Legate::Auth::TokenManager.new(token_store)
289
+
290
+ # Get a token (will auto-refresh if expired)
291
+ token = token_manager.get_token(scheme, credential)
292
+ ```
293
+
294
+ ## Provider-Specific Configurations
295
+
296
+ ### Google
297
+
298
+ ```ruby
299
+ scheme = Legate::Auth::Schemes::OAuth2.new(
300
+ authorization_url: 'https://accounts.google.com/o/oauth2/auth',
301
+ token_url: 'https://oauth2.googleapis.com/token',
302
+ scopes: ['profile', 'email', 'https://www.googleapis.com/auth/calendar']
303
+ )
304
+ ```
305
+
306
+ ### Microsoft Azure
307
+
308
+ ```ruby
309
+ scheme = Legate::Auth::Schemes::OAuth2.new(
310
+ authorization_url: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
311
+ token_url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
312
+ scopes: ['User.Read', 'Calendars.Read']
313
+ )
314
+ ```
315
+
316
+ ### GitHub
317
+
318
+ ```ruby
319
+ scheme = Legate::Auth::Schemes::OAuth2.new(
320
+ authorization_url: 'https://github.com/login/oauth/authorize',
321
+ token_url: 'https://github.com/login/oauth/access_token',
322
+ scopes: ['user', 'repo']
323
+ )
324
+ ```
325
+
326
+ ## Security Considerations
327
+
328
+ - Always use HTTPS for all OAuth 2.0 communications
329
+ - Store client secrets securely and never expose them in client-side code
330
+ - Implement state parameter validation to prevent CSRF attacks
331
+ - Use PKCE extension for public clients to prevent authorization code interception
332
+ - Store tokens securely; for at-rest encryption use the opt-in [`Legate::Auth::Encryption`](../encryption) module (TokenStore does not encrypt)
333
+ - Implement proper token lifecycle management, including expiration and revocation
334
+ - Request only the scopes that your application needs (principle of least privilege)
335
+
336
+ > **SSRF protection:** When the scheme makes HTTP calls (e.g. to the token endpoint), the token URL is validated by `Legate::Auth::UrlGuard`, which blocks loopback, link-local, private, CGNAT (100.64.0.0/10), and `0.0.0.0/8` addresses. Set `LEGATE_ALLOW_PRIVATE_AUTH_URLS=1` to bypass this in development.
337
+
338
+ ## See Also
339
+
340
+ - [Legate::Auth::Credential](../credential)
341
+ - [Legate::Auth::ExchangedCredential](../exchanged_credential)
342
+ - [Legate::Auth::Scheme](../scheme)
343
+ - [Legate::Auth::TokenManager](../token_manager)
@@ -0,0 +1,73 @@
1
+ # Legate::Auth::Schemes::OpenIDConnect (OIDC)
2
+
3
+ The `OpenIDConnect` class implements the OpenID Connect (OIDC) authentication scheme, which provides a layer of identity verification on top of OAuth 2.0 protocols. It handles the secure authentication and authorization flow between your application and OIDC providers.
4
+
5
+ > **Note**: This class is also available via the `OIDC` alias for backward compatibility. Both `:oidc` and `:openid_connect` scheme types map to this same `OpenIDConnect` class.
6
+
7
+ For full documentation including all methods, constructor parameters, and advanced usage examples, see the main [OpenIDConnect reference](./openid_connect).
8
+
9
+ ## Quick Start
10
+
11
+ ```ruby
12
+ # Create a basic OIDC scheme
13
+ scheme = Legate::Auth::Schemes::OpenIDConnect.new(
14
+ discovery_url: 'https://accounts.google.com/.well-known/openid-configuration',
15
+ scopes: ['openid', 'email', 'profile']
16
+ )
17
+
18
+ # Set up credential with client details
19
+ credential = Legate::Auth::Credential.new(
20
+ auth_type: :oidc,
21
+ client_id: ENV['OIDC_CLIENT_ID'],
22
+ client_secret: ENV['OIDC_CLIENT_SECRET']
23
+ )
24
+
25
+ # Create config and build authorization URI
26
+ config = Legate::Auth::Config.new(scheme: scheme, credential: credential)
27
+ state = SecureRandom.hex(16)
28
+ auth_url = config.build_authorization_uri(
29
+ 'http://localhost:3000/auth/callback',
30
+ state
31
+ )
32
+
33
+ # After callback, exchange token
34
+ config.response_uri = callback_uri
35
+ token = scheme.exchange_token(config, credential)
36
+
37
+ # Verify ID token
38
+ claims = scheme.verify_id_token(token[:id_token])
39
+
40
+ # Get user info
41
+ user_info = scheme.get_userinfo(token[:access_token])
42
+ ```
43
+
44
+ ## Key Methods
45
+
46
+ - `scheme_type` - Returns `:openid_connect`
47
+ - `validate!` - Validates scheme configuration
48
+ - `build_authorization_uri(config, redirect_uri, state)` - Builds the authorization URL
49
+ - `apply_to_request(request, credential)` - Applies authentication to a request
50
+ - `exchange_token(config, credential)` - Exchanges authorization code for tokens
51
+ - `refresh_token(exchanged_credential, credential)` - Refreshes expired tokens
52
+ - `verify_id_token(id_token, nonce, audience)` - Verifies an ID token
53
+ - `get_userinfo(access_token)` - Gets user info from the userinfo endpoint
54
+ - `discover_endpoints` - Discovers OIDC endpoints
55
+ - `to_h` - Converts to hash
56
+
57
+ ## Using with Token Manager
58
+
59
+ ```ruby
60
+ token_store = Legate::Auth::TokenStore.new(session_service)
61
+ token_manager = Legate::Auth::TokenManager.new(token_store)
62
+
63
+ # Get a token (will auto-refresh if expired)
64
+ token = token_manager.get_token(scheme, credential)
65
+ ```
66
+
67
+ ## See Also
68
+
69
+ - [Legate::Auth::Schemes::OpenIDConnect (full reference)](./openid_connect)
70
+ - [Legate::Auth::Credential](../credential)
71
+ - [Legate::Auth::ExchangedCredential](../exchanged_credential)
72
+ - [Legate::Auth::Scheme](../scheme)
73
+ - [Legate::Auth::TokenManager](../token_manager)