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,540 @@
|
|
|
1
|
+
# Environment Variable Management
|
|
2
|
+
|
|
3
|
+
This guide covers best practices and troubleshooting for environment variables used with the Legate Ruby library's authentication system.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Legate Ruby library uses environment variables for storing sensitive credentials and configuration settings. This approach separates sensitive data from your code, improving security and making your application more portable across different environments.
|
|
8
|
+
|
|
9
|
+
## Environment Variable Best Practices
|
|
10
|
+
|
|
11
|
+
### Naming Conventions
|
|
12
|
+
|
|
13
|
+
Use consistent naming conventions for your environment variables:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
# Preferred naming pattern
|
|
17
|
+
CLIENT_ID # General purpose
|
|
18
|
+
GOOGLE_CLIENT_ID # Provider-specific
|
|
19
|
+
DEV_CLIENT_ID # Environment-specific
|
|
20
|
+
DEV_GOOGLE_CLIENT_ID # Environment and provider-specific
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Security Considerations
|
|
24
|
+
|
|
25
|
+
1. **Never Commit Environment Variables**:
|
|
26
|
+
```bash
|
|
27
|
+
# Add environment files to .gitignore
|
|
28
|
+
echo ".env" >> .gitignore
|
|
29
|
+
echo ".env.*" >> .gitignore
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
2. **Use Different Values Across Environments**:
|
|
33
|
+
```bash
|
|
34
|
+
# Development environment
|
|
35
|
+
export DEV_CLIENT_ID="dev-client-id"
|
|
36
|
+
export DEV_CLIENT_SECRET="dev-client-secret"
|
|
37
|
+
|
|
38
|
+
# Production environment
|
|
39
|
+
export PROD_CLIENT_ID="prod-client-id"
|
|
40
|
+
export PROD_CLIENT_SECRET="prod-client-secret"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. **Limit Access to Environment Variables**:
|
|
44
|
+
```bash
|
|
45
|
+
# Set restrictive permissions on environment files
|
|
46
|
+
chmod 600 .env
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Common Issues and Solutions
|
|
50
|
+
|
|
51
|
+
### Missing Environment Variables
|
|
52
|
+
|
|
53
|
+
**Symptoms:**
|
|
54
|
+
- "Environment variable not found" errors
|
|
55
|
+
- Authentication failing with no clear error
|
|
56
|
+
|
|
57
|
+
**Possible Causes and Solutions:**
|
|
58
|
+
|
|
59
|
+
1. **Environment File Not Loaded**
|
|
60
|
+
```ruby
|
|
61
|
+
# Problem: .env file not loaded
|
|
62
|
+
|
|
63
|
+
# Solution: Use a library like dotenv
|
|
64
|
+
require 'dotenv'
|
|
65
|
+
Dotenv.load # Load .env file
|
|
66
|
+
|
|
67
|
+
# Or load environment-specific files
|
|
68
|
+
Dotenv.load(".env.#{ENV['RACK_ENV'] || 'development'}")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Environment Variable Not Set in Current Shell**
|
|
72
|
+
```bash
|
|
73
|
+
# Problem: Variable set in one shell but not available in another
|
|
74
|
+
|
|
75
|
+
# Solution: Verify the variable is set in the current shell
|
|
76
|
+
echo $CLIENT_ID
|
|
77
|
+
|
|
78
|
+
# If not set, set it:
|
|
79
|
+
export CLIENT_ID="your-client-id"
|
|
80
|
+
|
|
81
|
+
# Add to shell profile for persistence:
|
|
82
|
+
echo 'export CLIENT_ID="your-client-id"' >> ~/.bash_profile
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
3. **Environment Variables in Production**
|
|
86
|
+
```ruby
|
|
87
|
+
# Problem: Environment variables not set in production environment
|
|
88
|
+
|
|
89
|
+
# Solution: Set environment variables at the system or container level
|
|
90
|
+
|
|
91
|
+
# For Heroku:
|
|
92
|
+
# heroku config:set CLIENT_ID=your-client-id
|
|
93
|
+
|
|
94
|
+
# For Docker:
|
|
95
|
+
# docker run -e CLIENT_ID=your-client-id -e CLIENT_SECRET=your-client-secret your-app
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Environment Variable Resolution
|
|
99
|
+
|
|
100
|
+
**Symptoms:**
|
|
101
|
+
- Authentication failing with credential errors
|
|
102
|
+
- Environment variables not being properly resolved
|
|
103
|
+
|
|
104
|
+
**Possible Causes and Solutions:**
|
|
105
|
+
|
|
106
|
+
1. **Incorrect Reference Format**
|
|
107
|
+
```ruby
|
|
108
|
+
# Problem: Incorrect environment variable reference format
|
|
109
|
+
|
|
110
|
+
# Solution: Use the correct 'ENV:' prefix
|
|
111
|
+
|
|
112
|
+
# Incorrect:
|
|
113
|
+
credential = Legate::Auth::Credential.new(
|
|
114
|
+
auth_type: :oauth2,
|
|
115
|
+
client_id: "$CLIENT_ID", # Wrong format
|
|
116
|
+
client_secret: "${CLIENT_SECRET}" # Wrong format
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Correct:
|
|
120
|
+
credential = Legate::Auth::Credential.new(
|
|
121
|
+
auth_type: :oauth2,
|
|
122
|
+
client_id: "ENV:CLIENT_ID", # Correct format
|
|
123
|
+
client_secret: "ENV:CLIENT_SECRET" # Correct format
|
|
124
|
+
)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
2. **Case Sensitivity Issues**
|
|
128
|
+
```ruby
|
|
129
|
+
# Problem: Environment variable case mismatch
|
|
130
|
+
|
|
131
|
+
# Solution: Use consistent case
|
|
132
|
+
|
|
133
|
+
# If environment variable is defined as:
|
|
134
|
+
# export CLIENT_ID="your-client-id"
|
|
135
|
+
|
|
136
|
+
# This won't work:
|
|
137
|
+
credential = Legate::Auth::Credential.new(
|
|
138
|
+
auth_type: :oauth2,
|
|
139
|
+
client_id: "ENV:client_id" # Wrong case
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# This will work:
|
|
143
|
+
credential = Legate::Auth::Credential.new(
|
|
144
|
+
auth_type: :oauth2,
|
|
145
|
+
client_id: "ENV:CLIENT_ID" # Correct case
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
3. **Debug Environment Variable Resolution**
|
|
150
|
+
```ruby
|
|
151
|
+
# To debug environment variable resolution:
|
|
152
|
+
def debug_env_var(name)
|
|
153
|
+
puts "Checking environment variable: #{name}"
|
|
154
|
+
|
|
155
|
+
if ENV[name]
|
|
156
|
+
puts "✓ Environment variable is set"
|
|
157
|
+
puts "Value length: #{ENV[name].length} characters"
|
|
158
|
+
puts "Value preview: #{ENV[name][0..5]}..." if ENV[name].length > 0
|
|
159
|
+
else
|
|
160
|
+
puts "✗ Environment variable is NOT set"
|
|
161
|
+
puts "Available env vars: #{ENV.keys.grep(/#{name}/i).join(', ')}"
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Usage:
|
|
166
|
+
debug_env_var('CLIENT_ID')
|
|
167
|
+
debug_env_var('CLIENT_SECRET')
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Service Account JSON in Environment Variables
|
|
171
|
+
|
|
172
|
+
**Symptoms:**
|
|
173
|
+
- JSON parsing errors with service account keys
|
|
174
|
+
- Malformed service account credentials
|
|
175
|
+
|
|
176
|
+
**Possible Causes and Solutions:**
|
|
177
|
+
|
|
178
|
+
1. **Escaping Issues**
|
|
179
|
+
```ruby
|
|
180
|
+
# Problem: JSON escaping issues in the environment variable
|
|
181
|
+
|
|
182
|
+
# Solution: Properly escape the JSON string
|
|
183
|
+
|
|
184
|
+
# Incorrect (newlines and quotes will cause issues):
|
|
185
|
+
# export SERVICE_ACCOUNT_JSON='{"private_key":"-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n"}'
|
|
186
|
+
|
|
187
|
+
# Better approach - base64 encode the JSON:
|
|
188
|
+
# 1. Encode the file to base64
|
|
189
|
+
base64_key=$(base64 -i service-account-key.json)
|
|
190
|
+
|
|
191
|
+
# 2. Set the environment variable with the base64 string
|
|
192
|
+
export SERVICE_ACCOUNT_JSON_BASE64="$base64_key"
|
|
193
|
+
|
|
194
|
+
# 3. In your code, decode the base64 string
|
|
195
|
+
require 'base64'
|
|
196
|
+
json_string = Base64.decode64(ENV['SERVICE_ACCOUNT_JSON_BASE64'])
|
|
197
|
+
|
|
198
|
+
credential = Legate::Auth::Credential.new(
|
|
199
|
+
auth_type: :service_account,
|
|
200
|
+
service_account_key: json_string # raw JSON string, not a parsed Hash
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
2. **Size Limitations**
|
|
205
|
+
```ruby
|
|
206
|
+
# Problem: Environment variable too large
|
|
207
|
+
|
|
208
|
+
# Solution: Use a file-based approach instead
|
|
209
|
+
|
|
210
|
+
# Option 1: Store the service account key in a file
|
|
211
|
+
# This is often better for large service account keys
|
|
212
|
+
|
|
213
|
+
credential = Legate::Auth::Credential.new(
|
|
214
|
+
auth_type: :service_account,
|
|
215
|
+
service_account_key_file: 'path/to/service-account-key.json'
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Option 2: Use a secret management service
|
|
219
|
+
# Example with AWS Secrets Manager:
|
|
220
|
+
require 'aws-sdk-secretsmanager'
|
|
221
|
+
|
|
222
|
+
client = Aws::SecretsManager::Client.new(region: 'us-west-2')
|
|
223
|
+
secret = client.get_secret_value(secret_id: 'my-service-account-key')
|
|
224
|
+
|
|
225
|
+
credential = Legate::Auth::Credential.new(
|
|
226
|
+
auth_type: :service_account,
|
|
227
|
+
service_account_key: secret.secret_string # raw JSON string
|
|
228
|
+
)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Environment Variable Loading Order
|
|
232
|
+
|
|
233
|
+
**Symptoms:**
|
|
234
|
+
- Unexpected environment variable values
|
|
235
|
+
- Environment variables overwritten unexpectedly
|
|
236
|
+
|
|
237
|
+
**Possible Causes and Solutions:**
|
|
238
|
+
|
|
239
|
+
1. **Multiple Environment Files**
|
|
240
|
+
```ruby
|
|
241
|
+
# Problem: Multiple environment files with conflicting variables
|
|
242
|
+
|
|
243
|
+
# Solution: Establish a clear loading order
|
|
244
|
+
|
|
245
|
+
# With dotenv, you can control the order:
|
|
246
|
+
require 'dotenv'
|
|
247
|
+
|
|
248
|
+
# Load in this order (later files override earlier ones):
|
|
249
|
+
Dotenv.load('.env.local.development') # Local development overrides
|
|
250
|
+
Dotenv.load('.env.development') # Environment-specific defaults
|
|
251
|
+
Dotenv.load('.env.local') # Local overrides
|
|
252
|
+
Dotenv.load('.env') # Default values
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
2. **Application Code Overwriting Environment Variables**
|
|
256
|
+
```ruby
|
|
257
|
+
# Problem: Code overwrites environment variables
|
|
258
|
+
|
|
259
|
+
# Solution: Don't modify ENV directly, use a configuration layer
|
|
260
|
+
|
|
261
|
+
# Avoid this:
|
|
262
|
+
ENV['CLIENT_ID'] = 'hardcoded-value' # Don't do this!
|
|
263
|
+
|
|
264
|
+
# Better approach - use a configuration object:
|
|
265
|
+
class Configuration
|
|
266
|
+
def initialize
|
|
267
|
+
@values = {}
|
|
268
|
+
@values[:client_id] = ENV['CLIENT_ID']
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def client_id
|
|
272
|
+
@values[:client_id]
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
config = Configuration.new
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Environment Variable Management Tools
|
|
280
|
+
|
|
281
|
+
### Using dotenv for Development
|
|
282
|
+
|
|
283
|
+
```ruby
|
|
284
|
+
# Install dotenv gem
|
|
285
|
+
# gem install dotenv
|
|
286
|
+
|
|
287
|
+
# Create a .env file in your project root
|
|
288
|
+
# CLIENT_ID=your-client-id
|
|
289
|
+
# CLIENT_SECRET=your-client-secret
|
|
290
|
+
|
|
291
|
+
# In your application:
|
|
292
|
+
require 'dotenv'
|
|
293
|
+
Dotenv.load
|
|
294
|
+
|
|
295
|
+
# Now ENV['CLIENT_ID'] is available
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Using Encrypted Environment Variables
|
|
299
|
+
|
|
300
|
+
```ruby
|
|
301
|
+
# For sensitive production data, consider encrypted environment files
|
|
302
|
+
# Example using rails-encrypted-attributes:
|
|
303
|
+
|
|
304
|
+
# Install the gem
|
|
305
|
+
# gem install rails-encrypted-attributes
|
|
306
|
+
|
|
307
|
+
require 'rails-encrypted-attributes'
|
|
308
|
+
|
|
309
|
+
# Set up encryption
|
|
310
|
+
encryptor = RailsEncrypted::Encryptor.new(
|
|
311
|
+
key: ENV['ENCRYPTION_KEY'],
|
|
312
|
+
salt: 'legate-auth'
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
# Encrypt environment variable values
|
|
316
|
+
encrypted_value = encryptor.encrypt(ENV['CLIENT_SECRET'])
|
|
317
|
+
puts "Encrypted value: #{encrypted_value}"
|
|
318
|
+
|
|
319
|
+
# Decrypt when needed
|
|
320
|
+
decrypted_value = encryptor.decrypt(encrypted_value)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Environment Variable Validation
|
|
324
|
+
|
|
325
|
+
Validate required environment variables at startup:
|
|
326
|
+
|
|
327
|
+
```ruby
|
|
328
|
+
# Create an environment variable validator
|
|
329
|
+
class EnvironmentValidator
|
|
330
|
+
REQUIRED_VARIABLES = {
|
|
331
|
+
oauth2: ['CLIENT_ID', 'CLIENT_SECRET'],
|
|
332
|
+
api_key: ['API_KEY'],
|
|
333
|
+
service_account: ['SERVICE_ACCOUNT_JSON']
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
def self.validate!(auth_type)
|
|
337
|
+
required = REQUIRED_VARIABLES[auth_type.to_sym]
|
|
338
|
+
return unless required
|
|
339
|
+
|
|
340
|
+
missing = required.select { |var| ENV[var].nil? }
|
|
341
|
+
if missing.any?
|
|
342
|
+
raise "Missing required environment variables for #{auth_type}: #{missing.join(', ')}"
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# Usage
|
|
348
|
+
auth_type = :oauth2
|
|
349
|
+
EnvironmentValidator.validate!(auth_type)
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Environment Variable Security
|
|
353
|
+
|
|
354
|
+
### Protecting Environment Variables
|
|
355
|
+
|
|
356
|
+
Environment variables can be exposed in various ways. Protect them by:
|
|
357
|
+
|
|
358
|
+
1. **Avoiding Debug Output**
|
|
359
|
+
```ruby
|
|
360
|
+
# Don't log sensitive environment variables
|
|
361
|
+
|
|
362
|
+
# Avoid:
|
|
363
|
+
puts "ENV dump: #{ENV.inspect}"
|
|
364
|
+
|
|
365
|
+
# Instead, log only non-sensitive variables or mask sensitive ones:
|
|
366
|
+
def safe_env_dump
|
|
367
|
+
safe_env = ENV.to_h.dup
|
|
368
|
+
%w(CLIENT_SECRET API_KEY PRIVATE_KEY PASSWORD).each do |pattern|
|
|
369
|
+
safe_env.each do |key, value|
|
|
370
|
+
if key.include?(pattern)
|
|
371
|
+
safe_env[key] = "[REDACTED]"
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
safe_env
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
puts "Safe ENV dump: #{safe_env_dump.inspect}"
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
2. **Sanitizing Error Messages**
|
|
382
|
+
```ruby
|
|
383
|
+
# Sanitize error messages that might contain environment variables
|
|
384
|
+
|
|
385
|
+
begin
|
|
386
|
+
# Some code that might raise an error with sensitive data
|
|
387
|
+
rescue => e
|
|
388
|
+
# Sanitize error message before logging
|
|
389
|
+
error_message = e.message
|
|
390
|
+
%w(CLIENT_SECRET API_KEY PRIVATE_KEY PASSWORD).each do |pattern|
|
|
391
|
+
ENV.each do |key, value|
|
|
392
|
+
if key.include?(pattern) && value && !value.empty?
|
|
393
|
+
error_message = error_message.gsub(value, "[REDACTED]")
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
logger.error "Error: #{error_message}"
|
|
399
|
+
end
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
3. **Restricting Environment Variable Access**
|
|
403
|
+
```ruby
|
|
404
|
+
# Restrict access to environment variables using a wrapper
|
|
405
|
+
|
|
406
|
+
class SecureEnv
|
|
407
|
+
def self.get(name)
|
|
408
|
+
# Implement access control or auditing here
|
|
409
|
+
ENV[name]
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# Usage
|
|
414
|
+
client_id = SecureEnv.get('CLIENT_ID')
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## Provider-Specific Environment Variables
|
|
418
|
+
|
|
419
|
+
### Google Cloud
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
# Google OAuth2
|
|
423
|
+
export GOOGLE_CLIENT_ID="your-client-id"
|
|
424
|
+
export GOOGLE_CLIENT_SECRET="your-client-secret"
|
|
425
|
+
|
|
426
|
+
# Google Service Account
|
|
427
|
+
export GOOGLE_APPLICATION_CREDENTIALS="path/to/service-account-key.json"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Microsoft Azure
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
# Azure OAuth2/OIDC
|
|
434
|
+
export AZURE_CLIENT_ID="your-client-id"
|
|
435
|
+
export AZURE_CLIENT_SECRET="your-client-secret"
|
|
436
|
+
export AZURE_TENANT_ID="your-tenant-id"
|
|
437
|
+
|
|
438
|
+
# Azure Service Principal
|
|
439
|
+
export AZURE_SUBSCRIPTION_ID="your-subscription-id"
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### AWS
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
# AWS credentials
|
|
446
|
+
export AWS_ACCESS_KEY_ID="your-access-key-id"
|
|
447
|
+
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
|
|
448
|
+
export AWS_SESSION_TOKEN="your-session-token"
|
|
449
|
+
export AWS_REGION="us-west-2"
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Troubleshooting Tools
|
|
453
|
+
|
|
454
|
+
### Environment Variable Inspector
|
|
455
|
+
|
|
456
|
+
Create a simple tool to inspect environment variables:
|
|
457
|
+
|
|
458
|
+
```ruby
|
|
459
|
+
# Save this as env_inspector.rb
|
|
460
|
+
#!/usr/bin/env ruby
|
|
461
|
+
|
|
462
|
+
require 'optparse'
|
|
463
|
+
|
|
464
|
+
options = {}
|
|
465
|
+
OptionParser.new do |opts|
|
|
466
|
+
opts.banner = "Usage: env_inspector.rb [options]"
|
|
467
|
+
|
|
468
|
+
opts.on("-v", "--var NAME", "Check a specific environment variable") do |v|
|
|
469
|
+
options[:var] = v
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
opts.on("-p", "--pattern PATTERN", "Check variables matching a pattern") do |p|
|
|
473
|
+
options[:pattern] = p
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
opts.on("-l", "--list", "List all environment variables (values redacted)") do
|
|
477
|
+
options[:list] = true
|
|
478
|
+
end
|
|
479
|
+
end.parse!
|
|
480
|
+
|
|
481
|
+
if options[:var]
|
|
482
|
+
var = options[:var]
|
|
483
|
+
puts "Environment variable: #{var}"
|
|
484
|
+
if ENV[var]
|
|
485
|
+
puts " Value is set (#{ENV[var].length} characters)"
|
|
486
|
+
if var.upcase.include?("SECRET") || var.upcase.include?("KEY") || var.upcase.include?("PASSWORD")
|
|
487
|
+
puts " Value: [REDACTED]"
|
|
488
|
+
else
|
|
489
|
+
puts " Value: #{ENV[var]}"
|
|
490
|
+
end
|
|
491
|
+
else
|
|
492
|
+
puts " NOT SET"
|
|
493
|
+
similar = ENV.keys.select { |k| k.match(/#{var}/i) }
|
|
494
|
+
if similar.any?
|
|
495
|
+
puts " Similar variables: #{similar.join(', ')}"
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
elsif options[:pattern]
|
|
499
|
+
pattern = options[:pattern]
|
|
500
|
+
matches = ENV.keys.select { |k| k.match(/#{pattern}/i) }
|
|
501
|
+
puts "Variables matching pattern '#{pattern}':"
|
|
502
|
+
if matches.any?
|
|
503
|
+
matches.each do |var|
|
|
504
|
+
puts " #{var}: #{var.upcase.include?('SECRET') || var.upcase.include?('KEY') || var.upcase.include?('PASSWORD') ? '[REDACTED]' : ENV[var]}"
|
|
505
|
+
end
|
|
506
|
+
else
|
|
507
|
+
puts " No matches found"
|
|
508
|
+
end
|
|
509
|
+
elsif options[:list]
|
|
510
|
+
puts "All environment variables:"
|
|
511
|
+
ENV.each do |key, value|
|
|
512
|
+
if key.upcase.include?("SECRET") || key.upcase.include?("KEY") || key.upcase.include?("PASSWORD")
|
|
513
|
+
puts " #{key}: [REDACTED]"
|
|
514
|
+
else
|
|
515
|
+
puts " #{key}: #{value}"
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
else
|
|
519
|
+
puts "No options specified. Use --help for usage information."
|
|
520
|
+
end
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Usage:
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
# Check a specific variable
|
|
527
|
+
ruby env_inspector.rb --var CLIENT_ID
|
|
528
|
+
|
|
529
|
+
# Check variables matching a pattern
|
|
530
|
+
ruby env_inspector.rb --pattern GOOGLE
|
|
531
|
+
|
|
532
|
+
# List all variables (with sensitive values redacted)
|
|
533
|
+
ruby env_inspector.rb --list
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
## Next Steps
|
|
537
|
+
|
|
538
|
+
- [Credential Storage Issues](./credential_storage): For issues with storing credentials
|
|
539
|
+
- [Token Lifecycle Management](../guides/token_lifecycle): Advanced token management techniques
|
|
540
|
+
- [OAuth2 Troubleshooting](./oauth2_issues): For OAuth2-specific authentication issues
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Authentication Troubleshooting
|
|
2
|
+
|
|
3
|
+
This section provides solutions to common authentication issues and best practices for debugging authentication flows.
|
|
4
|
+
|
|
5
|
+
## Common Issues
|
|
6
|
+
|
|
7
|
+
- [OAuth2 Flow Issues](./oauth2_issues) - Solutions for OAuth2 authentication problems
|
|
8
|
+
- [OpenID Connect Issues](./oidc_issues) - Solutions for OIDC authentication problems
|
|
9
|
+
- [Token Refresh Problems](./token_refresh) - Solving token refresh and expiration issues
|
|
10
|
+
- [Credential Storage Issues](./credential_storage) - Solutions for credential storage problems
|
|
11
|
+
- [Environment Variable Issues](./environment_variables) - Resolving `ENV:`-prefixed credential values
|