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,504 @@
|
|
|
1
|
+
# Authentication Web UI Integration
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Legate Ruby library provides integration between the authentication system and the Web UI, enabling interactive authentication flows directly from the web interface. This guide explains how to integrate authentication with the Web UI and implement visual flows for authentication schemes like OAuth2 and OpenID Connect.
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
- Authentication status indicators in the Web UI
|
|
10
|
+
- Interactive login flows for OAuth2 and OIDC
|
|
11
|
+
- Token management interface for viewing and revoking tokens
|
|
12
|
+
- Secure credential storage in the browser
|
|
13
|
+
- Authentication debugging panels
|
|
14
|
+
|
|
15
|
+
## Web UI Authentication Components
|
|
16
|
+
|
|
17
|
+
### Authentication Status Indicator
|
|
18
|
+
|
|
19
|
+
The Legate Web UI includes an authentication status indicator that shows the current authentication state for tools requiring authentication:
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<!-- Authentication status indicator component -->
|
|
23
|
+
<div class="auth-status">
|
|
24
|
+
<span class="auth-status-icon authenticated"></span>
|
|
25
|
+
<span class="auth-status-text">Authenticated</span>
|
|
26
|
+
</div>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Login Interface
|
|
30
|
+
|
|
31
|
+
The Web UI provides a login interface for initiating authentication flows:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<!-- Login button for OAuth2 authentication -->
|
|
35
|
+
<button class="login-button" data-auth-scheme="oauth2">
|
|
36
|
+
Log in with OAuth2
|
|
37
|
+
</button>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Token Information Display
|
|
41
|
+
|
|
42
|
+
The Web UI includes a token information display for viewing active tokens:
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<!-- Token information display -->
|
|
46
|
+
<div class="token-info">
|
|
47
|
+
<div class="token-status">
|
|
48
|
+
<span class="label">Status:</span>
|
|
49
|
+
<span class="value">Valid</span>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="token-expiry">
|
|
52
|
+
<span class="label">Expires:</span>
|
|
53
|
+
<span class="value">2023-12-31 23:59:59 UTC</span>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="token-scopes">
|
|
56
|
+
<span class="label">Scopes:</span>
|
|
57
|
+
<span class="value">read write</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Interactive Authentication Flows
|
|
63
|
+
|
|
64
|
+
### OAuth2 Authentication Flow
|
|
65
|
+
|
|
66
|
+
The Web UI implements the OAuth2 authorization code flow with the following steps:
|
|
67
|
+
|
|
68
|
+
1. User clicks the login button for a tool requiring OAuth2 authentication
|
|
69
|
+
2. The Web UI displays a login popup or redirects to the OAuth2 provider
|
|
70
|
+
3. User completes authentication on the provider's site
|
|
71
|
+
4. The provider redirects back to the Legate callback URL
|
|
72
|
+
5. The Web UI captures the authorization code and exchanges it for tokens
|
|
73
|
+
6. The Web UI resumes the tool execution with the obtained tokens
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
// JavaScript for handling OAuth2 authentication flow
|
|
77
|
+
function initiateOAuth2Flow(authConfig) {
|
|
78
|
+
// Generate and store state parameter to prevent CSRF attacks
|
|
79
|
+
const state = generateSecureRandomString();
|
|
80
|
+
sessionStorage.setItem('oauth2_state', state);
|
|
81
|
+
|
|
82
|
+
// Construct the authorization URL
|
|
83
|
+
const authUrl = new URL(authConfig.authorizationUrl);
|
|
84
|
+
authUrl.searchParams.append('client_id', authConfig.clientId);
|
|
85
|
+
authUrl.searchParams.append('redirect_uri', authConfig.redirectUri);
|
|
86
|
+
authUrl.searchParams.append('response_type', 'code');
|
|
87
|
+
authUrl.searchParams.append('state', state);
|
|
88
|
+
if (authConfig.scopes) {
|
|
89
|
+
authUrl.searchParams.append('scope', authConfig.scopes.join(' '));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Open the authorization URL in a popup window
|
|
93
|
+
window.open(authUrl.toString(), 'oauth2_popup', 'width=600,height=700');
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### OAuth2 Callback Handling
|
|
98
|
+
|
|
99
|
+
The Web UI includes a callback endpoint for handling OAuth2 redirects:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
# Ruby route for handling OAuth2 callbacks
|
|
103
|
+
get '/auth/callback' do
|
|
104
|
+
# Verify state parameter to prevent CSRF attacks
|
|
105
|
+
client_state = request.params['state']
|
|
106
|
+
server_state = session[:oauth2_state]
|
|
107
|
+
halt 403, 'Invalid state parameter' unless client_state && client_state == server_state
|
|
108
|
+
|
|
109
|
+
# Get the authorization code from the callback
|
|
110
|
+
code = request.params['code']
|
|
111
|
+
halt 400, 'Missing authorization code' unless code
|
|
112
|
+
|
|
113
|
+
# Store the authorization code in the session
|
|
114
|
+
session[:auth_code] = code
|
|
115
|
+
session[:auth_response_uri] = request.url
|
|
116
|
+
|
|
117
|
+
# Close the popup window and notify the parent window
|
|
118
|
+
<<-HTML
|
|
119
|
+
<script>
|
|
120
|
+
window.opener.postMessage({ type: 'auth_callback', code: '#{code}' }, window.location.origin);
|
|
121
|
+
window.close();
|
|
122
|
+
</script>
|
|
123
|
+
HTML
|
|
124
|
+
end
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Token Management
|
|
128
|
+
|
|
129
|
+
### Token Management Interface
|
|
130
|
+
|
|
131
|
+
The Web UI provides a token management interface for viewing and managing active tokens:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<!-- Token management interface -->
|
|
135
|
+
<div class="token-management">
|
|
136
|
+
<h2>Active Tokens</h2>
|
|
137
|
+
<table class="token-table">
|
|
138
|
+
<thead>
|
|
139
|
+
<tr>
|
|
140
|
+
<th>API</th>
|
|
141
|
+
<th>Status</th>
|
|
142
|
+
<th>Expires</th>
|
|
143
|
+
<th>Actions</th>
|
|
144
|
+
</tr>
|
|
145
|
+
</thead>
|
|
146
|
+
<tbody>
|
|
147
|
+
<tr>
|
|
148
|
+
<td>Google Drive API</td>
|
|
149
|
+
<td>Valid</td>
|
|
150
|
+
<td>2023-12-31 23:59:59 UTC</td>
|
|
151
|
+
<td>
|
|
152
|
+
<button class="refresh-token-button">Refresh</button>
|
|
153
|
+
<button class="revoke-token-button">Revoke</button>
|
|
154
|
+
</td>
|
|
155
|
+
</tr>
|
|
156
|
+
</tbody>
|
|
157
|
+
</table>
|
|
158
|
+
</div>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Token Refresh
|
|
162
|
+
|
|
163
|
+
The Web UI allows users to manually refresh tokens:
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
// JavaScript for handling token refresh
|
|
167
|
+
async function refreshToken(credentialId) {
|
|
168
|
+
try {
|
|
169
|
+
const response = await fetch('/api/auth/refresh', {
|
|
170
|
+
method: 'POST',
|
|
171
|
+
headers: {
|
|
172
|
+
'Content-Type': 'application/json'
|
|
173
|
+
},
|
|
174
|
+
body: JSON.stringify({ credential_id: credentialId })
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
throw new Error('Failed to refresh token');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const result = await response.json();
|
|
182
|
+
updateTokenDisplay(result.tokens);
|
|
183
|
+
showNotification('Token refreshed successfully');
|
|
184
|
+
} catch (error) {
|
|
185
|
+
showErrorNotification('Failed to refresh token: ' + error.message);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Token Revocation
|
|
191
|
+
|
|
192
|
+
The Web UI allows users to revoke tokens:
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
// JavaScript for handling token revocation
|
|
196
|
+
async function revokeToken(credentialId) {
|
|
197
|
+
if (!confirm('Are you sure you want to revoke this token? You will need to authenticate again.')) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const response = await fetch('/api/auth/revoke', {
|
|
203
|
+
method: 'POST',
|
|
204
|
+
headers: {
|
|
205
|
+
'Content-Type': 'application/json'
|
|
206
|
+
},
|
|
207
|
+
body: JSON.stringify({ credential_id: credentialId })
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
throw new Error('Failed to revoke token');
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
updateTokenDisplay(null);
|
|
215
|
+
showNotification('Token revoked successfully');
|
|
216
|
+
} catch (error) {
|
|
217
|
+
showErrorNotification('Failed to revoke token: ' + error.message);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Security Features
|
|
223
|
+
|
|
224
|
+
### Secure Credential Storage
|
|
225
|
+
|
|
226
|
+
The Web UI securely stores authentication credentials in the browser:
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// JavaScript for secure credential storage
|
|
230
|
+
class SecureStorage {
|
|
231
|
+
constructor() {
|
|
232
|
+
// Initialize secure storage
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Store sensitive data securely
|
|
236
|
+
async store(key, value) {
|
|
237
|
+
// Use browser's Web Crypto API to encrypt data
|
|
238
|
+
const encryptedData = await this.encrypt(JSON.stringify(value));
|
|
239
|
+
localStorage.setItem(key, encryptedData);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Retrieve and decrypt sensitive data
|
|
243
|
+
async retrieve(key) {
|
|
244
|
+
const encryptedData = localStorage.getItem(key);
|
|
245
|
+
if (!encryptedData) return null;
|
|
246
|
+
|
|
247
|
+
try {
|
|
248
|
+
const decryptedData = await this.decrypt(encryptedData);
|
|
249
|
+
return JSON.parse(decryptedData);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error('Failed to decrypt data:', error);
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Encryption/decryption methods
|
|
257
|
+
// ...
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### CSRF Protection
|
|
262
|
+
|
|
263
|
+
The Web UI implements CSRF protection for authentication flows:
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
// JavaScript for CSRF protection
|
|
267
|
+
function generateSecureRandomString(length = 32) {
|
|
268
|
+
const array = new Uint8Array(length);
|
|
269
|
+
window.crypto.getRandomValues(array);
|
|
270
|
+
return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Developer Tools
|
|
275
|
+
|
|
276
|
+
### Authentication Debugging Panel
|
|
277
|
+
|
|
278
|
+
The Web UI includes an authentication debugging panel for troubleshooting:
|
|
279
|
+
|
|
280
|
+
```html
|
|
281
|
+
<!-- Authentication debugging panel -->
|
|
282
|
+
<div class="auth-debugging-panel">
|
|
283
|
+
<h2>Authentication Debugging</h2>
|
|
284
|
+
<div class="debug-section">
|
|
285
|
+
<h3>Current Authentication State</h3>
|
|
286
|
+
<pre id="auth-state-debug"></pre>
|
|
287
|
+
</div>
|
|
288
|
+
<div class="debug-section">
|
|
289
|
+
<h3>Authentication Logs</h3>
|
|
290
|
+
<pre id="auth-logs-debug"></pre>
|
|
291
|
+
</div>
|
|
292
|
+
<div class="debug-actions">
|
|
293
|
+
<button id="clear-auth-logs">Clear Logs</button>
|
|
294
|
+
<button id="copy-auth-logs">Copy Logs</button>
|
|
295
|
+
<button id="clear-auth-tokens">Clear All Tokens</button>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Authentication Flow Visualization
|
|
301
|
+
|
|
302
|
+
The Web UI provides a visualization of the authentication flow:
|
|
303
|
+
|
|
304
|
+
```html
|
|
305
|
+
<!-- Authentication flow visualization -->
|
|
306
|
+
<div class="auth-flow-visualization">
|
|
307
|
+
<div class="flow-step" data-step="1">
|
|
308
|
+
<div class="step-number">1</div>
|
|
309
|
+
<div class="step-description">Client requests protected resource</div>
|
|
310
|
+
</div>
|
|
311
|
+
<div class="flow-arrow">→</div>
|
|
312
|
+
<div class="flow-step" data-step="2">
|
|
313
|
+
<div class="step-number">2</div>
|
|
314
|
+
<div class="step-description">Legate yields for authentication</div>
|
|
315
|
+
</div>
|
|
316
|
+
<div class="flow-arrow">→</div>
|
|
317
|
+
<div class="flow-step active" data-step="3">
|
|
318
|
+
<div class="step-number">3</div>
|
|
319
|
+
<div class="step-description">User authenticates with provider</div>
|
|
320
|
+
</div>
|
|
321
|
+
<div class="flow-arrow">→</div>
|
|
322
|
+
<div class="flow-step" data-step="4">
|
|
323
|
+
<div class="step-number">4</div>
|
|
324
|
+
<div class="step-description">Legate exchanges code for tokens</div>
|
|
325
|
+
</div>
|
|
326
|
+
<div class="flow-arrow">→</div>
|
|
327
|
+
<div class="flow-step" data-step="5">
|
|
328
|
+
<div class="step-number">5</div>
|
|
329
|
+
<div class="step-description">Legate resumes with valid tokens</div>
|
|
330
|
+
</div>
|
|
331
|
+
</div>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Integration with Legate Core
|
|
335
|
+
|
|
336
|
+
### A Web UI Authentication Coordinator (illustrative)
|
|
337
|
+
|
|
338
|
+
Legate does not ship a `WebUIAuthenticationCoordinator` class. The pattern below
|
|
339
|
+
is an **illustrative coordinator you implement yourself** to bridge your web app
|
|
340
|
+
and the core `Legate::Auth::Config` flow. It uses the real `Config` API:
|
|
341
|
+
`config.auth_request_id`, `config.build_authorization_uri(redirect_uri, state)`,
|
|
342
|
+
`config.scheme.scheme_type`, and setting `config.response_uri` on the callback.
|
|
343
|
+
|
|
344
|
+
```ruby
|
|
345
|
+
# Your own coordinator class (not provided by Legate)
|
|
346
|
+
class WebUIAuthenticationCoordinator
|
|
347
|
+
def initialize(app)
|
|
348
|
+
@app = app
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def handle_auth_request(auth_config)
|
|
352
|
+
# Build the authorization URI (this generates and returns the state)
|
|
353
|
+
state = SecureRandom.hex(16)
|
|
354
|
+
auth_uri = auth_config.build_authorization_uri(@app.url('/auth/callback'), state)
|
|
355
|
+
@app.session[:oauth2_state] = auth_config.state
|
|
356
|
+
|
|
357
|
+
{
|
|
358
|
+
auth_request_id: auth_config.auth_request_id,
|
|
359
|
+
auth_type: auth_config.scheme.scheme_type,
|
|
360
|
+
authorization_url: auth_uri,
|
|
361
|
+
redirect_uri: @app.url('/auth/callback'),
|
|
362
|
+
scopes: auth_config.scheme.scopes,
|
|
363
|
+
state: auth_config.state
|
|
364
|
+
}
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def handle_auth_response(auth_config, params)
|
|
368
|
+
# Set the response URI on the original request config, then exchange
|
|
369
|
+
auth_config.response_uri = params[:auth_response_uri]
|
|
370
|
+
auth_config
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Complete Example: OAuth2 Authentication in Web UI
|
|
376
|
+
|
|
377
|
+
Here's a complete example of implementing OAuth2 authentication in the Legate Web UI:
|
|
378
|
+
|
|
379
|
+
```ruby
|
|
380
|
+
# Server-side route for handling authentication requests
|
|
381
|
+
post '/api/auth/request' do
|
|
382
|
+
content_type :json
|
|
383
|
+
|
|
384
|
+
# Get the authentication configuration from the request
|
|
385
|
+
auth_config = session[:auth_config]
|
|
386
|
+
halt 400, { error: 'No authentication request pending' }.to_json unless auth_config
|
|
387
|
+
|
|
388
|
+
# Prepare client-side configuration using your own coordinator
|
|
389
|
+
coordinator = WebUIAuthenticationCoordinator.new(self)
|
|
390
|
+
client_config = coordinator.handle_auth_request(auth_config)
|
|
391
|
+
|
|
392
|
+
client_config.to_json
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
# Server-side route for handling authentication responses
|
|
396
|
+
post '/api/auth/response' do
|
|
397
|
+
content_type :json
|
|
398
|
+
|
|
399
|
+
# Get parameters from the request
|
|
400
|
+
params = JSON.parse(request.body.read, symbolize_names: true)
|
|
401
|
+
|
|
402
|
+
# Validate the parameters
|
|
403
|
+
halt 400, { error: 'Missing auth_request_id' }.to_json unless params[:auth_request_id]
|
|
404
|
+
halt 400, { error: 'Missing auth_response_uri' }.to_json unless params[:auth_response_uri]
|
|
405
|
+
|
|
406
|
+
# Handle the authentication response using your own coordinator
|
|
407
|
+
coordinator = WebUIAuthenticationCoordinator.new(self)
|
|
408
|
+
auth_config = session[:auth_config]
|
|
409
|
+
auth_response = coordinator.handle_auth_response(auth_config, params)
|
|
410
|
+
|
|
411
|
+
# Store the response in the session for the next step in your flow
|
|
412
|
+
session[:auth_response] = auth_response
|
|
413
|
+
|
|
414
|
+
{ success: true }.to_json
|
|
415
|
+
end
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
With corresponding client-side JavaScript:
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
// Function to handle authentication requests from the server
|
|
422
|
+
async function handleAuthRequest() {
|
|
423
|
+
try {
|
|
424
|
+
const response = await fetch('/api/auth/request', {
|
|
425
|
+
method: 'POST',
|
|
426
|
+
headers: {
|
|
427
|
+
'Content-Type': 'application/json'
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
if (!response.ok) {
|
|
432
|
+
throw new Error('Failed to get authentication configuration');
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const authConfig = await response.json();
|
|
436
|
+
|
|
437
|
+
// Open the authorization popup
|
|
438
|
+
initiateOAuth2Flow(authConfig);
|
|
439
|
+
} catch (error) {
|
|
440
|
+
showErrorNotification('Authentication error: ' + error.message);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Function to handle authentication callbacks
|
|
445
|
+
async function handleAuthCallback(code, state) {
|
|
446
|
+
// Get the stored auth config
|
|
447
|
+
const authConfig = JSON.parse(sessionStorage.getItem('auth_config'));
|
|
448
|
+
if (!authConfig) {
|
|
449
|
+
showErrorNotification('No authentication in progress');
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Verify state parameter
|
|
454
|
+
if (state !== authConfig.state) {
|
|
455
|
+
showErrorNotification('Invalid state parameter');
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Send the authentication response to the server
|
|
460
|
+
try {
|
|
461
|
+
const response = await fetch('/api/auth/response', {
|
|
462
|
+
method: 'POST',
|
|
463
|
+
headers: {
|
|
464
|
+
'Content-Type': 'application/json'
|
|
465
|
+
},
|
|
466
|
+
body: JSON.stringify({
|
|
467
|
+
auth_request_id: authConfig.auth_request_id,
|
|
468
|
+
auth_response_uri: `${authConfig.redirect_uri}?code=${code}&state=${state}`,
|
|
469
|
+
redirect_uri: authConfig.redirect_uri
|
|
470
|
+
})
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
if (!response.ok) {
|
|
474
|
+
throw new Error('Failed to send authentication response');
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
showNotification('Authentication successful');
|
|
478
|
+
|
|
479
|
+
// Clear the stored auth config
|
|
480
|
+
sessionStorage.removeItem('auth_config');
|
|
481
|
+
|
|
482
|
+
// Reload the tools to reflect the authenticated state
|
|
483
|
+
loadTools();
|
|
484
|
+
} catch (error) {
|
|
485
|
+
showErrorNotification('Authentication error: ' + error.message);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Event listener for authentication callbacks from popup window
|
|
490
|
+
window.addEventListener('message', function(event) {
|
|
491
|
+
if (event.origin !== window.location.origin) return;
|
|
492
|
+
|
|
493
|
+
if (event.data.type === 'auth_callback' && event.data.code) {
|
|
494
|
+
handleAuthCallback(event.data.code, event.data.state);
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
## Related Topics
|
|
500
|
+
|
|
501
|
+
- [OAuth2 Authentication Guide](./oauth2)
|
|
502
|
+
- [OpenID Connect Guide](./oidc)
|
|
503
|
+
- [Token Lifecycle Management](./token_lifecycle)
|
|
504
|
+
- [Legate Web UI Documentation](../../web_ui/legate_web_ui)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Authentication in Legate Ruby
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Legate Ruby library provides a comprehensive framework for handling various authentication schemes required by external APIs. It supports common authentication methods including API Keys, OAuth2, OpenID Connect (OIDC), and Service Accounts, with a unified interface for both interactive and non-interactive flows.
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
- **Multiple Authentication Schemes**: Support for API Keys, HTTP Bearer tokens, OAuth2, OpenID Connect, and Service Account authentication
|
|
10
|
+
- **Interactive Flows**: Fiber-based control flow for OAuth2 and OIDC authentication requiring user interaction
|
|
11
|
+
- **Non-Interactive Flows**: Streamlined handling of API Keys, Bearer tokens, and Service Accounts
|
|
12
|
+
- **Scoped Storage**: Tokens cached in scoped session state, with opt-in at-rest encryption via `Legate::Auth::Encryption`
|
|
13
|
+
- **Token Lifecycle**: Automatic management of token expiration, refresh, and invalidation
|
|
14
|
+
- **Middleware Integration**: Seamless integration with HTTP clients (Excon) for attaching auth to tool requests
|
|
15
|
+
- **Middleware Support**: Excon middleware for automatic authentication header injection
|
|
16
|
+
|
|
17
|
+
## Core Components
|
|
18
|
+
|
|
19
|
+
- **`Legate::Auth::Scheme`**: Abstract base class defining how APIs expect credentials
|
|
20
|
+
- **`Legate::Auth::Credential`**: Container for initial authentication information
|
|
21
|
+
- **`Legate::Auth::Config`**: Configuration for the authentication flow
|
|
22
|
+
- **`Legate::Auth::ExchangedCredential`**: Container for exchanged tokens and state
|
|
23
|
+
- **`Legate::Auth::TokenManager`**: Handles token lifecycle management
|
|
24
|
+
- **`Legate::Auth::Encryption`**: Optional, opt-in module for encrypting sensitive credential data at rest
|
|
25
|
+
|
|
26
|
+
## Authentication Flows
|
|
27
|
+
|
|
28
|
+
1. **Interactive Flow** (OAuth2/OIDC)
|
|
29
|
+
- Tool requires authentication → Legate detects missing credentials
|
|
30
|
+
- Legate yields control to client application with auth URL
|
|
31
|
+
- User completes authentication in browser
|
|
32
|
+
- Client application resumes Legate execution with auth code
|
|
33
|
+
- Legate exchanges code for tokens and retries the original request
|
|
34
|
+
|
|
35
|
+
2. **Non-Interactive Flow** (API Key/Bearer Token)
|
|
36
|
+
- Tool is configured with credentials upfront
|
|
37
|
+
- Legate automatically includes credentials in API requests
|
|
38
|
+
- No user interaction required
|
|
39
|
+
|
|
40
|
+
3. **Service Account Flow**
|
|
41
|
+
- Tool is configured with service account credentials
|
|
42
|
+
- Legate automatically exchanges for access tokens
|
|
43
|
+
- Legate handles token refresh when needed
|
|
44
|
+
|
|
45
|
+
## Documentation Sections
|
|
46
|
+
|
|
47
|
+
- [Guides](./guides/index): Detailed guides for implementing authentication
|
|
48
|
+
- [API Reference](./api_reference/index): Documentation of all authentication classes and methods
|
|
49
|
+
- [Troubleshooting](./troubleshooting/index): Solutions for common authentication issues
|
|
50
|
+
|
|
51
|
+
## Getting Started
|
|
52
|
+
|
|
53
|
+
For most cases, you'll want to start with the [Authentication Overview Guide](./guides/overview) to understand the basic concepts, then follow the specific guide for your authentication needs:
|
|
54
|
+
|
|
55
|
+
- [API Key Authentication](./guides/api_key)
|
|
56
|
+
- [OAuth2 Authentication](./guides/oauth2)
|
|
57
|
+
- [OpenID Connect](./guides/oidc)
|
|
58
|
+
- [Service Account Authentication](./guides/service_account)
|