-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Which version of the app are you using?
v3.8.4
Which API Provider are you using?
AWS Bedrock
Which Model are you using?
Claude 3.7 Sonnet
What happened?
When using the AWS Bedrock provider and the AWS Profile authentication method, Roo API calls fail due to the profile only being available on the local host. In my use-case, AWS authentication is using single sign-on (SSO) and users typically do not setup the profiles on the remote SSH hosts.
There are workarounds,
- Use the direct credential and provide access keys and secrets (instead of using the AWS Profile method)
- Copy the profile credentials established via SSO over to the remote host.
- etc.
And looking into the root cause (with some help from Roon), the problem appears to have to do with how extensions run in VS Code. If the workspace is on a local machine, the extension commands run in that local context and if it is on a remote-host, the extension also runs on the remote-context. And when it attempts to grab credentials via the AWS Profile, Roo cann't find that on the remote host.
Steps to reproduce
- Configure an AWS Profile in your localhost (~/aws/config) and authenticate that profile
- Configure Roo to use the AWS Profile above
- Open VS Code against a local workspace and use Roo. It just works.
- Open VS Code against a remote SSH workspace and use Roo. API requests to the provider fail.
Relevant API REQUEST output
Additional context
Here is the detailed analysis of the problem and some solution strategies proposed by Roo architect.
AWS Profile Authentication in Remote SSH Hosts
Problem Statement
When using Roo-Code with AWS Bedrock provider in a remote SSH host scenario, AWS Profile authentication fails while AWS Credential mode works correctly. This happens because:
- When VS Code connects to a remote SSH host, the extension code runs on the remote host
- The AWS SDK's
fromIni()function looks for AWS credentials in standard locations on the machine where the code is running (the remote host) - The user's AWS profiles are stored on their local machine (typically in
~/.aws/credentialsand~/.aws/config) - As a result, the AWS SDK can't find the profile on the remote host and authentication fails
VS Code Extension Architecture
VS Code distinguishes between two kinds of extensions:
-
UI Extensions:
- Run on the user's local machine
- Cannot directly access files in the remote workspace
- Examples: themes, snippets, language grammars, and keymaps
-
Workspace Extensions:
- Run on the same machine where the workspace is located
- For remote workspaces, they run on the remote machine/environment
- Can access files in the workspace
- Examples: language servers, debuggers, and extensions that perform operations on workspace files
When a user installs an extension, VS Code automatically installs it to the correct location based on its kind. If an extension can run as either kind, VS Code will attempt to choose the optimal one for the situation.
Key Insight
VS Code's documentation reveals that certain APIs are designed to always run on the local machine, even when called from a Workspace Extension running remotely:
Like the clipboard API, the Webview API is always run on the user's local machine or in the browser, even when used from a Workspace Extension.
This provides a mechanism for accessing local resources from a remote extension.
Proposed Solution: WebView-Based AWS Profile Authentication
Instead of having different authentication flows for local vs. remote scenarios, we can create a unified approach using WebViews:
-
Always Use WebView for Profile Authentication:
- When AWS Profile authentication is selected, always use a WebView
- The WebView runs locally (even in remote contexts)
- This provides a consistent experience regardless of environment
-
Implementation Flow:
┌─────────────────────┐ ┌─────────────────────┐ │ │ │ │ │ Roo-Code Extension │ │ WebView (Local) │ │ (Local or Remote) │ │ │ │ │ │ │ └──────────┬──────────┘ └──────────┬──────────┘ │ │ │ 1. Launch WebView │ ├──────────────────────────►│ │ │ │ │ 2. Read ~/.aws/credentials │ │ and ~/.aws/config │ │ │ 3. Return credentials │ │◄──────────────────────────┤ │ │ ┌──────────▼──────────┐ │ │ │ │ │ AWS SDK │ │ │ (Use credentials │ │ │ directly) │ │ │ │ │ └─────────────────────┘ │
Implementation Plan
-
Create a WebView-Based Credential Provider:
- Implement a singleton class that manages a WebView for reading AWS credentials
- The WebView will use browser APIs to read the local AWS credentials file
- Credentials will be passed back to the extension via messaging
-
Modify the AWS Bedrock Handler:
- Update the constructor to use the WebView-based credential provider when AWS Profile authentication is selected
- Use the returned credentials directly instead of calling
fromIni() - Include a fallback to
fromIni()for local scenarios if the WebView approach fails
-
Security Considerations:
- Ensure secure handling of credentials in the WebView
- Implement proper error handling for cases where profiles don't exist
- Consider adding timeout and retry mechanisms
Benefits of This Approach
- Consistency: Same authentication flow regardless of local or remote context
- Simplicity: No need for redundant settings or different authentication paths
- Reliability: WebViews always run locally, ensuring access to local credentials
- User Experience: Transparent to the user - they just select a profile and it works
- Fallback Mechanism: Still falls back to
fromIni()as a last resort for local scenarios
Supporting Various AWS Authentication Methods
AWS profiles support multiple authentication methods, each with unique requirements. Our WebView-based solution needs to handle all of these methods to be a complete replacement for fromIni().
AWS Profile Authentication Methods
-
Static Credentials: Basic access key and secret key
[profile direct-auth] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
-
Role Assumption: Assuming another role using STS
[profile role-assumption] role_arn = arn:aws:iam::123456789012:role/role-name source_profile = base-profile
-
SSO Authentication: Using AWS SSO
[profile sso-auth] sso_start_url = https://my-sso-portal.awsapps.com/start sso_region = us-east-1 sso_account_id = 123456789012 sso_role_name = SSOReadOnlyRole
-
External Process: Using an external command
[profile external-process] credential_process = /path/to/credential/process --arguments
-
MFA-Based: Requiring multi-factor authentication
[profile mfa-auth] mfa_serial = arn:aws:iam::123456789012:mfa/user
Enhanced WebView-Based Solution
To support all these authentication methods, we need to enhance our WebView solution:
Enhanced Architecture
┌─────────────────────┐ ┌─────────────────────────────────┐
│ │ │ │
│ Roo-Code Extension │ │ Enhanced WebView (Local) │
│ (Local or Remote) │ │ │
│ │ │ - Profile Parser │
└──────────┬──────────┘ │ - Authentication Handler │
│ │ - AWS SDK Integration │
│ │ │
│ 1. Request │ │
│ credentials │ │
├───────────────►│ │
│ │ │
│ │ 2. Parse profile │
│ │ │
│ │ 3. Determine auth method │
│ │ │
│ │ 4. Execute appropriate │
│ │ authentication flow │
│ │ (may involve browser │
│ │ or external process) │
│ │ │
│ 5. Return │ │
│ credentials │ │
│◄───────────────┤ │
│ └─────────────────────────────────┘
Implementation Approach for Different Auth Methods
-
Static Credentials
- Directly read from the credentials file
- No additional processing needed
-
Role Assumption
- Read the source profile credentials
- Use AWS STS client in the WebView to assume the role
- Return the temporary credentials
-
SSO Authentication
- Check if SSO token cache exists and is valid
- If not, initiate SSO authentication flow:
- Launch a popup browser for SSO login
- Capture and store the SSO token
- Use the token to get SSO credentials via AWS SDK
-
External Process
- Execute the credential process in the WebView using:
- For simple cases: WebView's JavaScript capabilities
- For complex cases: Message back to extension to run the process locally and return results
- Execute the credential process in the WebView using:
-
MFA-Based Authentication
- Prompt the user for MFA code in the WebView
- Use the code with AWS STS to get temporary credentials
Handling Browser-Based Authentication (SSO)
For SSO authentication that requires a browser:
-
Option 1: In-WebView Browser
- Use an iframe within the WebView to handle the SSO authentication flow
- Capture the redirect with the authentication token
-
Option 2: External Browser with Communication Channel
- Launch the system browser for SSO authentication
- Use a local server or custom protocol handler to capture the authentication result
- Pass the result back to the WebView
-
Option 3: Extension API Integration
- Use VS Code's authentication provider API if available
- Integrate with existing authentication extensions
Handling External Processes
For profiles that use credential_process:
-
Option 1: WebView to Extension Communication
- WebView sends a message to the extension
- Extension executes the process locally
- Result is sent back to the WebView
-
Option 2: WebAssembly for Complex Processes
- For certain credential helpers, compile to WebAssembly
- Run directly in the WebView
Challenges and Considerations
-
Security:
- Need to ensure secure handling of credentials in the WebView
- Protect against XSS vulnerabilities
- Secure storage of temporary tokens
-
File Access:
- Need to implement file reading in the WebView (may require additional permissions)
- Handle file system differences between operating systems
-
User Experience:
- Brief WebView flash when authenticating (could be minimized with styling)
- Seamless handling of browser-based authentication flows
- Clear error messages for authentication failures
-
Error Handling:
- Need robust error handling for cases where profiles don't exist
- Handle network failures during authentication
- Graceful degradation when specific authentication methods fail
-
Authentication Method Complexity:
- SSO authentication requires browser interaction
- External processes may have dependencies that are hard to satisfy in a WebView
- Role chains (roles that assume other roles) require multiple API calls
Next Steps
- Implement the enhanced WebView-based credential provider with support for all authentication methods
- Modify the AWS Bedrock handler to use the new credential provider
- Add comprehensive error handling and fallback mechanisms for each authentication method
- Test in both local and remote SSH scenarios with various profile types
- Document the new behavior for users