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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +345 -0
- data/bin/legate +13 -0
- data/examples/00_quickstart.rb +51 -0
- data/examples/01_simple_agent.rb +105 -0
- data/examples/02_multi_tool_agent.rb +140 -0
- data/examples/03_custom_tool.rb +93 -0
- data/examples/04_agent_instructions.rb +84 -0
- data/examples/05_state_and_sessions.rb +91 -0
- data/examples/06_callbacks.rb +186 -0
- data/examples/07_async_jobs.rb +112 -0
- data/examples/08_loop_agent.rb +197 -0
- data/examples/09_sequential_workflow.rb +40 -0
- data/examples/10_parallel_workflow.rb +34 -0
- data/examples/11_agent_delegation.rb +24 -0
- data/examples/12_http_client_tool.rb +156 -0
- data/examples/13_authentication.rb +220 -0
- data/examples/14_mcp_client.rb +154 -0
- data/examples/15_mcp_server.rb +79 -0
- data/examples/16_webhooks.rb +91 -0
- data/examples/README_sequential_agents.md +164 -0
- data/examples/advanced/auth/cookie_auth_tool.rb +146 -0
- data/examples/advanced/auth/custom_auth_flows_example.rb +626 -0
- data/examples/advanced/auth/excon_middleware.rb +317 -0
- data/examples/advanced/auth/excon_middleware_auth.rb +399 -0
- data/examples/advanced/auth/fiber_auth_example.rb +281 -0
- data/examples/advanced/auth/fiber_oidc_example.rb +403 -0
- data/examples/advanced/auth/httpbin_bearer_tool.rb +159 -0
- data/examples/advanced/auth/oauth2_auth.rb +419 -0
- data/examples/advanced/auth/oidc_auth.rb +514 -0
- data/examples/advanced/auth/openweather_api.rb +251 -0
- data/examples/advanced/auth/openweather_tool.rb +153 -0
- data/examples/advanced/auth/query_param_middleware_test.rb +138 -0
- data/examples/advanced/auth/service_account.rb +135 -0
- data/examples/advanced/auth/test_with_httpbin.rb +202 -0
- data/examples/advanced/auth/token_lifecycle_example.rb +428 -0
- data/examples/advanced/callback_monitoring.rb +679 -0
- data/examples/advanced/mas/fixed_delegation_example.rb +191 -0
- data/examples/advanced/mas/loop_workflow.rb +28 -0
- data/examples/advanced/mas/mock_planner.rb +77 -0
- data/examples/advanced/mas/proper_delegation_example.rb +276 -0
- data/examples/advanced/mcp/legate_mcp_server_resource_example.rb +182 -0
- data/examples/advanced/mcp/mcp_resource_server_example.rb +309 -0
- data/examples/advanced/mcp/mcp_server_async.rb +76 -0
- data/examples/advanced/mcp/mcp_server_async_tools.rb +122 -0
- data/examples/advanced/mcp/mcp_server_legate_agent.rb +95 -0
- data/examples/advanced/mcp/mcp_server_rack.rb +89 -0
- data/examples/advanced/random_calculator.rb +104 -0
- data/examples/advanced/sleep_agent.rb +153 -0
- data/examples/advanced/webhooks/webhook_e2e_runner.rb +110 -0
- data/examples/advanced/webhooks/webhook_receiver_agent.rb +58 -0
- data/examples/advanced/workflows/task_refinement_loop_agent.rb +278 -0
- data/examples/advanced/workflows/travel_planner_auto_sequential.rb +444 -0
- data/examples/advanced/workflows/travel_planner_parallel.rb +656 -0
- data/examples/advanced/workflows/travel_planner_sequential.rb +512 -0
- data/examples/tools/oauth2_example.rb +136 -0
- data/examples/tools/sleepy_tool.rb +42 -0
- data/lib/legate/activity_log.rb +71 -0
- data/lib/legate/agent.rb +959 -0
- data/lib/legate/agent_code_generator.rb +185 -0
- data/lib/legate/agent_definition.rb +812 -0
- data/lib/legate/agentic/decision.rb +49 -0
- data/lib/legate/agentic/loop.rb +134 -0
- data/lib/legate/agentic.rb +5 -0
- data/lib/legate/agents/loop_agent.rb +248 -0
- data/lib/legate/agents/parallel_agent.rb +163 -0
- data/lib/legate/agents/sequential_agent.rb +190 -0
- data/lib/legate/agents.rb +14 -0
- data/lib/legate/auth/config.rb +148 -0
- data/lib/legate/auth/coordinator.rb +218 -0
- data/lib/legate/auth/coordinators/oauth2_coordinator.rb +99 -0
- data/lib/legate/auth/coordinators/oidc_coordinator.rb +68 -0
- data/lib/legate/auth/coordinators/service_account_coordinator.rb +122 -0
- data/lib/legate/auth/credential.rb +157 -0
- data/lib/legate/auth/encryption.rb +108 -0
- data/lib/legate/auth/error.rb +94 -0
- data/lib/legate/auth/exchanged_credential.rb +180 -0
- data/lib/legate/auth/excon_middleware.rb +285 -0
- data/lib/legate/auth/http_client_utils.rb +364 -0
- data/lib/legate/auth/manager.rb +531 -0
- data/lib/legate/auth/manager_store.rb +394 -0
- data/lib/legate/auth/middleware_factory.rb +290 -0
- data/lib/legate/auth/runner.rb +279 -0
- data/lib/legate/auth/scheme.rb +125 -0
- data/lib/legate/auth/schemes/api_key.rb +212 -0
- data/lib/legate/auth/schemes/google_service_account.rb +108 -0
- data/lib/legate/auth/schemes/http_bearer.rb +98 -0
- data/lib/legate/auth/schemes/oauth2.rb +396 -0
- data/lib/legate/auth/schemes/openid_connect.rb +346 -0
- data/lib/legate/auth/schemes/service_account.rb +388 -0
- data/lib/legate/auth/schemes.rb +40 -0
- data/lib/legate/auth/token_manager.rb +362 -0
- data/lib/legate/auth/token_store.rb +86 -0
- data/lib/legate/auth/tool_context_extension.rb +97 -0
- data/lib/legate/auth/tool_integration.rb +188 -0
- data/lib/legate/auth/url_guard.rb +81 -0
- data/lib/legate/auth.rb +453 -0
- data/lib/legate/callbacks/callback_context.rb +71 -0
- data/lib/legate/cli/agent_commands.rb +950 -0
- data/lib/legate/cli/auth_commands.rb +520 -0
- data/lib/legate/cli/base_command.rb +24 -0
- data/lib/legate/cli/deployment_commands.rb +934 -0
- data/lib/legate/cli/output_helper.rb +108 -0
- data/lib/legate/cli/session_commands.rb +138 -0
- data/lib/legate/cli/skaffold_commands.rb +223 -0
- data/lib/legate/cli/tool_commands.rb +261 -0
- data/lib/legate/cli/web_commands.rb +182 -0
- data/lib/legate/cli.rb +40 -0
- data/lib/legate/configuration/webhooks.rb +113 -0
- data/lib/legate/configuration.rb +39 -0
- data/lib/legate/definition_store.rb +23 -0
- data/lib/legate/errors.rb +118 -0
- data/lib/legate/event.rb +161 -0
- data/lib/legate/gemini_ai_beta_patch.rb +39 -0
- data/lib/legate/generators/agent_generator.rb +412 -0
- data/lib/legate/generators/code_validator.rb +48 -0
- data/lib/legate/generators/legate/install_generator.rb +35 -0
- data/lib/legate/generators/legate/templates/create_legate_tables.rb.tt +36 -0
- data/lib/legate/generators/legate/templates/initializer.rb +18 -0
- data/lib/legate/generators/runtime_tool_loader.rb +76 -0
- data/lib/legate/generators/tool_generator.rb +408 -0
- data/lib/legate/generators.rb +11 -0
- data/lib/legate/global_definition_registry.rb +506 -0
- data/lib/legate/global_tool_manager.rb +135 -0
- data/lib/legate/llm/adapter.rb +69 -0
- data/lib/legate/llm/gemini.rb +172 -0
- data/lib/legate/llm/ollama.rb +80 -0
- data/lib/legate/llm.rb +34 -0
- data/lib/legate/mcp/client.rb +320 -0
- data/lib/legate/mcp/connection/sse.rb +292 -0
- data/lib/legate/mcp/connection/stdio.rb +273 -0
- data/lib/legate/mcp/connection_manager.rb +103 -0
- data/lib/legate/mcp/server/legate_agent_adapter.rb +170 -0
- data/lib/legate/mcp/server/legate_direct_agent_adapter.rb +140 -0
- data/lib/legate/mcp/server/legate_tool_adapter.rb +119 -0
- data/lib/legate/mcp/tool_wrapper.rb +138 -0
- data/lib/legate/mcp/util/schema_converter.rb +134 -0
- data/lib/legate/mcp.rb +23 -0
- data/lib/legate/plan_executor.rb +375 -0
- data/lib/legate/planner.rb +839 -0
- data/lib/legate/rails/railtie.rb +43 -0
- data/lib/legate/rails.rb +9 -0
- data/lib/legate/redaction.rb +32 -0
- data/lib/legate/session.rb +299 -0
- data/lib/legate/session_service/active_record.rb +300 -0
- data/lib/legate/session_service/base.rb +68 -0
- data/lib/legate/session_service/event_broadcast.rb +74 -0
- data/lib/legate/session_service/in_memory.rb +188 -0
- data/lib/legate/tool/metadata_dsl.rb +122 -0
- data/lib/legate/tool.rb +276 -0
- data/lib/legate/tool_code_generator.rb +103 -0
- data/lib/legate/tool_context.rb +350 -0
- data/lib/legate/tool_loader.rb +39 -0
- data/lib/legate/tool_registry.rb +73 -0
- data/lib/legate/tool_result.rb +61 -0
- data/lib/legate/tools/agent_tool.rb +187 -0
- data/lib/legate/tools/base/http_client.rb +319 -0
- data/lib/legate/tools/base/safe_url.rb +56 -0
- data/lib/legate/tools/base_async_job_tool.rb +91 -0
- data/lib/legate/tools/calculator.rb +89 -0
- data/lib/legate/tools/cat_facts.rb +81 -0
- data/lib/legate/tools/check_job_status_tool.rb +48 -0
- data/lib/legate/tools/current_time_tool.rb +64 -0
- data/lib/legate/tools/echo.rb +43 -0
- data/lib/legate/tools/http_request_tool.rb +105 -0
- data/lib/legate/tools/random_number_tool.rb +64 -0
- data/lib/legate/tools/read_webpage_tool.rb +92 -0
- data/lib/legate/tools/sleepy_tool.rb +74 -0
- data/lib/legate/tools/webhook_tool.rb +146 -0
- data/lib/legate/version.rb +5 -0
- data/lib/legate/web/app.rb +984 -0
- data/lib/legate/web/public/css/main.css +4980 -0
- data/lib/legate/web/public/images/favicon-256.png +0 -0
- data/lib/legate/web/public/images/favicon-32.png +0 -0
- data/lib/legate/web/public/images/legate-logo-dark.png +0 -0
- data/lib/legate/web/public/images/legate-logo-light.png +0 -0
- data/lib/legate/web/public/js/legate.js +616 -0
- data/lib/legate/web/public/styles/main.scss +4402 -0
- data/lib/legate/web/routes/agent_authentication_routes.rb +530 -0
- data/lib/legate/web/routes/agent_definition_routes.rb +803 -0
- data/lib/legate/web/routes/agent_generator_routes.rb +80 -0
- data/lib/legate/web/routes/agent_interaction_routes.rb +734 -0
- data/lib/legate/web/routes/agent_runtime_routes.rb +323 -0
- data/lib/legate/web/routes/api_routes.rb +56 -0
- data/lib/legate/web/routes/authentication_routes.rb +1541 -0
- data/lib/legate/web/routes/core_routes.rb +111 -0
- data/lib/legate/web/routes/documentation_routes.rb +220 -0
- data/lib/legate/web/routes/tool_generator_routes.rb +81 -0
- data/lib/legate/web/routes/tools_ui_routes.rb +207 -0
- data/lib/legate/web/sass_compiler.rb +73 -0
- data/lib/legate/web/views/_active_session_info.slim +25 -0
- data/lib/legate/web/views/_activity_list.slim +55 -0
- data/lib/legate/web/views/_agent_card.slim +56 -0
- data/lib/legate/web/views/_agent_generator_modal.slim +382 -0
- data/lib/legate/web/views/_agent_status_controls.slim +71 -0
- data/lib/legate/web/views/_agent_tool_table.slim +74 -0
- data/lib/legate/web/views/_chat_message.slim +95 -0
- data/lib/legate/web/views/_display_agent_configuration.slim +26 -0
- data/lib/legate/web/views/_display_agent_description.slim +11 -0
- data/lib/legate/web/views/_display_agent_fallback.slim +15 -0
- data/lib/legate/web/views/_display_agent_hierarchy.slim +93 -0
- data/lib/legate/web/views/_display_agent_instruction.slim +17 -0
- data/lib/legate/web/views/_display_agent_mcp.slim +13 -0
- data/lib/legate/web/views/_display_agent_model.slim +17 -0
- data/lib/legate/web/views/_display_agent_name.slim +42 -0
- data/lib/legate/web/views/_display_agent_output_key.slim +26 -0
- data/lib/legate/web/views/_display_agent_type.slim +65 -0
- data/lib/legate/web/views/_edit_agent_configuration.slim +74 -0
- data/lib/legate/web/views/_edit_agent_description.slim +16 -0
- data/lib/legate/web/views/_edit_agent_fallback.slim +25 -0
- data/lib/legate/web/views/_edit_agent_hierarchy.slim +98 -0
- data/lib/legate/web/views/_edit_agent_instruction.slim +49 -0
- data/lib/legate/web/views/_edit_agent_mcp.slim +33 -0
- data/lib/legate/web/views/_edit_agent_model.slim +23 -0
- data/lib/legate/web/views/_edit_agent_output_key.slim +36 -0
- data/lib/legate/web/views/_edit_agent_tools.slim +40 -0
- data/lib/legate/web/views/_edit_agent_type.slim +67 -0
- data/lib/legate/web/views/_session_error.slim +4 -0
- data/lib/legate/web/views/_skeleton.slim +69 -0
- data/lib/legate/web/views/_tool_card.slim +9 -0
- data/lib/legate/web/views/_tool_generator_modal.slim +311 -0
- data/lib/legate/web/views/agent.slim +436 -0
- data/lib/legate/web/views/agent_auth.slim +562 -0
- data/lib/legate/web/views/agents.slim +369 -0
- data/lib/legate/web/views/auth.slim +112 -0
- data/lib/legate/web/views/auth_credential_detail.slim +327 -0
- data/lib/legate/web/views/auth_credentials.slim +261 -0
- data/lib/legate/web/views/auth_debug.slim +94 -0
- data/lib/legate/web/views/auth_mapping_detail.slim +151 -0
- data/lib/legate/web/views/auth_mapping_new.slim +123 -0
- data/lib/legate/web/views/auth_mappings.slim +120 -0
- data/lib/legate/web/views/auth_scheme_detail.slim +274 -0
- data/lib/legate/web/views/auth_schemes.slim +259 -0
- data/lib/legate/web/views/auth_test.slim +418 -0
- data/lib/legate/web/views/chat.slim +192 -0
- data/lib/legate/web/views/docs_index.slim +105 -0
- data/lib/legate/web/views/docs_show.slim +105 -0
- data/lib/legate/web/views/error_404.slim +5 -0
- data/lib/legate/web/views/index.slim +148 -0
- data/lib/legate/web/views/layout.slim +144 -0
- data/lib/legate/web/views/tool_detail.slim +87 -0
- data/lib/legate/web/views/tools.slim +50 -0
- data/lib/legate/web/webhook_listener.rb +367 -0
- data/lib/legate/web.rb +9 -0
- data/lib/legate.rb +220 -0
- data/public/docs/advanced/callbacks.md +828 -0
- data/public/docs/advanced/mcp_schema_conversion.md +59 -0
- data/public/docs/authentication/api_reference/config.md +210 -0
- data/public/docs/authentication/api_reference/credential.md +246 -0
- data/public/docs/authentication/api_reference/encryption.md +218 -0
- data/public/docs/authentication/api_reference/exchanged_credential.md +271 -0
- data/public/docs/authentication/api_reference/excon_middleware.md +175 -0
- data/public/docs/authentication/api_reference/index.md +30 -0
- data/public/docs/authentication/api_reference/scheme.md +250 -0
- data/public/docs/authentication/api_reference/schemes/api_key.md +175 -0
- data/public/docs/authentication/api_reference/schemes/google_service_account.md +221 -0
- data/public/docs/authentication/api_reference/schemes/http_bearer.md +169 -0
- data/public/docs/authentication/api_reference/schemes/oauth2.md +343 -0
- data/public/docs/authentication/api_reference/schemes/oidc.md +73 -0
- data/public/docs/authentication/api_reference/schemes/openid_connect.md +311 -0
- data/public/docs/authentication/api_reference/schemes/service_account.md +287 -0
- data/public/docs/authentication/api_reference/token_manager.md +221 -0
- data/public/docs/authentication/api_reference/token_store.md +146 -0
- data/public/docs/authentication/api_reference/tool_context_extension.md +166 -0
- data/public/docs/authentication/guides/api_key.md +190 -0
- data/public/docs/authentication/guides/bearer.md +172 -0
- data/public/docs/authentication/guides/configuration.md +255 -0
- data/public/docs/authentication/guides/custom_flow.md +523 -0
- data/public/docs/authentication/guides/index.md +24 -0
- data/public/docs/authentication/guides/migration.md +435 -0
- data/public/docs/authentication/guides/oauth2.md +252 -0
- data/public/docs/authentication/guides/oidc.md +241 -0
- data/public/docs/authentication/guides/overview.md +155 -0
- data/public/docs/authentication/guides/secure_storage.md +301 -0
- data/public/docs/authentication/guides/service_account.md +228 -0
- data/public/docs/authentication/guides/token_lifecycle.md +295 -0
- data/public/docs/authentication/guides/web_ui_integration.md +504 -0
- data/public/docs/authentication/index.md +58 -0
- data/public/docs/authentication/troubleshooting/credential_storage.md +550 -0
- data/public/docs/authentication/troubleshooting/environment_variables.md +540 -0
- data/public/docs/authentication/troubleshooting/index.md +11 -0
- data/public/docs/authentication/troubleshooting/oauth2_issues.md +220 -0
- data/public/docs/authentication/troubleshooting/oidc_issues.md +412 -0
- data/public/docs/authentication/troubleshooting/token_refresh.md +338 -0
- data/public/docs/cli/legate_cli_usage.md +363 -0
- data/public/docs/core_concepts/legate_agent_lifecycle.md +124 -0
- data/public/docs/core_concepts/legate_architecture_overview.md +110 -0
- data/public/docs/core_concepts/legate_configuration.md +116 -0
- data/public/docs/core_concepts/legate_definition_store.md +102 -0
- data/public/docs/core_concepts/legate_planner.md +94 -0
- data/public/docs/core_concepts/legate_session_service.md +104 -0
- data/public/docs/error_handling/legate_error_handling.md +122 -0
- data/public/docs/examples.md +199 -0
- data/public/docs/getting_started.md +111 -0
- data/public/docs/guides/agentic_agents.md +137 -0
- data/public/docs/guides/ai_code_generators.md +437 -0
- data/public/docs/guides/auto_loading.md +326 -0
- data/public/docs/guides/configuring_agent_webhooks.md +219 -0
- data/public/docs/guides/http_client_usage.md +264 -0
- data/public/docs/guides/llm_providers.md +137 -0
- data/public/docs/guides/mcp_client_integration.md +232 -0
- data/public/docs/guides/mcp_server_exposure.md +206 -0
- data/public/docs/guides/rails_integration.md +128 -0
- data/public/docs/guides/sending_outbound_webhooks.md +227 -0
- data/public/docs/guides/streaming.md +112 -0
- data/public/docs/guides/webhooks.md +288 -0
- data/public/docs/introduction.md +51 -0
- data/public/docs/multi_agent_systems/advanced_features.md +57 -0
- data/public/docs/multi_agent_systems/agent_delegation.md +190 -0
- data/public/docs/multi_agent_systems/agent_hierarchy.md +49 -0
- data/public/docs/multi_agent_systems/state_management.md +47 -0
- data/public/docs/multi_agent_systems/workflow_agents.md +72 -0
- data/public/docs/tools/legate_built_in_tools.md +332 -0
- data/public/docs/tools/legate_tools_and_registry.md +263 -0
- data/public/docs/web_ui/legate_web_ui.md +137 -0
- metadata +823 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Token Lifecycle Management
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `Legate::Auth::TokenManager` is responsible for managing the lifecycle of authentication tokens, including token storage, expiration handling, and automatic refresh. It serves as a critical component in the Legate authentication system, ensuring that valid tokens are always available for API requests.
|
|
6
|
+
|
|
7
|
+
## Class Definition
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
module Legate
|
|
11
|
+
module Auth
|
|
12
|
+
class TokenManager
|
|
13
|
+
# Token lifecycle management implementation
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Key Features
|
|
20
|
+
|
|
21
|
+
- Caching of authentication tokens via the token store
|
|
22
|
+
- Automatic token refresh before expiration
|
|
23
|
+
- Token validation and expiration checking
|
|
24
|
+
- Support for all token-based authentication schemes
|
|
25
|
+
- Event callbacks for token lifecycle events
|
|
26
|
+
- Integration with the Legate token store
|
|
27
|
+
|
|
28
|
+
## Constructor
|
|
29
|
+
|
|
30
|
+
### `new`
|
|
31
|
+
|
|
32
|
+
Creates a new token manager instance.
|
|
33
|
+
|
|
34
|
+
**Parameters:**
|
|
35
|
+
- `token_store` (Legate::Auth::TokenStore): The token store for persisting tokens (positional argument)
|
|
36
|
+
- `config` (Hash, optional): Configuration options (positional argument, default: {})
|
|
37
|
+
|
|
38
|
+
**Examples:**
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
# Create a token manager with a token store
|
|
42
|
+
token_store = Legate::Auth::TokenStore.new(session_service)
|
|
43
|
+
token_manager = Legate::Auth::TokenManager.new(token_store)
|
|
44
|
+
|
|
45
|
+
# With configuration options
|
|
46
|
+
token_manager = Legate::Auth::TokenManager.new(token_store, { refresh_buffer: 300 })
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Configuration keys** (with defaults):
|
|
50
|
+
|
|
51
|
+
| Key | Default | Description |
|
|
52
|
+
|-----|---------|-------------|
|
|
53
|
+
| `refresh_buffer` | `60` | Seconds before expiration to trigger refresh |
|
|
54
|
+
| `retry_max_attempts` | `3` | Maximum number of refresh retry attempts |
|
|
55
|
+
| `retry_delay` | `2` | Initial delay between retries (seconds) |
|
|
56
|
+
| `retry_backoff` | `1.5` | Backoff multiplier for subsequent retries |
|
|
57
|
+
| `auto_refresh` | `true` | Whether to automatically refresh tokens |
|
|
58
|
+
| `background_refresh` | `false` | Whether to refresh tokens in the background |
|
|
59
|
+
|
|
60
|
+
## Instance Methods
|
|
61
|
+
|
|
62
|
+
### `get_token`
|
|
63
|
+
|
|
64
|
+
Retrieves a valid token for the given scheme and credential, refreshing if necessary.
|
|
65
|
+
|
|
66
|
+
**Parameters:**
|
|
67
|
+
- `scheme` (Legate::Auth::Scheme): The authentication scheme
|
|
68
|
+
- `credential` (Legate::Auth::Credential): The credential to get a token for
|
|
69
|
+
- `force_refresh` (Boolean, optional): Force a token refresh even if the current token is valid (default: false)
|
|
70
|
+
|
|
71
|
+
**Returns:**
|
|
72
|
+
- Legate::Auth::ExchangedCredential: A valid token
|
|
73
|
+
|
|
74
|
+
**Examples:**
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
# Get a token (will auto-refresh if expired)
|
|
78
|
+
token = token_manager.get_token(scheme, credential)
|
|
79
|
+
|
|
80
|
+
# Force a fresh token
|
|
81
|
+
token = token_manager.get_token(scheme, credential, force_refresh: true)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `refresh_token`
|
|
85
|
+
|
|
86
|
+
Refreshes a token using the scheme's refresh mechanism.
|
|
87
|
+
|
|
88
|
+
**Parameters:**
|
|
89
|
+
- `scheme` (Legate::Auth::Scheme): The authentication scheme
|
|
90
|
+
- `credential` (Legate::Auth::Credential): The credential associated with the token
|
|
91
|
+
- `token` (Legate::Auth::ExchangedCredential, optional): The token to refresh (default: nil)
|
|
92
|
+
- `cache_key` (String, optional): The cache key for the token (default: nil)
|
|
93
|
+
|
|
94
|
+
**Returns:**
|
|
95
|
+
- Legate::Auth::ExchangedCredential: The refreshed token
|
|
96
|
+
|
|
97
|
+
**Examples:**
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
# Refresh a specific token
|
|
101
|
+
refreshed = token_manager.refresh_token(scheme, credential, token)
|
|
102
|
+
|
|
103
|
+
# Refresh with a cache key
|
|
104
|
+
refreshed = token_manager.refresh_token(scheme, credential, token, 'my_cache_key')
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `invalidate_token`
|
|
108
|
+
|
|
109
|
+
Invalidates a cached token, removing it from the store.
|
|
110
|
+
|
|
111
|
+
**Parameters:**
|
|
112
|
+
- `cache_key` (String): The cache key of the token to invalidate
|
|
113
|
+
|
|
114
|
+
**Examples:**
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
token_manager.invalidate_token('oauth2_client123')
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### `revoke_token`
|
|
121
|
+
|
|
122
|
+
Revokes a token using the scheme's revocation mechanism.
|
|
123
|
+
|
|
124
|
+
**Parameters:**
|
|
125
|
+
- `scheme` (Legate::Auth::Scheme): The authentication scheme
|
|
126
|
+
- `credential` (Legate::Auth::Credential): The credential associated with the token
|
|
127
|
+
- `token` (Legate::Auth::ExchangedCredential): The token to revoke
|
|
128
|
+
|
|
129
|
+
**Examples:**
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
token_manager.revoke_token(scheme, credential, token)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### `on`
|
|
136
|
+
|
|
137
|
+
Registers an event callback for token lifecycle events.
|
|
138
|
+
|
|
139
|
+
**Parameters:**
|
|
140
|
+
- `event` (Symbol): The event to listen for. Valid events are `:before_expiry`, `:refresh_success`, `:refresh_failure`, and `:invalidated`. Any other event raises `ArgumentError`.
|
|
141
|
+
- `&callback` (Block): The callback to invoke when the event occurs
|
|
142
|
+
|
|
143
|
+
Each callback receives a **single Hash** argument with keys including `:event`, `:token`, `:scheme`, `:credential` (plus event-specific extras such as `:error` for `:refresh_failure` or `:cache_key` for `:invalidated`).
|
|
144
|
+
|
|
145
|
+
**Examples:**
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
# Listen for successful token refreshes
|
|
149
|
+
token_manager.on(:refresh_success) do |data|
|
|
150
|
+
puts "Token refreshed for #{data[:scheme]&.scheme_type}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Listen for tokens approaching expiry
|
|
154
|
+
token_manager.on(:before_expiry) do |data|
|
|
155
|
+
puts "Token approaching expiration"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Listen for refresh failures
|
|
159
|
+
token_manager.on(:refresh_failure) do |data|
|
|
160
|
+
puts "Refresh failed: #{data[:error]&.message}"
|
|
161
|
+
end
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Usage
|
|
165
|
+
|
|
166
|
+
### Basic Usage
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
# Create a token store and manager
|
|
170
|
+
token_store = Legate::Auth::TokenStore.new(session_service)
|
|
171
|
+
token_manager = Legate::Auth::TokenManager.new(token_store)
|
|
172
|
+
|
|
173
|
+
# Get a token for an OAuth2 flow
|
|
174
|
+
token = token_manager.get_token(oauth2_scheme, oauth2_credential)
|
|
175
|
+
|
|
176
|
+
# Use the token
|
|
177
|
+
puts token[:access_token]
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### With Automatic Refresh
|
|
181
|
+
|
|
182
|
+
```ruby
|
|
183
|
+
# The token manager automatically refreshes expired tokens
|
|
184
|
+
token = token_manager.get_token(scheme, credential)
|
|
185
|
+
|
|
186
|
+
# If the token is expired and the scheme supports refresh,
|
|
187
|
+
# it will be automatically refreshed before being returned
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Token Structure
|
|
191
|
+
|
|
192
|
+
Tokens are stored as Legate::Auth::ExchangedCredential objects with attributes like:
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
{
|
|
196
|
+
access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
|
197
|
+
refresh_token: 'rtok_abc123...',
|
|
198
|
+
id_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', # Optional, for OIDC
|
|
199
|
+
token_type: 'Bearer',
|
|
200
|
+
expires_in: 3600
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Integration with Authentication Schemes
|
|
205
|
+
|
|
206
|
+
The token manager integrates with authentication schemes to handle scheme-specific token operations:
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
# OAuth2 token management
|
|
210
|
+
token = token_manager.get_token(oauth2_scheme, oauth2_credential)
|
|
211
|
+
|
|
212
|
+
# Service account token management
|
|
213
|
+
token = token_manager.get_token(service_account_scheme, sa_credential)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Related Classes
|
|
217
|
+
|
|
218
|
+
- [`Legate::Auth::TokenStore`](./token_store): Secure storage for tokens
|
|
219
|
+
- [`Legate::Auth::ExchangedCredential`](./exchanged_credential): Container for exchanged credentials
|
|
220
|
+
- [`Legate::Auth::Schemes::OAuth2`](./schemes/oauth2): OAuth2 authentication scheme
|
|
221
|
+
- [`Legate::Auth::ExconMiddleware`](./excon_middleware): HTTP client middleware
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Token Store
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `Legate::Auth::TokenStore` class caches authentication tokens in scoped session state (under the `auth` scope). It serves as the foundation for token management within the Legate authentication system.
|
|
6
|
+
|
|
7
|
+
> **Note:** `TokenStore` does **not** encrypt tokens. `store` persists the plaintext result of `token.to_h` into scoped state, and `get` reads it back as-is. For at-rest encryption, use the opt-in [`Legate::Auth::Encryption`](./encryption) module yourself.
|
|
8
|
+
|
|
9
|
+
## Class Definition
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
module Legate
|
|
13
|
+
module Auth
|
|
14
|
+
class TokenStore
|
|
15
|
+
# Token store implementation
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Key Features
|
|
22
|
+
|
|
23
|
+
- Caching of authentication tokens in scoped session state
|
|
24
|
+
- Automatic expiry check on retrieval (expired tokens are cleared and return `nil`)
|
|
25
|
+
- Integration with Legate session service
|
|
26
|
+
- Token retrieval by key
|
|
27
|
+
- Support for multiple token sets
|
|
28
|
+
|
|
29
|
+
## Constructor
|
|
30
|
+
|
|
31
|
+
### `new`
|
|
32
|
+
|
|
33
|
+
Creates a new token store instance.
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
- `session_service` (Legate::SessionService::Base): The session service for persisting token data (positional argument)
|
|
37
|
+
|
|
38
|
+
**Examples:**
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
# Create a token store with the session service
|
|
42
|
+
token_store = Legate::Auth::TokenStore.new(session_service)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Instance Methods
|
|
46
|
+
|
|
47
|
+
### `store`
|
|
48
|
+
|
|
49
|
+
Stores a token under the given key by serializing it with `token.to_h` and saving it to scoped state. Only `Legate::Auth::ExchangedCredential` instances are accepted; anything else returns `false`.
|
|
50
|
+
|
|
51
|
+
**Parameters:**
|
|
52
|
+
- `key` (String): The key to store the token under
|
|
53
|
+
- `token` (Legate::Auth::ExchangedCredential): The token to store
|
|
54
|
+
|
|
55
|
+
**Returns:**
|
|
56
|
+
- Boolean: `true` if the token was stored, `false` otherwise
|
|
57
|
+
|
|
58
|
+
**Examples:**
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
token_store.store('oauth2_client123', exchanged_credential)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `get`
|
|
65
|
+
|
|
66
|
+
Retrieves the token stored under the specified key, deserializing it back into an `ExchangedCredential`. If the stored token is expired it is cleared and `nil` is returned.
|
|
67
|
+
|
|
68
|
+
**Parameters:**
|
|
69
|
+
- `key` (String): The key to retrieve the token for
|
|
70
|
+
|
|
71
|
+
**Returns:**
|
|
72
|
+
- Legate::Auth::ExchangedCredential, or nil if not found or expired
|
|
73
|
+
|
|
74
|
+
**Examples:**
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
token = token_store.get('oauth2_client123')
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `clear`
|
|
81
|
+
|
|
82
|
+
Removes the token stored under the specified key.
|
|
83
|
+
|
|
84
|
+
**Parameters:**
|
|
85
|
+
- `key` (String): The key of the token to remove
|
|
86
|
+
|
|
87
|
+
**Examples:**
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
token_store.clear('oauth2_client123')
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `clear_all`
|
|
94
|
+
|
|
95
|
+
Removes all tokens from the token store.
|
|
96
|
+
|
|
97
|
+
**Examples:**
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
token_store.clear_all
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Token Storage and At-Rest Encryption
|
|
104
|
+
|
|
105
|
+
The token store persists tokens as plaintext `token.to_h` data in scoped session state. It does **not** encrypt them. The security of stored tokens therefore depends on the underlying session service (for example, in-memory storage in the default container deployment).
|
|
106
|
+
|
|
107
|
+
If you need at-rest encryption, apply the opt-in [`Legate::Auth::Encryption`](./encryption) module in your own storage layer (it requires the `rbnacl` gem and a Base64 key in `LEGATE_AUTH_ENCRYPTION_KEY`).
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
# Tokens are stored as-is (no automatic encryption)
|
|
111
|
+
token_store.store('client123', token)
|
|
112
|
+
|
|
113
|
+
# Retrieved as-is (expired tokens are cleared and return nil)
|
|
114
|
+
token = token_store.get('client123')
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Integration with Session Service
|
|
118
|
+
|
|
119
|
+
The token store integrates with the Legate session service to persist tokens across requests:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
# Create an in-memory session service
|
|
123
|
+
session_service = Legate::SessionService::InMemory.new
|
|
124
|
+
|
|
125
|
+
# Create a token store with the session service
|
|
126
|
+
token_store = Legate::Auth::TokenStore.new(session_service)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Usage with Token Manager
|
|
130
|
+
|
|
131
|
+
The token store is typically used via the `TokenManager` rather than directly:
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
# Create a token store and manager
|
|
135
|
+
token_store = Legate::Auth::TokenStore.new(session_service)
|
|
136
|
+
token_manager = Legate::Auth::TokenManager.new(token_store)
|
|
137
|
+
|
|
138
|
+
# The token manager uses the store internally
|
|
139
|
+
token = token_manager.get_token(scheme, credential)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Related Classes
|
|
143
|
+
|
|
144
|
+
- [`Legate::Auth::TokenManager`](./token_manager): Token lifecycle management
|
|
145
|
+
- [`Legate::Auth::Encryption`](./encryption): Opt-in encryption utilities (not wired into TokenStore)
|
|
146
|
+
- [`Legate::SessionService::Base`](../../core_concepts/legate_session_service): Base session service class
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Tool Context Authentication Extensions
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `Legate::Auth::ToolContextExtension` module extends the `Legate::ToolContext` class with authentication-specific functionality, allowing tools to easily access and manage authentication credentials. This extension is critical for tools that need to authenticate with external APIs.
|
|
6
|
+
|
|
7
|
+
## Module Definition
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
module Legate
|
|
11
|
+
module Auth
|
|
12
|
+
module ToolContextExtension
|
|
13
|
+
# Authentication extensions for ToolContext
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Key Features
|
|
20
|
+
|
|
21
|
+
- Access to authentication runners and token stores
|
|
22
|
+
- Managed authentication sessions
|
|
23
|
+
- Integration with interactive authentication flows
|
|
24
|
+
- Support for all authentication schemes
|
|
25
|
+
|
|
26
|
+
## Methods
|
|
27
|
+
|
|
28
|
+
### `auth_runner`
|
|
29
|
+
|
|
30
|
+
Returns the authentication runner for managing authentication flows.
|
|
31
|
+
|
|
32
|
+
**Returns:**
|
|
33
|
+
- The authentication runner instance
|
|
34
|
+
|
|
35
|
+
**Examples:**
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
# In a tool's implementation
|
|
39
|
+
runner = context.auth_runner
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `get_token_store`
|
|
43
|
+
|
|
44
|
+
Returns the token store for the current session.
|
|
45
|
+
|
|
46
|
+
**Returns:**
|
|
47
|
+
- Legate::Auth::TokenStore: The token store
|
|
48
|
+
|
|
49
|
+
**Examples:**
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
token_store = context.get_token_store
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### `with_authentication`
|
|
56
|
+
|
|
57
|
+
Wraps a block with authentication handling. If authentication is required, it will initiate the authentication flow and retry the block once authentication is complete.
|
|
58
|
+
|
|
59
|
+
**Parameters:**
|
|
60
|
+
- `&block` (Block): The block to execute with authentication
|
|
61
|
+
|
|
62
|
+
**Examples:**
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
# In a tool's implementation
|
|
66
|
+
def perform_execution(params, context)
|
|
67
|
+
context.with_authentication do
|
|
68
|
+
# Make authenticated API calls here
|
|
69
|
+
# If auth fails, the flow will be initiated automatically
|
|
70
|
+
response = make_api_request(context)
|
|
71
|
+
{ status: :success, result: response }
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `auth_session`
|
|
77
|
+
|
|
78
|
+
Creates an authentication session for the given scheme and credential.
|
|
79
|
+
|
|
80
|
+
**Parameters:**
|
|
81
|
+
- `scheme` (Legate::Auth::Scheme): The authentication scheme
|
|
82
|
+
- `credential` (Legate::Auth::Credential): The credential to use
|
|
83
|
+
- `**options` (Hash): Additional options for the authentication session
|
|
84
|
+
|
|
85
|
+
**Returns:**
|
|
86
|
+
- An authentication session object
|
|
87
|
+
|
|
88
|
+
**Examples:**
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
session = context.auth_session(oauth2_scheme, oauth2_credential)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `handle_auth_response`
|
|
95
|
+
|
|
96
|
+
Handles an authentication response from an interactive authentication flow (e.g., OAuth2 callback).
|
|
97
|
+
|
|
98
|
+
**Parameters:**
|
|
99
|
+
- `request_id` (String): The authentication request ID
|
|
100
|
+
- `response` (Hash): The authentication response data
|
|
101
|
+
|
|
102
|
+
**Examples:**
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# When the OAuth2 callback is received
|
|
106
|
+
context.handle_auth_response('req_123456', {
|
|
107
|
+
code: params[:code],
|
|
108
|
+
state: params[:state]
|
|
109
|
+
})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `cancel_auth_flow`
|
|
113
|
+
|
|
114
|
+
Cancels an in-progress authentication flow.
|
|
115
|
+
|
|
116
|
+
**Parameters:**
|
|
117
|
+
- `request_id` (String): The authentication request ID to cancel
|
|
118
|
+
- `reason` (String, optional): The reason for cancellation (default: nil)
|
|
119
|
+
|
|
120
|
+
**Examples:**
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
# Cancel an authentication flow
|
|
124
|
+
context.cancel_auth_flow('req_123456', 'User declined')
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Integration with Tool Implementation
|
|
128
|
+
|
|
129
|
+
Here's a complete example of how to use the tool context extensions in a custom tool:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
class MyApiTool < Legate::Tool
|
|
133
|
+
def perform_execution(params, context)
|
|
134
|
+
context.with_authentication do
|
|
135
|
+
# Get a token store for caching
|
|
136
|
+
token_store = context.get_token_store
|
|
137
|
+
|
|
138
|
+
# Create an auth session
|
|
139
|
+
session = context.auth_session(
|
|
140
|
+
Legate::Auth::Schemes::OAuth2.new(
|
|
141
|
+
authorization_url: 'https://auth.example.com/authorize',
|
|
142
|
+
token_url: 'https://auth.example.com/token'
|
|
143
|
+
),
|
|
144
|
+
Legate::Auth::Credential.new(
|
|
145
|
+
auth_type: :oauth2,
|
|
146
|
+
client_id: ENV['CLIENT_ID'],
|
|
147
|
+
client_secret: ENV['CLIENT_SECRET']
|
|
148
|
+
)
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Make authenticated API request
|
|
152
|
+
conn = Excon.new('https://api.example.com')
|
|
153
|
+
response = conn.get(path: '/data')
|
|
154
|
+
|
|
155
|
+
# Process response
|
|
156
|
+
{ result: JSON.parse(response.body) }
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Related Classes
|
|
163
|
+
|
|
164
|
+
- [`Legate::Auth::Config`](./config): Authentication configuration
|
|
165
|
+
- [`Legate::Auth::TokenManager`](./token_manager): Token lifecycle management
|
|
166
|
+
- [`Legate::Auth::Scheme`](./scheme): Base class for authentication schemes
|