awslabs / aws-crt-nodejs

NodeJS bindings for the AWS Common Runtime.
Apache License 2.0
37 stars 24 forks source link

Default provider chain does not support SSO profile-defined credentials #532

Open Zordrak opened 4 months ago

Zordrak commented 4 months ago

Describe the bug

NOTE: This has also been raised as https://github.com/awslabs/aws-c-auth/issues/228 - but not knowing where ownership lies, I'm raising here also for visibility.

Short Version

aws_credentials_provider_new_chain_default doesn't account for SSO credentials configuration in an INI profile, and this appears to be a bug rather than an unimplemented feature.

Long Version

Coming from https://github.com/awslabs/aws-crt-nodejs, all of the AWS guidance for Sig4(a) signing HTTP requests in JavaScript is to use the aws-crt package, which is backed by aws-c-auth.

The options in that package's sign function expect a self-defined credentials provider generated by the NAPI-exposed functions labelled newDefault, newStatic, newCognito and newX509.

The expectation, and all available guidance, is that you should use aws-crt.auth.AwsCredentialsProvider.newDefault() if you want/need to source credentials from the default provider chain, and it is expected that this will mirror the behaviour of other implementations, sourcing credentials from the environment, from local profile, from ECS and then IMDS etc.

However, when the aws-crt package calls aws_credentials_provider_new_chain_default from aws-c-auth, between aws_profile.c and credentials_provider_profile.c, there does not appear to be any call to the credentials_provider_sso.c implementation, or attempt to load sso-specific configuration properties from the profile.

I have been focussing heavily on the SSO functionality, but I suspect this is also true for other credential providers that are normally invoked from the use of specific property names in a profile configuration, for example the process provider.

This issue is especially confusing as while there's no specific indication that SSO is not supported through a profile configuration, the library explicitly contains code for interpreting and managing SSO-sourced credentials.

We are now working around this issue by taking a leaf from @aws-sdk/client-s3's book, and sourcing credentials ourselves (using @aws-sdk/credential-providers//fromNodeProviderChain()), and then passing those credentials into newStatic, bypassing the chain-lookup native to these packages, however it has taken a lot of time and effort to understand the nature of the problem and decide upon the workaround.

Documentation regarding expectations of the default provider chain for AWS SDKs and tools: https://docs.aws.amazon.com/sdkref/latest/guide/feature-sso-credentials.html

Expected Behavior

Given valid SSO credentials in the local credentials cache, generated by an SSO profile being configured, active and logged in, the credentials should be used to SigV4a sign a request when present and the Default provider chain is requested as a credentials provider.

Current Behavior

CrtError: aws-c-auth: AWS_AUTH_SIGNING_NO_CREDENTIALS, Attempt to sign an http request without credentials
    at /<srcpath>/node_modules/aws-crt/lib/native/auth.ts:365:28 {
  error: 6146,
  error_code: 6146,
  error_name: 'AWS_AUTH_SIGNING_NO_CREDENTIALS'
}

Relevant Debug Logs from aws-crt:

[INFO] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x7f8fdc031ce0): TLS context not provided, initializing a new one for credentials provider.
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Creating profile collection from file at "/home/<user>/.aws/config"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "<None>", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_session"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_account_id"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_role_name"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_start_url"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_region"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Creating profile collection from file at "/home/<user>/.aws/credentials"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "<None>", current property: "<None>"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_role_name" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_session" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_account_id" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_start_url" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_registration_scopes" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Creating profile collection from file at "/home/<user>/.aws/config"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "<None>", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_session"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_account_id"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_role_name"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_start_url"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_region"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - Successfully built config profile collection from file at (/home/<user>/.aws/config)
[ERROR] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - Failed to resolve role arn during sts web identity provider initialization.
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Creating profile collection from file at "/home/<user>/.aws/config"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "<None>", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_session"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_account_id"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_role_name"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_start_url"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_region"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - Successfully built config profile collection from file at (/home/<user>/.aws/config)
[ERROR] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - Failed to resolve credentials_process command during process credentials provider initialization.
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [channel-bootstrap] - id=0x6adf210: acquiring bootstrap reference
[INFO] [2024-02-07T12:36:45Z] [00007f901173c800] [connection-manager] - id=0x6e23cc0: Successfully created
[INFO] [2024-02-07T12:36:45Z] [00007f901173c800] [exp-backoff-strategy] - id=0x6e2b3a0: Initializing exponential backoff retry strategy with scale factor: 0 jitter mode: 0 and max retries 1
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x7f8fdc031ce0) Credentials provider chain get credentials dispatch
[INFO] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6d72ea0) Cached credentials provider has expired credentials.  Requerying.
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd41f0) Credentials provider chain get credentials dispatch
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd41f0) Credentials provider chain callback 1 invoked with invalid credentials and error code 6150
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd41f0) Credentials provider chain invoking chain member #1
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Creating profile collection from file at "/home/<user>/.aws/config"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "<None>", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "default", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "region"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "output"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_session"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_account_id"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myprofilename", current property: "sso_role_name"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "<None>"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_start_url"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "myssoconfigname", current property: "sso_region"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd3ac0) Profile credentials provider successfully built config profile collection from file at (/home/<user>/.aws/config)
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Creating profile collection from file at "/home/<user>/.aws/credentials"
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - Parsing aws profile line in profile "<None>", current property: "<None>"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd3ac0) Profile credentials provider successfully built credentials profile collection from file at (/home/<user>/.aws/credentials)
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_role_name" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_session" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_account_id" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "output" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_start_url" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_region" has value "" replaced during merge
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AWSProfile] - property "sso_registration_scopes" has value "" replaced during merge
[INFO] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd3ac0) Profile credentials provider attempting to pull credentials from profile "myprofilename"
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd41f0) Credentials provider chain callback 2 invoked with invalid credentials and error code 1
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [AuthCredentialsProvider] - (id=0x6dd41f0) Credentials provider chain invoking chain member #2
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [exp-backoff-strategy] - id=0x6e2b3a0: Initializing retry token 0x6da9e30
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [event-loop] - id=0x6a9ef40: Scheduling task 0x6da9ea0 cross-thread for timestamp 0
[TRACE] [2024-02-07T12:36:45Z] [00007f901173c800] [event-loop] - id=0x6a9ef40: Waking up event-loop thread
[DEBUG] [2024-02-07T12:36:45Z] [00007f901173c800] [Unknown] - (id=0x6d6fff0) IMDS client's token is invalid and is now updating.
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: wake up with 1 events to process.
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: activity on fd 49, invoking handler.
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: notified of cross-thread tasks to schedule
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: processing cross-thread tasks
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: task 0x6da9ea0 pulled to event-loop, scheduling now.
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [task-scheduler] - id=0x6da9ea0: Scheduling aws_exponential_backoff_retry_task task for immediate execution
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: running scheduled tasks.
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [task-scheduler] - id=0x6da9ea0: Running aws_exponential_backoff_retry_task task with <Running> status
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [exp-backoff-strategy] - id=0x6e2b3a0: Vending retry_token 0x6da9e30
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [Unknown] - id=0x6d6fff0: IMDS Client successfully acquired retry token.
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [connection-manager] - id=0x6e23cc0: Acquire connection
<SNIPPED UNNECESSARY IMDS CONNECTION ACTIVITY>
[WARN] [2024-02-07T12:36:45Z] [00007f8fd3011640] [Unknown] - id=0x6d6fff0: IMDS Client failed to acquire a connection, error code 1049(socket connect failure, no route to host.)
[INFO] [2024-02-07T12:36:45Z] [00007f8fd3011640] [AuthCredentialsProvider] - (id=0x6dd41f0) Credentials provider chain callback terminating on index 3, with invalid credentials and error code 6153
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [AuthCredentialsProvider] - (id=0x6d72ea0) Cached credentials provider next refresh time set to 179869986998474
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [AuthCredentialsProvider] - (id=0x6d72ea0) Cached credentials provider was unable to source credentials on refresh
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [AuthCredentialsProvider] - (id=0x6d72ea0) Cached credentials provider notifying pending queries of new credentials
[ERROR] [2024-02-07T12:36:45Z] [00007f8fd3011640] [AuthCredentialsProvider] - (id=0x7f8fdc031ce0) Default chain credentials provider failed to source credentials with error 6153(aws-c-auth: AWS_AUTH_CREDENTIALS_PROVIDER_IMDS_SOURCE_FAILURE, Valid credentials could not be sourced by the IMDS provider)
[ERROR] [2024-02-07T12:36:45Z] [00007f8fd3011640] [AuthSigning] - (id=0x7f8fe000f9e0) Credentials Provider failed to source credentials with error 6153(aws-c-auth: AWS_AUTH_CREDENTIALS_PROVIDER_IMDS_SOURCE_FAILURE, Valid credentials could not be sourced by the IMDS provider)
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [channel-bootstrap] - releasing client connection args, args=0x7f8fcc00b1c0
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [channel-bootstrap] - releasing client connection args, args=0x7f8fcc00b1c0
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [channel-bootstrap] - destroying client connection args, args=0x7f8fcc00b1c0
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [channel-bootstrap] - id=0x6adf210: releasing bootstrap reference
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: running scheduled tasks.
[DEBUG] [2024-02-07T12:36:45Z] [00007f8fd3011640] [task-scheduler] - id=0x7f8fcc0022b0: Running epoll_event_loop_unsubscribe_cleanup task with <Running> status
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: detected more scheduled tasks with the next occurring at 1897309167, using timeout of 1897.
[TRACE] [2024-02-07T12:36:45Z] [00007f8fd3011640] [event-loop] - id=0x6a9ef40: waiting for a maximum of 1897 ms
Uncaught:
[CrtError: aws-c-auth: AWS_AUTH_SIGNING_NO_CREDENTIALS, Attempt to sign an http request without credentials] {
  error: 6146,
  error_code: 6146,
  error_name: 'AWS_AUTH_SIGNING_NO_CREDENTIALS'
}
> [DEBUG] [2024-02-07T12:36:46Z] [00007f8fd200f640] [dns] - static: resolving host 169.254.169.254
[DEBUG] [2024-02-07T12:36:46Z] [00007f8fd200f640] [dns] - static: resolved record: 169.254.169.254
[DEBUG] [2024-02-07T12:36:46Z] [00007f8fd200f640] [dns] - static, resolving host 169.254.169.254 successful, returned 1 addresses
[TRACE] [2024-02-07T12:36:46Z] [00007f8fd200f640] [dns] - static: updating expiry for 169.254.169.254 for host 169.254.169.254 to 179000989727560
<SNIPPED REMAINING NETWORK ACTIVITY EVENT LOOP>

Reproduction Steps

Given

~/.aws/config

[profile myprofilename]
region = eu-west-2
output = json
sso_session = myssoconfigname
sso_account_id = 123456789012
sso_role_name = AdministratorAccess
[sso-session myssoconfigname]
sso_start_url = https://example.awsapps.com/start
sso_region = eu-west-2
sso_registration_scopes = sso:account:access

And

export AWS_PROFILE=myprofilename

And

$ aws sso login
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.eu-west-2.amazonaws.com/

Then enter the code:

ABCD-EFGH
Successfully logged into Start URL: https://example.awsapps.com/start

Then

ts-node sign.ts
sign.ts
import { auth } from "aws-crt";
import { HttpRequest } from "aws-crt/dist/native/http";
import { HttpHeaders } from "aws-crt/lib/native/binding";
import { RawAxiosRequestHeaders } from "axios";

const convertAwsCrtToHeadersToObject = (headers: HttpHeaders): Record<string, string> => {
  const obj: Record<string, string> = {};
  for (const header of headers) {
    obj[header[0]] = header[1];
  }
  return obj;
};

export async function generateAwsSignedHeaders(
  method: string,
  endpoint: string,
  service: string,
  region: string,
): Promise<RawAxiosRequestHeaders> {
  const host = new URL(endpoint).host;
  const request = new HttpRequest(method, endpoint);
  request.headers.add("host", host);

  const config = {
    service,
    region,
    algorithm: auth.AwsSigningAlgorithm.SigV4Asymmetric,
    signature_type: auth.AwsSignatureType.HttpRequestViaHeaders,
    signed_body_header: auth.AwsSignedBodyHeaderType.XAmzContentSha256,
    provider: auth.AwsCredentialsProvider.newDefault(),
  };

  await auth.aws_sign_request(request, config);
  return convertAwsCrtToHeadersToObject(request.headers);
}

const sign = async () => {
  const signedHeaders = await generateAwsSignedHeaders(
    "GET",
    "https://foo.execute-api.eu-west-2.amazonaws.com/bar/",
    "apigateway",
    "eu-west-2",
  );

  console.log(JSON.stringify(signedHeaders, null, 2));
};

sign().catch(console.error);

Should Output

{
  "host": "foo.execute-api.eu-west-2.amazonaws.com",
  "X-Amz-Security-Token": "<valid security token>",
  "X-Amz-Date": "<valid date string>",
  "X-Amz-Region-Set": "eu-west-2",
  "x-amz-content-sha256": "<valid sha256>",
  "Authorization": "AWS4-ECDSA-P256-SHA256 Credential=<roleId>/<YYYYMMDD>/apigateway/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-region-set;x-amz-security-token, Signature=<signature_string>"
}

Should Not Output

CrtError: aws-c-auth: AWS_AUTH_SIGNING_NO_CREDENTIALS, Attempt to sign an http request without credentials
    at /<srcpath>/node_modules/aws-crt/lib/native/auth.ts:365:28 {
  error: 6146,
  error_code: 6146,
  error_name: 'AWS_AUTH_SIGNING_NO_CREDENTIALS'
}

Possible Solution

My understanding of the exact structure of the code is limited, but I believe it is a matter of configuring the new_default provider chain to include the use of the sso credentials provider already present in the code, when the sso_session property is configured in a profile.

Additional Information/Context

This is how we are now working around this problem.

Credentials are looked up using fromNodeProviderChain() and passed hardcoded to newStatic().

This is aligned to the approach taken in @aws-sdk/client-s3: https://github.com/aws/aws-sdk-js-v3/blob/5afac5e175e7b0a92cd612c5a4730a4269c4fa52/packages/signature-v4-crt/src/CrtSignerV4.ts#L281

However because we are not informed enough to presume what might be supported in the newDefault chain that may not be supported in fromNodeProviderChain, we fall back to newDefault in the event fromNodeProviderChain is unable to provide credentials. This potentially duplicated failed chain sources, but is more robust in handling future expectations from either package.

import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
import type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@smithy/types";

// <snip>

export async function generateAwsSignedHeaders(
  method: string,
  endpoint: string,
  service: string,
  region: string,
): Promise<RawAxiosRequestHeaders> {
  const host = new URL(endpoint).host;
  const request = new HttpRequest(method, endpoint);
  request.headers.add("host", host);

  let provider: auth.AwsCredentialsProvider;

  const credsProvider: AwsCredentialIdentityProvider = fromNodeProviderChain({});
  const creds: AwsCredentialIdentity = await credsProvider();

  if (creds.accessKeyId !== undefined && creds.secretAccessKey !== undefined) {
    provider = auth.AwsCredentialsProvider.newStatic(creds.accessKeyId, creds.secretAccessKey, creds.sessionToken);
  } else {
    provider = auth.AwsCredentialsProvider.newDefault();
  }

  const config = {
    service,
    region,
    algorithm: auth.AwsSigningAlgorithm.SigV4Asymmetric,
    signature_type: auth.AwsSignatureType.HttpRequestViaHeaders,
    signed_body_header: auth.AwsSignedBodyHeaderType.XAmzContentSha256,
    provider,
  };

  process.env.DEBUG && io.enable_logging(io.LogLevel.TRACE);
  await auth.aws_sign_request(request, config);
  return convertAwsCrtToHeadersToObject(request.headers);
}

aws-crt-nodejs version used

v1.21.0

nodejs version used

v20.5.1

Operating System and version

Linux 5.15.94 #1 SMP PREEMPT x86_64 13th Gen Intel(R) Core(TM) i7-13850HX GenuineIntel GNU/Linux

jmklix commented 4 months ago

We never added support for SSO profile-defined credentials to this repo, so this is not expected to work. This is something that we would like to add in the future, but I don't have a timeframe for when it might be added. Changing this to a feature request.

adabir2 commented 2 months ago

Thanks for raising this detailed issue. I just ran into this as well and would like to add support to the feature request. Cheers!