ServerlessLife / serverless-spy

CDK-based library for writing elegant, fast-executing integration tests on AWS serverless architecture and an additional web console to monitor events in real time.
https://serverlessspy.com/
Mozilla Public License 2.0
79 stars 5 forks source link

Feature request: support config based authentication #36

Closed nmussy closed 5 months ago

nmussy commented 5 months ago

Given the following ~/.aws/config file, set up to handle a basic AWS Organization main main account and sub sub account:

[default]
region = eu-west-3
output = json

[profile main]
aws_access_key_id = xxx
aws_secret_access_key = xxx

[profile sub]
role_arn = arn:aws:iam::xxx:role/OrganizationAccountAccessRole
source_profile = main

The env AWS_PROFILE=sub variable is correctly detected, but sspy only tries to access ~/.aws/credentials:

$ sspy --cdkoutput cdkOutput.json
ServerlessSoy console runing at http://localhost:3456
Connection
SSPY Using IoT endpoint: xxx.iot.us-east-1.amazonaws.com

TypeError: Cannot read properties of undefined (reading 'aws_access_key_id')
    at new DeviceClient (/Users/user/projects/serverless-spy-example/node_modules/serverless-spy/node_modules/aws-iot-device-sdk/device/index.js:494:38)

// ...

Failed to read credentials for AWS_PROFILE sub from /Users/user/.aws/credentials
To connect via WebSocket/SigV4, AWS Access Key ID and AWS Secret Key must be passed either in options or as environment variables; see README.md
/Users/user/projects/serverless-spy-example/node_modules/serverless-spy/node_modules/aws-iot-device-sdk/device/index.js:505
            throw new Error(exceptions.INVALID_CONNECT_OPTIONS);

This seems to be a limitation of aws-iot-device-sdk-js, but was supposedly fixed in aws-iot-device-sdk-v2, see https://github.com/aws/aws-iot-device-sdk-js/issues/307

This can be worked around by manually generating credentials and loading them in your env using the AWS CLI:

$ aws sts assume-role --role-arn arn:aws:iam::xxx:role/OrganizationAccountAccessRole --role-session-name temp --profile main > temp_credentials.json

$ set -x AWS_ACCESS_KEY_ID (jq '.Credentials.AccessKeyId' temp_credentials.json)
$ set -x AWS_SECRET_ACCESS_KEY (jq '.Credentials.SecretAccessKey' temp_credentials.json)
$ set -x AWS_SESSION_TOKEN (jq '.Credentials.SessionToken' temp_credentials.json)

$ rm temp_credentials.json
markostru commented 5 months ago

@nmussy Thank you for creating an issue.

If you have experience with aws-iot-device-sdk-v2, can you provide us with a snippet or maybe even a PR?

nmussy commented 5 months ago

I don't have any experience with it, just did a quick issue lookup in the v1 repo, sorry to say šŸ˜…

Lewenhaupt commented 5 months ago

@markostru I looked at it when I did the implementation (was not aware of this limitation) but v2 required some binary that caused issues when run on lambda. There has been a change to aws-crt (the cause of the issue) that does provide a "solution". It's still a bit hacky but I think I could make it work using something like this https://github.com/awslabs/aws-crt-nodejs/issues/467#issuecomment-2047870650 @nmussy Thanks for the detailed issue :)

ServerlessLife commented 5 months ago

@Lewenhaupt Are you planning to try? That would be awesome.

Lewenhaupt commented 5 months ago

@ServerlessLife yeah I'll give it a go šŸ˜Š need a reason to keep learning nvim as well so it's the perfect opportunity šŸ˜…

Lewenhaupt commented 5 months ago

Yeah the aws-crt didn't work fully. It did support the config file, but not sso based Auth. I think I got it working by using a credentials provider from the sdk and then retrieving the resolved credentials from that.