From bb3568869627a72762bb12c6915d44d57d12ae66 Mon Sep 17 00:00:00 2001 From: Zelda Hessler Date: Wed, 4 Oct 2023 10:02:14 -0500 Subject: [PATCH] fix use_fips in provider config (#3007) I'm not 100% that I fixed this in the right way. Feel free to set me straight if that's the case. ## Motivation and Context aws-sdk-rust#882 ## Description This change causes the`ProviderConfig` to respect both `use_fips` and `use_dual_stack` when those settings are configured in a user's environment or profile. ## Testing I wrote two tests ## Checklist - [x] I have updated `CHANGELOG.next.toml` if I made changes to the smithy-rs codegen or runtime crates - [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS SDK, generated SDK code, or SDK runtime crates ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --------- Co-authored-by: John DiSanti --- CHANGELOG.next.toml | 6 + .../src/default_provider/credentials.rs | 3 + .../aws-config/src/environment/credentials.rs | 2 +- aws/rust-runtime/aws-config/src/lib.rs | 29 +++-- .../aws-config/src/profile/credentials.rs | 17 ++- .../src/profile/credentials/exec.rs | 21 ++-- .../aws-config/src/provider_config.rs | 62 ++++++++-- aws/rust-runtime/aws-config/src/sso.rs | 27 ++--- aws/rust-runtime/aws-config/src/sts.rs | 19 ---- .../aws-config/src/sts/assume_role.rs | 14 +-- aws/rust-runtime/aws-config/src/test_case.rs | 9 ++ .../aws-config/src/web_identity_token.rs | 2 +- .../e2e_fips_and_dual_stack_sso/env.json | 7 ++ .../fs/home/.aws/config | 6 + ...e00cba5f8355ec9d274ceb2bcebdfbeed0e12.json | 5 + .../http-traffic.json | 93 +++++++++++++++ .../test-case.json | 12 ++ .../e2e_fips_and_dual_stack_sts/env.json | 3 + .../fs/home/.aws/config | 9 ++ .../fs/home/.aws/credentials | 3 + .../http-traffic.json | 107 ++++++++++++++++++ .../test-case.json | 12 ++ 22 files changed, 384 insertions(+), 84 deletions(-) create mode 100644 aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/env.json create mode 100644 aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/config create mode 100644 aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/sso/cache/dace00cba5f8355ec9d274ceb2bcebdfbeed0e12.json create mode 100644 aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/http-traffic.json create mode 100644 aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/test-case.json create mode 100644 aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/env.json create mode 100644 aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/config create mode 100644 aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/credentials create mode 100644 aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/http-traffic.json create mode 100644 aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/test-case.json diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 620e4e2c3..d9ed61662 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -261,3 +261,9 @@ For more information, see the [Change Log Discussion](https://github.com/awslabs meta = { "breaking" = true, "tada" = false, "bug" = false } references = ["smithy-rs#3014"] author = "rcoh" + +[[aws-sdk-rust]] +message = "STS and SSO-based credential providers will now respect both `use_fips` and `use_dual_stack` when those settings are configured in a user's environment or profile." +references = ["aws-sdk-rust#882", "smithy-rs#3007"] +meta = { "breaking" = true, "tada" = true, "bug" = true } +author = "Velfi" diff --git a/aws/rust-runtime/aws-config/src/default_provider/credentials.rs b/aws/rust-runtime/aws-config/src/default_provider/credentials.rs index a5e1fb0dc..30fd0101a 100644 --- a/aws/rust-runtime/aws-config/src/default_provider/credentials.rs +++ b/aws/rust-runtime/aws-config/src/default_provider/credentials.rs @@ -306,6 +306,9 @@ mod test { #[cfg(feature = "credentials-sso")] make_test!(sso_no_token_file); + #[cfg(feature = "credentials-sso")] + make_test!(e2e_fips_and_dual_stack_sso); + #[tokio::test] async fn profile_name_override() { let conf = diff --git a/aws/rust-runtime/aws-config/src/environment/credentials.rs b/aws/rust-runtime/aws-config/src/environment/credentials.rs index 2004bed40..fa015df41 100644 --- a/aws/rust-runtime/aws-config/src/environment/credentials.rs +++ b/aws/rust-runtime/aws-config/src/environment/credentials.rs @@ -245,6 +245,6 @@ mod test { fn real_environment() { let provider = EnvironmentVariableCredentialsProvider::new(); // we don't know what's in the env, just make sure it doesn't crash. - let _ = provider.provide_credentials(); + let _fut = provider.provide_credentials(); } } diff --git a/aws/rust-runtime/aws-config/src/lib.rs b/aws/rust-runtime/aws-config/src/lib.rs index e1d8657d8..b39bcf571 100644 --- a/aws/rust-runtime/aws-config/src/lib.rs +++ b/aws/rust-runtime/aws-config/src/lib.rs @@ -589,6 +589,23 @@ mod loader { .with_http_connector(http_connector.clone()) }) .with_profile_config(self.profile_files_override, self.profile_name_override); + + let use_fips = if let Some(use_fips) = self.use_fips { + Some(use_fips) + } else { + use_fips_provider(&conf).await + }; + + let use_dual_stack = if let Some(use_dual_stack) = self.use_dual_stack { + Some(use_dual_stack) + } else { + use_dual_stack_provider(&conf).await + }; + + let conf = conf + .with_use_fips(use_fips) + .with_use_dual_stack(use_dual_stack); + let region = if let Some(provider) = self.region { provider.region().await } else { @@ -648,18 +665,6 @@ mod loader { None }; - let use_fips = if let Some(use_fips) = self.use_fips { - Some(use_fips) - } else { - use_fips_provider(&conf).await - }; - - let use_dual_stack = if let Some(use_dual_stack) = self.use_dual_stack { - Some(use_dual_stack) - } else { - use_dual_stack_provider(&conf).await - }; - let mut builder = SdkConfig::builder() .region(region) .retry_config(retry_config) diff --git a/aws/rust-runtime/aws-config/src/profile/credentials.rs b/aws/rust-runtime/aws-config/src/profile/credentials.rs index c3d08e58d..f38090260 100644 --- a/aws/rust-runtime/aws-config/src/profile/credentials.rs +++ b/aws/rust-runtime/aws-config/src/profile/credentials.rs @@ -22,15 +22,13 @@ //! - `exec` which contains a chain representation of providers to implement passing bootstrapped credentials //! through a series of providers. -use crate::profile::credentials::exec::named::NamedProviderFactory; -use crate::profile::credentials::exec::ProviderChain; use crate::profile::parser::ProfileFileLoadError; use crate::profile::profile_file::ProfileFiles; use crate::profile::Profile; use crate::provider_config::ProviderConfig; use aws_credential_types::provider::{self, error::CredentialsError, future, ProvideCredentials}; -use aws_sdk_sts::config::Builder as StsConfigBuilder; use aws_smithy_types::error::display::DisplayErrorContext; +use aws_types::SdkConfig; use std::borrow::Cow; use std::collections::HashMap; use std::error::Error; @@ -141,8 +139,8 @@ impl ProvideCredentials for ProfileFileCredentialsProvider { #[doc = include_str!("location_of_profile_files.md")] #[derive(Debug)] pub struct ProfileFileCredentialsProvider { - factory: NamedProviderFactory, - sts_config: StsConfigBuilder, + factory: exec::named::NamedProviderFactory, + sdk_config: SdkConfig, provider_config: ProviderConfig, } @@ -182,7 +180,7 @@ impl ProfileFileCredentialsProvider { }; for provider in inner_provider.chain().iter() { let next_creds = provider - .credentials(creds, &self.sts_config) + .credentials(creds, &self.sdk_config) .instrument(tracing::debug_span!("load_assume_role", provider = ?provider)) .await; match next_creds { @@ -444,7 +442,7 @@ impl Builder { ProfileFileCredentialsProvider { factory, - sts_config: conf.sts_client_config(), + sdk_config: conf.client_config("profile file"), provider_config: conf, } } @@ -452,8 +450,8 @@ impl Builder { async fn build_provider_chain( provider_config: &ProviderConfig, - factory: &NamedProviderFactory, -) -> Result { + factory: &exec::named::NamedProviderFactory, +) -> Result { let profile_set = provider_config .try_profile() .await @@ -485,6 +483,7 @@ mod test { } make_test!(e2e_assume_role); + make_test!(e2e_fips_and_dual_stack_sts); make_test!(empty_config); make_test!(retry_on_error); make_test!(invalid_config); diff --git a/aws/rust-runtime/aws-config/src/profile/credentials/exec.rs b/aws/rust-runtime/aws-config/src/profile/credentials/exec.rs index 838007ad1..48a8d0c88 100644 --- a/aws/rust-runtime/aws-config/src/profile/credentials/exec.rs +++ b/aws/rust-runtime/aws-config/src/profile/credentials/exec.rs @@ -11,10 +11,13 @@ use crate::provider_config::ProviderConfig; use crate::sso::{SsoCredentialsProvider, SsoProviderConfig}; use crate::sts; use crate::web_identity_token::{StaticConfiguration, WebIdentityTokenCredentialsProvider}; -use aws_credential_types::provider::{self, error::CredentialsError, ProvideCredentials}; -use aws_sdk_sts::config::{Builder as StsConfigBuilder, Credentials}; +use aws_credential_types::provider::{ + self, error::CredentialsError, ProvideCredentials, SharedCredentialsProvider, +}; +use aws_sdk_sts::config::Credentials; use aws_sdk_sts::Client as StsClient; use aws_smithy_async::time::SharedTimeSource; +use aws_types::SdkConfig; use std::fmt::Debug; use std::sync::Arc; @@ -30,13 +33,13 @@ impl AssumeRoleProvider { pub(super) async fn credentials( &self, input_credentials: Credentials, - sts_config: &StsConfigBuilder, + sdk_config: &SdkConfig, ) -> provider::Result { - let config = sts_config - .clone() - .credentials_provider(input_credentials) + let config = sdk_config + .to_builder() + .credentials_provider(SharedCredentialsProvider::new(input_credentials)) .build(); - let client = StsClient::from_conf(config); + let client = StsClient::new(&config); let session_name = &self.session_name.as_ref().cloned().unwrap_or_else(|| { sts::util::default_session_name("assume-role-from-profile", self.time_source.now()) }); @@ -143,8 +146,8 @@ impl ProviderChain { tracing::info!(role_arn = ?role_arn, "which will be used to assume a role"); AssumeRoleProvider { role_arn: role_arn.role_arn.into(), - external_id: role_arn.external_id.map(|id| id.into()), - session_name: role_arn.session_name.map(|id| id.into()), + external_id: role_arn.external_id.map(Into::into), + session_name: role_arn.session_name.map(Into::into), time_source: provider_config.time_source(), } }) diff --git a/aws/rust-runtime/aws-config/src/provider_config.rs b/aws/rust-runtime/aws-config/src/provider_config.rs index f1caa75e5..ec543a7b6 100644 --- a/aws/rust-runtime/aws-config/src/provider_config.rs +++ b/aws/rust-runtime/aws-config/src/provider_config.rs @@ -5,27 +5,26 @@ //! Configuration Options for Credential Providers +use crate::connector::{default_connector, expect_connector}; +use crate::profile; +use crate::profile::profile_file::ProfileFiles; +use crate::profile::{ProfileFileLoadError, ProfileSet}; use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, SharedAsyncSleep}; use aws_smithy_async::time::SharedTimeSource; use aws_smithy_client::erase::DynConnector; use aws_smithy_types::error::display::DisplayErrorContext; +use aws_smithy_types::retry::RetryConfig; use aws_types::os_shim_internal::{Env, Fs}; use aws_types::{ http_connector::{ConnectorSettings, HttpConnector}, region::Region, + SdkConfig, }; use std::borrow::Cow; - use std::fmt::{Debug, Formatter}; use std::sync::Arc; use tokio::sync::OnceCell; -use crate::connector::default_connector; -use crate::profile; - -use crate::profile::profile_file::ProfileFiles; -use crate::profile::{ProfileFileLoadError, ProfileSet}; - /// Configuration options for Credential Providers /// /// Most credential providers builders offer a `configure` method which applies general provider configuration @@ -42,6 +41,8 @@ pub struct ProviderConfig { connector: HttpConnector, sleep: Option, region: Option, + use_fips: Option, + use_dual_stack: Option, /// An AWS profile created from `ProfileFiles` and a `profile_name` parsed_profile: Arc>>, /// A list of [std::path::Path]s to profile files @@ -57,6 +58,8 @@ impl Debug for ProviderConfig { .field("fs", &self.fs) .field("sleep", &self.sleep) .field("region", &self.region) + .field("use_fips", &self.use_fips) + .field("use_dual_stack", &self.use_dual_stack) .finish() } } @@ -76,6 +79,8 @@ impl Default for ProviderConfig { connector, sleep: default_async_sleep(), region: None, + use_fips: None, + use_dual_stack: None, parsed_profile: Default::default(), profile_files: ProfileFiles::default(), profile_name_override: None, @@ -104,6 +109,8 @@ impl ProviderConfig { connector: HttpConnector::Prebuilt(None), sleep: None, region: None, + use_fips: None, + use_dual_stack: None, profile_name_override: None, } } @@ -144,6 +151,8 @@ impl ProviderConfig { connector: HttpConnector::Prebuilt(None), sleep: None, region: None, + use_fips: None, + use_dual_stack: None, parsed_profile: Default::default(), profile_files: ProfileFiles::default(), profile_name_override: None, @@ -161,6 +170,8 @@ impl ProviderConfig { connector: HttpConnector::Prebuilt(None), sleep, region: None, + use_fips: None, + use_dual_stack: None, profile_name_override: None, } } @@ -181,6 +192,21 @@ impl ProviderConfig { Self::without_region().load_default_region().await } + pub(crate) fn client_config(&self, feature_name: &str) -> SdkConfig { + let mut builder = SdkConfig::builder() + .http_connector(expect_connector( + &format!("The {feature_name} features of aws-config"), + self.connector(&Default::default()), + )) + .retry_config(RetryConfig::standard()) + .region(self.region()) + .time_source(self.time_source()) + .use_fips(self.use_fips().unwrap_or_default()) + .use_dual_stack(self.use_dual_stack().unwrap_or_default()); + builder.set_sleep_impl(self.sleep()); + builder.build() + } + // When all crate features are disabled, these accessors are unused #[allow(dead_code)] @@ -219,6 +245,16 @@ impl ProviderConfig { self.region.clone() } + #[allow(dead_code)] + pub(crate) fn use_fips(&self) -> Option { + self.use_fips + } + + #[allow(dead_code)] + pub(crate) fn use_dual_stack(&self) -> Option { + self.use_dual_stack + } + pub(crate) async fn try_profile(&self) -> Result<&ProfileSet, &ProfileFileLoadError> { let parsed_profile = self .parsed_profile @@ -249,6 +285,18 @@ impl ProviderConfig { self } + /// Override the `use_fips` setting. + pub(crate) fn with_use_fips(mut self, use_fips: Option) -> Self { + self.use_fips = use_fips; + self + } + + /// Override the `use_dual_stack` setting. + pub(crate) fn with_use_dual_stack(mut self, use_dual_stack: Option) -> Self { + self.use_dual_stack = use_dual_stack; + self + } + pub(crate) fn with_profile_name(self, profile_name: String) -> Self { let profile_files = self.profile_files.clone(); self.with_profile_config(Some(profile_files), Some(profile_name)) diff --git a/aws/rust-runtime/aws-config/src/sso.rs b/aws/rust-runtime/aws-config/src/sso.rs index 592ed5b6b..7a601f7be 100644 --- a/aws/rust-runtime/aws-config/src/sso.rs +++ b/aws/rust-runtime/aws-config/src/sso.rs @@ -18,12 +18,13 @@ use aws_credential_types::cache::CredentialsCache; use aws_credential_types::provider::{self, error::CredentialsError, future, ProvideCredentials}; use aws_credential_types::Credentials; use aws_sdk_sso::types::RoleCredentials; -use aws_sdk_sso::{config::Builder as SsoConfigBuilder, Client as SsoClient, Config as SsoConfig}; +use aws_sdk_sso::Client as SsoClient; use aws_smithy_json::deserialize::Token; use aws_smithy_types::date_time::Format; use aws_smithy_types::DateTime; use aws_types::os_shim_internal::{Env, Fs}; use aws_types::region::Region; +use aws_types::SdkConfig; use std::convert::TryInto; use std::error::Error; @@ -31,8 +32,6 @@ use std::fmt::{Display, Formatter}; use std::io; use std::path::PathBuf; -use crate::connector::expect_connector; -use aws_smithy_types::retry::RetryConfig; use ring::digest; use zeroize::Zeroizing; @@ -47,7 +46,7 @@ pub struct SsoCredentialsProvider { fs: Fs, env: Env, sso_provider_config: SsoProviderConfig, - sso_config: SsoConfigBuilder, + sdk_config: SdkConfig, } impl SsoCredentialsProvider { @@ -63,26 +62,18 @@ impl SsoCredentialsProvider { let fs = provider_config.fs(); let env = provider_config.env(); - let mut sso_config = SsoConfig::builder() - .http_connector(expect_connector( - "The SSO credentials provider", - provider_config.connector(&Default::default()), - )) - .retry_config(RetryConfig::standard()); - sso_config.set_sleep_impl(provider_config.sleep()); - SsoCredentialsProvider { fs, env, sso_provider_config, - sso_config, + sdk_config: provider_config.client_config("SSO"), } } async fn credentials(&self) -> provider::Result { load_sso_credentials( &self.sso_provider_config, - &self.sso_config, + &self.sdk_config, &self.env, &self.fs, ) @@ -206,20 +197,20 @@ pub(crate) struct SsoProviderConfig { async fn load_sso_credentials( sso_provider_config: &SsoProviderConfig, - sso_config: &SsoConfigBuilder, + sdk_config: &SdkConfig, env: &Env, fs: &Fs, ) -> provider::Result { let token = load_token(&sso_provider_config.start_url, env, fs) .await .map_err(CredentialsError::provider_error)?; - let config = sso_config - .clone() + let config = sdk_config + .to_builder() .region(sso_provider_config.region.clone()) .credentials_cache(CredentialsCache::no_caching()) .build(); // TODO(enableNewSmithyRuntimeCleanup): Use `customize().config_override()` to set the region instead of creating a new client once middleware is removed - let client = SsoClient::from_conf(config); + let client = SsoClient::new(&config); let resp = client .get_role_credentials() .role_name(&sso_provider_config.role_name) diff --git a/aws/rust-runtime/aws-config/src/sts.rs b/aws/rust-runtime/aws-config/src/sts.rs index 028409bfb..f774c6590 100644 --- a/aws/rust-runtime/aws-config/src/sts.rs +++ b/aws/rust-runtime/aws-config/src/sts.rs @@ -10,22 +10,3 @@ pub(crate) mod util; pub use assume_role::{AssumeRoleProvider, AssumeRoleProviderBuilder}; mod assume_role; - -use crate::connector::expect_connector; -use aws_sdk_sts::config::Builder as StsConfigBuilder; -use aws_smithy_types::retry::RetryConfig; - -impl crate::provider_config::ProviderConfig { - pub(crate) fn sts_client_config(&self) -> StsConfigBuilder { - let mut builder = aws_sdk_sts::Config::builder() - .http_connector(expect_connector( - "The STS features of aws-config", - self.connector(&Default::default()), - )) - .retry_config(RetryConfig::standard()) - .region(self.region()) - .time_source(self.time_source()); - builder.set_sleep_impl(self.sleep()); - builder - } -} diff --git a/aws/rust-runtime/aws-config/src/sts/assume_role.rs b/aws/rust-runtime/aws-config/src/sts/assume_role.rs index 3dd290fc8..06e79bc35 100644 --- a/aws/rust-runtime/aws-config/src/sts/assume_role.rs +++ b/aws/rust-runtime/aws-config/src/sts/assume_role.rs @@ -362,7 +362,7 @@ mod test { #[tokio::test] async fn configures_session_length() { let (server, request) = capture_request(None); - let provider_conf = SdkConfig::builder() + let sdk_config = SdkConfig::builder() .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .time_source(StaticTimeSource::new( UNIX_EPOCH + Duration::from_secs(1234567890 - 120), @@ -371,7 +371,7 @@ mod test { .region(Region::from_static("this-will-be-overridden")) .build(); let provider = AssumeRoleProvider::builder("myrole") - .configure(&provider_conf) + .configure(&sdk_config) .region(Region::new("us-east-1")) .session_length(Duration::from_secs(1234567)) .build_from_provider(provide_credentials_fn(|| async { @@ -388,7 +388,7 @@ mod test { #[tokio::test] async fn loads_region_from_sdk_config() { let (server, request) = capture_request(None); - let provider_conf = SdkConfig::builder() + let sdk_config = SdkConfig::builder() .sleep_impl(SharedAsyncSleep::new(TokioSleep::new())) .time_source(StaticTimeSource::new( UNIX_EPOCH + Duration::from_secs(1234567890 - 120), @@ -397,14 +397,12 @@ mod test { .credentials_provider(SharedCredentialsProvider::new(provide_credentials_fn( || async { panic!("don't call me — will be overridden"); - #[allow(unreachable_code)] - Ok(Credentials::for_tests()) }, ))) .region(Region::from_static("us-west-2")) .build(); let provider = AssumeRoleProvider::builder("myrole") - .configure(&provider_conf) + .configure(&sdk_config) .session_length(Duration::from_secs(1234567)) .build_from_provider(provide_credentials_fn(|| async { Ok(Credentials::for_tests()) @@ -476,7 +474,7 @@ mod test { UNIX_EPOCH + Duration::from_secs(1234567890 - 120), // 1234567890 since UNIX_EPOCH is 2009-02-13T23:31:30Z ); - let provider_conf = SdkConfig::builder() + let sdk_config = SdkConfig::builder() .sleep_impl(SharedAsyncSleep::new(sleep)) .time_source(testing_time_source.clone()) .http_connector(DynConnector::new(conn)) @@ -499,7 +497,7 @@ mod test { ])); let credentials_list_cloned = credentials_list.clone(); let provider = AssumeRoleProvider::builder("myrole") - .configure(&provider_conf) + .configure(&sdk_config) .region(Region::new("us-east-1")) .build_from_provider(provide_credentials_fn(move || { let list = credentials_list.clone(); diff --git a/aws/rust-runtime/aws-config/src/test_case.rs b/aws/rust-runtime/aws-config/src/test_case.rs index 14859d57e..54d39d112 100644 --- a/aws/rust-runtime/aws-config/src/test_case.rs +++ b/aws/rust-runtime/aws-config/src/test_case.rs @@ -14,6 +14,8 @@ use aws_types::os_shim_internal::{Env, Fs}; use serde::Deserialize; use crate::connector::default_connector; +use crate::default_provider::use_dual_stack::use_dual_stack_provider; +use crate::default_provider::use_fips::use_fips_provider; use aws_smithy_types::error::display::DisplayErrorContext; use std::collections::HashMap; use std::env; @@ -236,6 +238,13 @@ impl TestEnvironment { .with_sleep(TokioSleep::new()) .load_default_region() .await; + + let use_dual_stack = use_dual_stack_provider(&provider_config).await; + let use_fips = use_fips_provider(&provider_config).await; + let provider_config = provider_config + .with_use_fips(use_fips) + .with_use_dual_stack(use_dual_stack); + Ok(TestEnvironment { base_dir: dir.into(), metadata, diff --git a/aws/rust-runtime/aws-config/src/web_identity_token.rs b/aws/rust-runtime/aws-config/src/web_identity_token.rs index 7ea55fdf2..50d717122 100644 --- a/aws/rust-runtime/aws-config/src/web_identity_token.rs +++ b/aws/rust-runtime/aws-config/src/web_identity_token.rs @@ -204,7 +204,7 @@ impl Builder { WebIdentityTokenCredentialsProvider { source, fs: conf.fs(), - sts_client: StsClient::from_conf(conf.sts_client_config().build()), + sts_client: StsClient::new(&conf.client_config("STS")), time_source: conf.time_source(), } } diff --git a/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/env.json b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/env.json new file mode 100644 index 000000000..7e1f0ed5e --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/env.json @@ -0,0 +1,7 @@ +{ + "HOME": "/home", + "AWS_REGION": "us-west-2", + "AWS_PROFILE": "sso-test", + "AWS_USE_FIPS_ENDPOINT": "true", + "AWS_USE_DUALSTACK_ENDPOINT": "true" +} diff --git a/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/config b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/config new file mode 100644 index 000000000..796722104 --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/config @@ -0,0 +1,6 @@ +[profile sso-test] +sso_start_url = https://ssotest.awsapps.com/start +sso_region = us-east-2 +sso_account_id = 123456789 +sso_role_name = MySsoRole +region = us-east-2 diff --git a/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/sso/cache/dace00cba5f8355ec9d274ceb2bcebdfbeed0e12.json b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/sso/cache/dace00cba5f8355ec9d274ceb2bcebdfbeed0e12.json new file mode 100644 index 000000000..c4cca143f --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/fs/home/.aws/sso/cache/dace00cba5f8355ec9d274ceb2bcebdfbeed0e12.json @@ -0,0 +1,5 @@ +{ + "accessToken": "a-token", + "expiresAt": "2080-10-16T03:56:45Z", + "startUrl": "https://ssotest.awsapps.com/start" +} diff --git a/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/http-traffic.json b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/http-traffic.json new file mode 100644 index 000000000..f7f80963e --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/http-traffic.json @@ -0,0 +1,93 @@ +{ + "events": [ + { + "connection_id": 0, + "action": { + "Request": { + "request": { + "uri": "https://portal.sso-fips.us-east-2.api.aws/federation/credentials?account_id=123456789&role_name=MySsoRole", + "headers": { + "x-amz-sso_bearer_token": [ + "a-token" + ], + "Host": [ + "portal.sso-fips.us-east-2.api.aws" + ] + }, + "method": "GET" + } + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Request" + } + } + }, + { + "connection_id": 0, + "action": { + "Response": { + "response": { + "Ok": { + "status": 200, + "version": "HTTP/1.1", + "headers": { + "Date": [ + "Mon, 03 Jan 2022 19:13:54 GMT" + ], + "Content-Type": [ + "application/json" + ], + "Content-Length": [ + "144" + ], + "Connection": [ + "keep-alive" + ], + "Access-Control-Expose-Headers": [ + "RequestId" + ], + "Cache-Control": [ + "no-cache" + ], + "RequestId": [ + "b339b807-25d1-474c-a476-b070e9f350e4" + ], + "Server": [ + "AWS SSO" + ] + } + } + } + } + } + }, + { + "connection_id": 0, + "action": { + "Data": { + "data": { + "Utf8": "{\"roleCredentials\":{\"accessKeyId\":\"ASIARCORRECT\",\"secretAccessKey\":\"secretkeycorrect\",\"sessionToken\":\"tokencorrect\",\"expiration\":1234567890000}}" + }, + "direction": "Response" + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Response" + } + } + } + ], + "docs": "Load SSO credentials", + "version": "V0" +} diff --git a/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/test-case.json b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/test-case.json new file mode 100644 index 000000000..91d9a21d9 --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/default-provider-chain/e2e_fips_and_dual_stack_sso/test-case.json @@ -0,0 +1,12 @@ +{ + "name": "e2e_fips_and_dual_stack_sso", + "docs": "end to end SSO test with FIPS and dual stack enabled", + "result": { + "Ok": { + "access_key_id": "ASIARCORRECT", + "secret_access_key": "secretkeycorrect", + "session_token": "tokencorrect", + "expiry": 1234567890 + } + } +} diff --git a/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/env.json b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/env.json new file mode 100644 index 000000000..55fcfbeb0 --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/env.json @@ -0,0 +1,3 @@ +{ + "HOME": "/home" +} diff --git a/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/config b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/config new file mode 100644 index 000000000..17d486343 --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/config @@ -0,0 +1,9 @@ +[default] +region = us-east-1 +role_arn = arn:aws:iam::123456789:role/integration-test +source_profile = base +use_fips_endpoint = true +use_dualstack_endpoint = true + +[profile base] +region = us-east-1 diff --git a/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/credentials b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/credentials new file mode 100644 index 000000000..1cab6a6ca --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/fs/home/.aws/credentials @@ -0,0 +1,3 @@ +[base] +aws_access_key_id = AKIAFAKE +aws_secret_access_key = FAKE diff --git a/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/http-traffic.json b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/http-traffic.json new file mode 100644 index 000000000..000b74b8e --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/http-traffic.json @@ -0,0 +1,107 @@ +{ + "events": [ + { + "connection_id": 0, + "action": { + "Request": { + "request": { + "uri": "https://sts-fips.us-east-1.api.aws/", + "headers": { + "content-type": [ + "application/x-www-form-urlencoded" + ], + "authorization": [ + "AWS4-HMAC-SHA256 Credential=AKIAFAKE/20210810/us-east-1/sts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-user-agent, Signature=cd5cb2aa1d20717ca17692bcbda711797ae9eb8bb1130690b021b3952b7ae56e" + ], + "user-agent": [ + "aws-sdk-rust/0.1.0 os/macos lang/rust/1.55.0-nightly" + ], + "content-length": [ + "146" + ], + "x-amz-date": [ + "20210810T003833Z" + ], + "host": [ + "sts-fips.us-east-1.api.aws" + ], + "x-amz-user-agent": [ + "aws-sdk-rust/0.1.0 api/sts/0.0.14-alpha os/macos lang/rust/1.55.0-nightly" + ] + }, + "method": "POST" + } + } + } + }, + { + "connection_id": 0, + "action": { + "Data": { + "data": { + "Utf8": "Action=AssumeRole&Version=2011-06-15&RoleArn=arn%3Aaws%3Aiam%3A%3A123456789%3Arole%2Fintegration-test&RoleSessionName=assume-role-provider-session" + }, + "direction": "Request" + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Request" + } + } + }, + { + "connection_id": 0, + "action": { + "Response": { + "response": { + "Ok": { + "status": 200, + "version": "HTTP/1.1", + "headers": { + "date": [ + "Thu, 05 Aug 2021 18:58:02 GMT" + ], + "content-length": [ + "1491" + ], + "content-type": [ + "text/xml" + ], + "x-amzn-requestid": [ + "c2e971c2-702d-4124-9b1f-1670febbea18" + ] + } + } + } + } + } + }, + { + "connection_id": 0, + "action": { + "Data": { + "data": { + "Utf8": "\n \n \n AROARABCDEFGHIJKLMNOP:assume-role-provider-session\n arn:aws:sts::123456789012:assumed-role/integration-test/assume-role-provider-session\n \n \n ASIARTESTID\n TESTSECRETKEY\n TESTSESSIONTOKEN\n 2021-08-05T19:58:02Z\n \n \n \n c2e971c2-702d-4124-9b1f-1670febbea18\n \n\n" + }, + "direction": "Response" + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Response" + } + } + } + ], + "docs": "standard request / response with STS", + "version": "V0" +} diff --git a/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/test-case.json b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/test-case.json new file mode 100644 index 000000000..6d1c5079f --- /dev/null +++ b/aws/rust-runtime/aws-config/test-data/profile-provider/e2e_fips_and_dual_stack_sts/test-case.json @@ -0,0 +1,12 @@ +{ + "name": "e2e_fips_and_dual_stack_sts", + "docs": "end to end STS role assumption test with FIPS and dual stack enabled", + "result": { + "Ok": { + "access_key_id": "ASIARTESTID", + "secret_access_key": "TESTSECRETKEY", + "session_token": "TESTSESSIONTOKEN", + "expiry": 1628193482 + } + } +} -- GitLab