Giter Site home page Giter Site logo

awslabs / aws-c-auth Goto Github PK

View Code? Open in Web Editor NEW
40.0 27.0 28.0 1.08 MB

C99 library implementation of AWS client-side authentication: standard credentials providers and signing.

License: Apache License 2.0

CMake 1.42% C 98.12% Python 0.46%
hacktoberfest

aws-c-auth's Introduction

AWS C Auth

C99 library implementation of AWS client-side authentication: standard credentials providers and signing.

From a cryptographic perspective, only functions with the suffix "_constant_time" should be considered constant time.

License

This library is licensed under the Apache 2.0 License.

Usage

Building

CMake 3.1+ is required to build.

<install-path> must be an absolute path in the following instructions.

Linux-Only Dependencies

If you are building on Linux, you will need to build aws-lc and s2n-tls first.

git clone [email protected]:awslabs/aws-lc.git
cmake -S aws-lc -B aws-lc/build -DCMAKE_INSTALL_PREFIX=<install-path>
cmake --build aws-lc/build --target install

git clone [email protected]:aws/s2n-tls.git
cmake -S s2n-tls -B s2n-tls/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path>
cmake --build s2n-tls/build --target install

Building aws-c-auth and Remaining Dependencies

git clone [email protected]:awslabs/aws-c-common.git
cmake -S aws-c-common -B aws-c-common/build -DCMAKE_INSTALL_PREFIX=<install-path>
cmake --build aws-c-common/build --target install

git clone [email protected]:awslabs/aws-c-cal.git
cmake -S aws-c-cal -B aws-c-cal/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path>
cmake --build aws-c-cal/build --target install

git clone [email protected]:awslabs/aws-c-io.git
cmake -S aws-c-io -B aws-c-io/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path>
cmake --build aws-c-io/build --target install

git clone [email protected]:awslabs/aws-c-compression.git
cmake -S aws-c-compression -B aws-c-compression/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path>
cmake --build aws-c-compression/build --target install

git clone [email protected]:awslabs/aws-c-http.git
cmake -S aws-c-http -B aws-c-http/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path>
cmake --build aws-c-http/build --target install

git clone [email protected]:awslabs/aws-c-auth.git
cmake -S aws-c-auth -B aws-c-auth/build -DCMAKE_INSTALL_PREFIX=<install-path> -DCMAKE_PREFIX_PATH=<install-path>
cmake --build aws-c-auth/build --target install

Testing

Certain tests require a specific environment setup in order to run successfully. This may be a specific execution environment (EC2, ECS, etc...) or it may require certain environment variables to be set that configure properties (often sensitive materials, like keys). Whether or not these tests are enabled is controlled by certain CMAKE properties:

  • AWS_BUILDING_ON_EC2 - indicates real IMDS credentials provider test(s) should run
  • AWS_BUILDING_ON_ECS - indciates real ECS credentials provider tests(s) should run
  • AWS_HAS_CI_ENVIRONMENT - indicates that all tests that require environmentally injected secrets/properties should run

Environment properties are injected by CRT builder process via the custom builder step defined in ./.builder/action/aws-c-auth-test.py

aws-c-auth's People

Contributors

bretambrose avatar coldencullen avatar davidogunsaws avatar dmitriymusatkin avatar graebm avatar ilevyor avatar jamesbornholt avatar jmklix avatar jonathanhenson avatar rccarper avatar sbstevek avatar singku-china avatar tingdaok avatar twistedtwigleg avatar waahm7 avatar wps132230 avatar yasminetalby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-c-auth's Issues

default chain provider: add support for SSO generated credentials

The AWS C++ SDK supports AWS SSO credentials since version 1.9.

As of June 2022, the aws-c-auth aws_credentials_provider_default_chain does not support SSO credentials,
which means it can not be used on systems that rely on SSO, or called from the AWS SDK > 1.9.0 when using the
CommonRunTime (CRT) extension for PutObject/GetObject.

(Related issue: support for STS credentials #157).

FreeBSD systems require -lexecinfo flag

Hello,
While trying to get the v2 aws-cli working on FreeBSD I ran into an issue where aws would fail due to their not being a backtrace symbol in _awscrt.cpython-38.so.

After doing some digging I traced this down to how cmake in this repository. After applying the following patch I am able to successfully build and run the v2 aws-cli on my FreeBSD systems. This will ensure FreeBSD systems use the OS provided execinfo library:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b25dda8..1b35ba4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,7 +68,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
 elseif (APPLE)
     set(PLATFORM_LIBS "")
 elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
-    set(PLATFORM_LIBS "")
+    set(PLATFORM_LIBS "-lexecinfo")
 endif()

I have not tested on NetBSD yet, but I believe this will be required for that platform as well.

ECS Credentials Provider results in status code 400 (Bad Request)

I try to resolve AWS Credentials in my Fargate application using aws-crt-python. It creates the default chain including the needed ECS provider. It fails with status code 400 (see log outputs below). It do work without any issue to resolve credentials with Boto3. So my workaround right now is to pass static credentials from Boto3 when using aws-crt-python.

[DEBUG] [2021-01-21T12:20:12Z] [00007f804ac9f740] [dns] - id=0x555face6da50: Host resolution requested for 169.254.170.2
--
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f804ac9f740] [dns] - id=0x555face6da50: No cached entries found for 169.254.170.2 starting new resolver thread.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8046d2b700] [dns] - static: resolving host 169.254.170.2
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8046d2b700] [dns] - static: resolved record: 169.254.170.2
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8046d2b700] [dns] - static, resolving host 169.254.170.2 successful, returned 1 addresses
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8046d2b700] [dns] - static: new address resolved 169.254.170.2 for host 169.254.170.2 caching
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8046d2b700] [dns] - static, invoking resolution callback for host 169.254.170.2 with 1 addresses
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8030001280: Scheduling attempt_connection task for immediate execution
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8030001280: Running attempt_connection task with <Running> status
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: initializing with domain 0 and type 0
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: setting socket options to: keep-alive 0, keep idle 0, keep-alive interval 0, keep-alive probe count 0.
  | 2021-01-21T13:20:12.199+01:00 | [WARN] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: setsockopt() for NO_SIGNAL failed with errno 92. If you are having SIGPIPE signals thrown, you may want to install a signal trap in your application layer.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: beginning connect.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: connecting to endpoint 169.254.170.2:80.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038000fc0: Scheduling (null) task for future execution at time 68022077124
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038001370: Scheduling epoll_event_loop_unsubscribe_cleanup task for immediate execution
  | 2021-01-21T13:20:12.199+01:00 | [INFO] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: connection success
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: local endpoint 169.254.172.42:54372
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket] - id=0x7f8038001070 fd=9: assigning to event loop 0x555facb40370
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [channel-bootstrap] - id=0x555facb3cc30: client connection on socket 0x7f8038001070 completed with error 0.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [channel] - id=0x7f8038001670: Beginning creation and setup of new channel.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038001a90: Scheduling on_channel_setup_complete task for immediate execution
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038001370: Running epoll_event_loop_unsubscribe_cleanup task with <Running> status
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038001a90: Running on_channel_setup_complete task with <Running> status
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [channel] - id=0x7f8038001670: setup complete, notifying caller.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [channel] - id=0x7f8038001670: no message pool is currently stored in the event-loop local storage, adding 0x7f8038001c00 with max message size 16384, message count 4, with 4 small blocks of 128 bytes.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [channel-bootstrap] - id=0x555facb3cc30: channel 0x7f8038001670 setup succeeded: bootstrapping.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [socket-handler] - id=0x7f8038012860: Socket handler created with max_read_size of 16384
  | 2021-01-21T13:20:12.199+01:00 | [INFO] [2021-01-21T12:20:12Z] [00007f8047d2d700] [http-connection] - id=0x7f8038012aa0: HTTP/1.1 client connection established.
  | 2021-01-21T13:20:12.199+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [connection-manager] - id=0x555faccbf520: Received new connection (id=0x7f8038012aa0) from http layer
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [connection-manager] - id=0x555faccbf520: Grabbing pooled connection (0x7f8038012aa0)
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [connection-manager] - id=0x555faccbf520: snapshot - state=1, idle_connection_count=0, pending_acquire_count=0, pending_connect_count=0, vended_connection_count=1, open_connection_count=1, ref_count=1
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [connection-manager] - id=0x555faccbf520: Successfully completed connection acquisition with connection id=0x7f8038012aa0
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [http-stream] - id=0x7f80380133a0: Created client request on connection=0x7f8038012aa0: GET /v2/credentials/a98a83b0-8249-4cd1-99b1-676543e1992a HTTP/1.1
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038012b98: Scheduling http1_connection_cross_thread_work task for immediate execution
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038012b98: Running http1_connection_cross_thread_work task with <Running> status
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038012b30: Scheduling http1_connection_outgoing_stream task for immediate execution
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038012b30: Running http1_connection_outgoing_stream task with <Running> status
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [AuthCredentialsProvider] - (id=0x555facd65930) ECS credentials provider query received http status code 400
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [http-stream] - id=0x7f80380133a0: Client request complete, response status: 400 (Bad Request).
  | 2021-01-21T13:20:12.200+01:00 | [INFO] [2021-01-21T12:20:12Z] [00007f8047d2d700] [http-connection] - id=0x7f8038012aa0: Shutting down connection with error code 0 (AWS_ERROR_SUCCESS).
  | 2021-01-21T13:20:12.200+01:00 | [DEBUG] [2021-01-21T12:20:12Z] [00007f8047d2d700] [task-scheduler] - id=0x7f8038001870: Scheduling channel_shutdown task for immediate execution
  | 2021-01-21T13:20:12.200+01:00 | [ERROR] [2021-01-21T12:20:12Z] [00007f8047d2d700] [AuthCredentialsProvider] - Failed to parse document as Json document.
  | 2021-01-21T13:20:12.200+01:00 | [WARN] [2021-01-21T12:20:12Z] [00007f8047d2d700] [AuthCredentialsProvider] - (id=0x555facd65930) ECS credentials provider failed to query instance role credentials with error 6157(Unsuccessful status code returned from credentials-fetching http request)```

IMDSv2 credentials provider hangs forever from Docker container

When I create a client in container environment and the http-put-response-hop-limit of the host instance is 1, the IMDS credentials provider would hang forever.

Looking at the code, I expect the credentials provider to time out because we will never get a response back from the server and then fall back to IMDSv1. However, that does not happen.

My initial thought is that we only have connect_timeout here in the CRT's http client, while looking at the timeout configuration of the SDK like aws-rust-sdk, they have both connect_timeout and read_timeout. Is this something missing from the CRT config?

Default provider chain does not support SSO profile-defined credentials

Describe the bug

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-c-auth version used

v0.9.12 (Submoduled from aws-crt v1.21.0)

Compiler and version used

GNU libc 2.33 x86_64

Operating System and version

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

[STS web identity] TLS negotiation timeout too small

This was observed in the STS Web Identity provider, but could be a general problem affecting other credential providers as well.

Problem description

In production we experiences STS Web Identity TLS negotiation timeout of more than 10 seconds (the default).

Here is one of the traces we captured:

3/11/2022, 1:34:11 PM UTC	stdout	[ERROR] 2022-03-11 13:34:11.117 file-utils [140518474917760] static: Failed to open file /root/.aws/config with errno 2
3/11/2022, 1:34:11 PM UTC	stdout	[WARN] 2022-03-11 13:34:11.117 AuthProfile [140518474917760] Failed to read file at "/root/.aws/config"
3/11/2022, 1:34:11 PM UTC	stdout	[ERROR] 2022-03-11 13:34:11.117 file-utils [140518474917760] static: Failed to open file /root/.aws/credentials with errno 2
3/11/2022, 1:34:11 PM UTC	stdout	[WARN] 2022-03-11 13:34:11.117 AuthProfile [140518474917760] Failed to read file at "/root/.aws/credentials"
3/11/2022, 1:34:11 PM UTC	stdout	[ERROR] 2022-03-11 13:34:11.117 AuthCredentialsProvider [140518474917760] static: Profile credentials parser could not load or parse a credentials or config file.
3/11/2022, 1:34:21 PM UTC	stdout	[ERROR] 2022-03-11 13:34:21.164 http-connection [140518184900352] static: Client connection failed with error 1067 (AWS_IO_TLS_NEGOTIATION_TIMEOUT).
3/11/2022, 1:34:21 PM UTC	stdout	[WARN] 2022-03-11 13:34:21.164 connection-manager [140518184900352] id=0x7fcd00063b00: Failed to obtain new connection from http layer, error 1067(Channel shutdown due to tls negotiation timeout)
3/11/2022, 1:34:21 PM UTC	stdout	[WARN] 2022-03-11 13:34:21.164 connection-manager [140518184900352] id=0x7fcd00063b00: Failed to complete connection acquisition with error_code 1067(Channel shutdown due to tls negotiation timeout)
3/11/2022, 1:34:21 PM UTC	stdout	[WARN] 2022-03-11 13:34:21.164 AuthCredentialsProvider [140518184900352] id=0x7fcce7d4afe0: STS_WEB_IDENTITY provider failed to acquire a connection, error code 1067(Channel shutdown due to tls negotiation timeout)
3/11/2022, 1:34:21 PM UTC	stdout	[WARN] 2022-03-11 13:34:21.164 AuthCredentialsProvider [140518184900352] (id=0x7fcce7d4afe0) STS_WEB_IDENTITY credentials provider failed to query credentials

We decided to use a TLS negotiation timeout of multiples of the TCP timeout, since TLS handshakes consume 2 extra RTTs.

Potential fix

This is how we solved the problem in our code:

--- a/source/credentials_provider_sts_web_identity.c
+++ b/source/credentials_provider_sts_web_identity.c
@@ -1213,6 +1213,12 @@ struct aws_credentials_provider *aws_credentials_provider_new_sts_web_identity(
     }

     aws_tls_connection_options_init_from_ctx(&tls_connection_options, options->tls_ctx);
+    /*
+     * Override the TLS timeout. The default of 10s has led to timeouts.
+     * Since TLS has a higher overhead than TCP, use multiples of the connection timeout.
+     */
+    tls_connection_options.timeout_ms = 3 * STS_WEB_IDENTITY_CONNECT_TIMEOUT_DEFAULT_IN_SECONDS * 1000 /*msec*/;
+
     struct aws_byte_cursor host = aws_byte_cursor_from_buf(&parameters->endpoint);
     if (aws_tls_connection_options_set_server_name(&tls_connection_options, allocator, &host)) {
         AWS_LOGF_ERROR(

Clarification on SigV4 test encoding

The SigV4 test suite expects request paths to be URI-encoded one time for the canonical request. For example, get-space-normalized expects /example space/ to be canonicalized as /example%20space/. According to the public SigV4 docs, though, AWS services except S3 expect double-encoded paths in the canonical request (e.g. /example%2520space/). This is confirmed through tests against AWS services.

It would help to know if this is expected and we should add a flag in our tests to use single-encoding like S3.

Testsuite hangs forever after test 232

I just packaged aws-c-auth for openSUSE and noticed that the testsuite hangs forever after test 232:

[   14s] 228/234 Test #234: sigv4_get_space_unnormalized_test .............................................   Passed    0.01 sec
[   15s] 229/234 Test  #36: credentials_provider_ecs_real_new_destroy .....................................   Passed    1.01 sec
[   15s] 230/234 Test  #43: credentials_provider_x509_real_new_destroy ....................................   Passed    1.01 sec
[   15s] 231/234 Test  #77: imds_client_multiple_resource_requests_random_responses_finally_all_success ...   Passed    1.06 sec
[   20s] 232/234 Test  #28: credentials_provider_imds_real_new_destroy ....................................   Passed    6.01 sec

Allow ECS credential provider ports to be configured to enable binding and integration testing

As is the ports used to connect to the credential-providing service for ECS environments is hard coded to 443/80. These low ports present a problem for cases in which we wish to execute tests that exercise this credential provider as we cannot run a test service on these ports without changes to the host machine running the test.

Expected behavior:
As a binding developer I can specify the ports used by the ECS credential provider to retrieve credentials

Actual behavior:
ECS credential provider will only read from 443/80

`aws_credentials_provider_new_chain_default` hangs without ever calling credentialsCallBack

Issue:

The function aws_credentials_provider_new_chain_default hangs (its callback is never invoked) in the code sample that is shown below in a Kubernetes/EKS context.

Background:

The Kubernetes/EKS setup for obtaining credentials using IRSA requires STS::AssumeRoleWithWebIdentity functionality in conjunction with a proper EKS service account setup.

Additionally, EKS uses the same JWT method that web browsers do, and hence TLS with the credential authority needs to be set up as well, as the code below does, "as though" the EKS node is an end-user website, so to speak. The JWT token in the case of EKS nodes is located in this scenario not in a web browser's cache, but instead in the running pods at the following path: /var/run/secrets/eks.amazonaws.com/serviceaccount/token .

(You don't need to do this for an EC2 instance that has been granted the same service account role outside of EKS.)

Additionally, notice the documentation for aws_credentials_provider_new_chain_default (from the source code at /include/aws/auth/credentials.h):

(Documentation for aws_credentials_provider_new_chain_default)

Creates the default provider chain used by most AWS SDKs.
Generally:
(1) Environment
(2) Profile
(3) STS web identity

...So this function claims to support STS web identity (3rd option). Even more so in that case, it should not hang.

In the code below, unfortunately this function IS hanging (in the sense that the credentialsCallback is never called).

I suspect the function is hanging for one of two reasons (I haven't done testing to determine which):

  1. When the TLS data structure is not set up (and just left as nullptr)
  2. The function just doesn't support the STS::AssumeRoleWithWebIdentity functionality in this EKS context (despite its claim above)

In either scenario, the function should not hang. At the very least, it should invoke the callback with some kind of error message.

But, in particular because the function supports the STS web identity method, if the problem is the TLS structure not being set, this function should notice that the EKS JWT token is available on the system and therefore if the TLS settings are not initialized properly it should be aware of this and invoke the callback with an error message stating something like when EKS JWT tokens are in use, the TLS context in the provider chain options must be initialized.

Here is a short code snippet exhibiting both the bug, and a working version (see the #if IS_USING_KUBERNETES block):

int EnclaveCommander::readCredentials()
{
    // ...
    struct aws_credentials_provider *provider_chain = nullptr;
    // ...
    auto cleanup = [&](){/* ... */}
    // ...
    struct aws_client_bootstrap_options bootstrap_options = {/* ... */};
    struct aws_client_bootstrap *bootstrap = aws_client_bootstrap_new(m_app_ctx.allocator, &bootstrap_options);
    // ...
    struct aws_credentials_provider_sts_web_identity_options chain_options = {.bootstrap=bootstrap /* ... */};
#if IS_USING_KUBERNETES == 1
    fprintf(stderr, "EKS context.\n");
    ###
    # This code block works. There are two changes:
    # 1. The TLS structure is set up
    # 2. The function `aws_credentials_provider_new_sts_web_identity` is called,
    #     rather than the `aws_credentials_provider_new_chain_default` function,
    #     because I know that `STS::AssumeRoleWithWebIdentity` is required,
    #     so no need to call the generic function (as it is below)
    ###
    struct aws_tls_ctx_options tls_options;
    aws_tls_ctx_options_init_default_client(&tls_options, m_app_ctx.allocator);
    chain_options.tls_ctx = aws_tls_client_ctx_new(m_app_ctx.allocator, &tls_options);
    chain_options.function_table = nullptr; // For mocking the http layer in tests, leave NULL otherwise
    provider_chain = aws_credentials_provider_new_sts_web_identity(m_app_ctx.allocator, &chain_options);
#else
    fprintf(stderr, "Human-at-the-keyboard context.\n");
    ###
    # This code exhibits the problem.
    # With `aws_credentials_provider_new_chain_default` called here,
    # the following call to `aws_credentials_provider_get_credentials` hangs -
    # (i.e, its callback is never invoked)
    ###
    provider_chain = aws_credentials_provider_new_chain_default(m_app_ctx.allocator, &chain_options);
#endif
    // ...
    ###
    # This is the function that passes the callback that is never called
    ###
    rc = aws_credentials_provider_get_credentials(provider_chain, credentialsCallBack, &m_app_ctx);
    // ...
    aws_mutex_lock(&m_app_ctx.mutex);
    ###
    # This is the function that hangs.
    # It hangs because the callback, above, is never invoked, so the wait condition is never reached.
    ###
    aws_condition_variable_wait_pred(&m_app_ctx.c_var, &m_app_ctx.mutex, credentialsPredicate, &m_app_ctx);
    aws_mutex_unlock(&m_app_ctx.mutex);    
    // ...
    return cleanup();
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.