aws / aws-toolkit-vscode

Amazon Q, CodeCatalyst, Local Lambda debug, SAM/CFN syntax, ECS Terminal, AWS resources
https://marketplace.visualstudio.com/items?itemName=AmazonWebServices.amazon-q-vscode
Apache License 2.0
1.48k stars 412 forks source link

auth: credentials set in environment (by "direnv") not used in UI #3271

Open jaridmargolin opened 1 year ago

jaridmargolin commented 1 year ago

Problem

The UI and corresponding API calls to AWS are not using the expected credentials based on the selected profile. These profiles and accounts are actively used for CDK deployments and operations with the AWS CLI, so I am reasonably confident this issue is specific to aws-toolkit-vscode and not the implementation of configuration / IAM permissions.

Steps to reproduce the issue

Set AWS Credentials of user from AccountA in env:

AWS_ACCESS_KEY_ID=XXX
AWS_SECRET_ACCESS_KEY=XXX

Set custom config dir (unknown if this impacts the bug but as it is part of our setup I am including it)

export AWS_CONFIG_FILE=/path/to/config

Set profile in config

[profile accountBProfile]
credential_source = Environment
region = us-west-2
role_arn = arn:aws:iam::<AccountB>:role/<RoleToAssume>

Attempt to use Extension.

Expected behavior

The expected behavior would be for the UI and subsequent API calls to use credentials generated from the profile accountBProfile and call the services residing on AccountB.

Actual behavior

From the logs I am viewing, it appears the credentials are changing to accountBProfile, however, the subsequent API calls are being made from AWS Credentials corresponding to the user of AccountA and being made to the corresponding service on AccountA.

(naming modified to fit reproduction steps):

023-03-24 02:52:26 [DEBUG]: command: running "_aws.auth.reauthenticate" with arguments [[object Object], [object Object]]
2023-03-24 02:52:26 [VERBOSE]: Profile accountBProfile contains credential_source - treating as Environment Credentials
2023-03-24 02:52:26 [DEBUG]: telemetry: emitted metric "vscode_executeCommand"
2023-03-24 02:52:26 [VERBOSE]: provider for instance unavailable in this environment
2023-03-24 02:52:26 [VERBOSE]: provider for instance unavailable in this environment
2023-03-24 02:52:26 [DEBUG]: telemetry: emitted metric "aws_loadCredentials"
2023-03-24 02:52:26 [DEBUG]: telemetry: emitted metric "aws_loadCredentials"
2023-03-24 02:52:37 [DEBUG]: command: running "aws.codeWhisperer.refresh"
2023-03-24 02:52:37 [DEBUG]: command: running "aws.codeWhisperer.refreshRootNode"
2023-03-24 02:52:37 [DEBUG]: command: running "aws.codeWhisperer.refreshStatusBar"
2023-03-24 02:52:37 [DEBUG]: command: running "aws.codeWhisperer.updateReferenceLog"
2023-03-24 02:52:37 [DEBUG]: command: running "aws.refreshAwsExplorerNode" with arguments [[object Object]]
2023-03-24 02:52:37 [DEBUG]: commands: skipped telemetry for "aws.codeWhisperer.refresh"
2023-03-24 02:52:37 [DEBUG]: commands: skipped telemetry for "aws.codeWhisperer.refreshRootNode"
2023-03-24 02:52:37 [DEBUG]: commands: skipped telemetry for "aws.codeWhisperer.refreshStatusBar"
2023-03-24 02:52:37 [DEBUG]: commands: skipped telemetry for "aws.codeWhisperer.updateReferenceLog"
2023-03-24 02:52:37 [DEBUG]: commands: skipped telemetry for "aws.refreshAwsExplorerNode"
2023-03-24 02:52:37 [DEBUG]: telemetry: emitted metric "aws_setCredentials"
2023-03-24 02:52:37 [DEBUG]: commands: skipped telemetry for "aws.auth.switchConnections"
2023-03-24 02:52:37 [VERBOSE]: Credentials changed (profile:accountBProfile), updating AWS Explorer
2023-03-24 02:52:37 [DEBUG]: telemetry: emitted metric "aws_validateCredentials"
2023-03-24 02:52:47 [ERROR]: AccessDenied: User: arn:aws:iam::<AccountA>:user/<AccountAUser> is not authorized to perform: cloudformation:ListStacks on resource: arn:aws:cloudformation:us-west-2:<AccountA>:stack/*/* because no identity-based policy allows the cloudformation:ListStacks action

System details (run the AWS: About Toolkit command)

2023-03-24 02:27:54 [INFO]: OS: Darwin arm64 22.2.0
2023-03-24 02:27:54 [INFO]: Visual Studio Code extension host:  1.76.2
2023-03-24 02:27:54 [INFO]: AWS Toolkit:  1.65.0
2023-03-24 02:27:54 [INFO]: node: 16.14.2
2023-03-24 02:27:54 [INFO]: electron: 19.1.11
justinmk3 commented 1 year ago

Set AWS Credentials of user from AccountA in env:

Need more specifics here. Are you setting env vars in your terminal and then lauching vscode using the code command from that same terminal?

Does https://github.com/aws/aws-toolkit-vscode/issues/1351 cover your use-case?

jaridmargolin commented 1 year ago

From my initial scan, I don't see anything in #1351 that suggests it covers my use case, however I may be missing something?


Set AWS Credentials of user from AccountA in env: Need more specifics here. Are you setting env vars in your terminal and then lauching vscode using the code command from that same terminal?

To expand, at the root of the workspace I have a .envrc file containing the env vars mentioned above:

AWS_ACCESS_KEY_ID=XXX
AWS_SECRET_ACCESS_KEY=XXX
AWS_CONFIG_FILE=/path/to/config

While I do typically launch vscode from the terminal where these vars are set using direnv, I have also installed the direnv extension in vscode to ensure they are available no matter how the application was opened.

This allows me to keep my profiles installed locally within the repo/workspace. I can confirm that the .envrc file is being sourced due to the fact that the aws-toolkit-vscode extension is capable of resolving the profiles defined in the config file at AWS_CONFIG_FILE.

justinmk3 commented 1 year ago

While I do typically launch vscode from the terminal where these vars are set using direnv, I have also installed the direnv extension in vscode to ensure they are available no matter how the application was opened.

Nice, thanks for mentioning the direnv extension. https://github.com/aws/aws-toolkit-vscode/issues/1084 tracks a similar idea for "dotenv" (.env). (What is the difference between dotenv vs direnv?)

I'm guessing that things are working "by accident" and we need to look closer to ensure that all parts of the Toolkit pull from the environment when it changes. E.g. if we have an AWS service client "cached", will it check for changed environment on the next request?

jaridmargolin commented 1 year ago

My understanding is that dotenv is a utility that uses a consistent resolution mechanism to load environment variables. More specifically, it looks for a .env file in the cwd (there may be a bit more to the resolution logic). dotenv can be utilized by individual tools and processes, such as Fastlane, which automatically loads a .env file if it exists. Alternatively, an application or framework may choose to use dotenv to load a .env file at the start of the process.

On the other hand, direnv is a shell extension that adds a new feature to existing shells. It can load and unload environment variables based on the current directory. If there is a .envrc file in the directory, it will be loaded when you change into that directory. Technically, you could even have your .envrc file call dotenv if you wanted to.

While both dotenv and direnv are used to load environment variables, their usage and purpose are slightly different.


As for "tracking" this issue, the author of #1084 seems to want direct support for automatically loading dotenv files. I don't necessarily need the AWS CLI or anything else to "support" direnv. direnv will automatically load env vars in my terminal when I am within a workspace, and the direnv extension will ensure that vscode automatically loads the .envrc file upon opening. In fact, I'm not convinced if my issue is tied to direnv or not.

For the sake of testing, I moved my credentials and config file to ~/.aws to see if I could get the extension to work with more "default" behavior and avoid any potential issues that may be caused by the extension loading order in vscode. From what I can tell, I have the same issue.

2023-03-24 20:08:31 [VERBOSE]: Profile accountBProfile contains role_arn - treating as regular Shared Credentials
2023-03-24 20:08:31 [DEBUG]: command: running "aws.codeWhisperer.refresh"
2023-03-24 20:08:31 [DEBUG]: command: running "aws.codeWhisperer.refreshRootNode"
2023-03-24 20:08:31 [DEBUG]: command: running "aws.codeWhisperer.refreshStatusBar"
2023-03-24 20:08:31 [DEBUG]: command: running "aws.codeWhisperer.updateReferenceLog"
2023-03-24 20:08:31 [DEBUG]: command: running "aws.refreshAwsExplorerNode" with arguments [[object Object]]
2023-03-24 20:08:31 [DEBUG]: telemetry: emitted metric "vscode_executeCommand"
2023-03-24 20:08:31 [DEBUG]: telemetry: emitted metric "vscode_executeCommand"
2023-03-24 20:08:31 [DEBUG]: commands: skipped telemetry for "aws.codeWhisperer.refreshStatusBar"
2023-03-24 20:08:31 [DEBUG]: commands: skipped telemetry for "aws.codeWhisperer.updateReferenceLog"
2023-03-24 20:08:31 [DEBUG]: telemetry: emitted metric "vscode_executeCommand"
2023-03-24 20:08:31 [DEBUG]: telemetry: emitted metric "aws_setCredentials"
2023-03-24 20:08:31 [DEBUG]: commands: skipped telemetry for "aws.auth.switchConnections"
2023-03-24 20:08:31 [VERBOSE]: Credentials changed (profile:sharedServicesAdmin), updating AWS Explorer
2023-03-24 20:08:31 [DEBUG]: telemetry: emitted metric "aws_validateCredentials"
2023-03-24 20:08:36 [ERROR]: AccessDenied: User: arn:aws:I am::<AccountA>:user/<AccountAUser> is not authorized to perform

Maybe to help build clarity, are you able to validate that assuming cross-account profiles work in aws-toolkit-vscode? Going back to my first comment in the thread, I am unable to get the following to work:

AWS Credentials for AccountA with a profile referencing a role in AccountB.