Unverified Commit 57459f04 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Fix optional auth in the orchestrator (#2808)

This PR:
- Renames "anonymous auth" to "no auth"
- Removes fallback to other auth schemes when an identity fails to
resolve (this was not complying to the reference architecture)
- Adds the ability to opt out of credentials in `ConfigLoader`, and
removes defaulting of the shared credentials cache if no credentials
provider is given
- Makes `ConfigBagAccessors` work on `FrozenLayer` and `CloneableLayer`
- Fixes STS and aws-config tests

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent fbeaab9d
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -250,11 +250,14 @@ mod test {
                .await
                .unwrap()
                .with_provider_config($provider_config_builder)
                .$func(|conf| async {
                .$func(|conf| {
                    let conf = conf.clone();
                    async move {
                        crate::default_provider::credentials::Builder::default()
                            .configure(conf)
                            .build()
                            .await
                    }
                })
                .await
            }
+71 −19
Original line number Diff line number Diff line
@@ -171,6 +171,17 @@ mod loader {
    use crate::profile::profile_file::ProfileFiles;
    use crate::provider_config::ProviderConfig;

    #[derive(Default, Debug)]
    enum CredentialsProviderOption {
        /// No provider was set by the user. We can set up the default credentials provider chain.
        #[default]
        NotSet,
        /// The credentials provider was explicitly unset. Do not set up a default chain.
        ExplicitlyUnset,
        /// Use the given credentials provider.
        Set(SharedCredentialsProvider),
    }

    /// Load a cross-service [`SdkConfig`](aws_types::SdkConfig) from the environment
    ///
    /// This builder supports overriding individual components of the generated config. Overriding a component
@@ -181,7 +192,7 @@ mod loader {
    pub struct ConfigLoader {
        app_name: Option<AppName>,
        credentials_cache: Option<CredentialsCache>,
        credentials_provider: Option<SharedCredentialsProvider>,
        credentials_provider: CredentialsProviderOption,
        endpoint_url: Option<String>,
        region: Option<Box<dyn ProvideRegion>>,
        retry_config: Option<RetryConfig>,
@@ -348,7 +359,33 @@ mod loader {
            mut self,
            credentials_provider: impl ProvideCredentials + 'static,
        ) -> Self {
            self.credentials_provider = Some(SharedCredentialsProvider::new(credentials_provider));
            self.credentials_provider = CredentialsProviderOption::Set(
                SharedCredentialsProvider::new(credentials_provider),
            );
            self
        }

        // TODO(enableNewSmithyRuntimeLaunch): Remove the doc hidden from this function
        #[doc(hidden)]
        /// Don't use credentials to sign requests.
        ///
        /// Turning off signing with credentials is necessary in some cases, such as using
        /// anonymous auth for S3, calling operations in STS that don't require a signature,
        /// or using token-based auth.
        ///
        /// # Examples
        ///
        /// Turn off credentials in order to call a service without signing:
        /// ```no_run
        /// # async fn create_config() {
        /// let config = aws_config::from_env()
        ///     .no_credentials()
        ///     .load()
        ///     .await;
        /// # }
        /// ```
        pub fn no_credentials(mut self) -> Self {
            self.credentials_provider = CredentialsProviderOption::ExplicitlyUnset;
            self
        }

@@ -570,13 +607,28 @@ mod loader {
                .http_connector
                .unwrap_or_else(|| HttpConnector::ConnectorFn(Arc::new(default_connector)));

            let credentials_cache = self.credentials_cache.unwrap_or_else(|| {
            let credentials_provider = match self.credentials_provider {
                CredentialsProviderOption::Set(provider) => Some(provider),
                CredentialsProviderOption::NotSet => {
                    let mut builder =
                        credentials::DefaultCredentialsChain::builder().configure(conf.clone());
                    builder.set_region(region.clone());
                    Some(SharedCredentialsProvider::new(builder.build().await))
                }
                CredentialsProviderOption::ExplicitlyUnset => None,
            };

            let credentials_cache = if credentials_provider.is_some() {
                Some(self.credentials_cache.unwrap_or_else(|| {
                    let mut builder = CredentialsCache::lazy_builder().time_source(
                        aws_credential_types::time_source::TimeSource::shared(conf.time_source()),
                    );
                    builder.set_sleep(conf.sleep());
                    builder.into_credentials_cache()
            });
                }))
            } else {
                None
            };

            let use_fips = if let Some(use_fips) = self.use_fips {
                Some(use_fips)
@@ -590,26 +642,18 @@ mod loader {
                use_dual_stack_provider(&conf).await
            };

            let credentials_provider = if let Some(provider) = self.credentials_provider {
                provider
            } else {
                let mut builder = credentials::DefaultCredentialsChain::builder().configure(conf);
                builder.set_region(region.clone());
                SharedCredentialsProvider::new(builder.build().await)
            };

            let ts = self.time_source.unwrap_or_default();

            let mut builder = SdkConfig::builder()
                .region(region)
                .retry_config(retry_config)
                .timeout_config(timeout_config)
                .credentials_cache(credentials_cache)
                .credentials_provider(credentials_provider)
                .time_source(ts)
                .http_connector(http_connector);

            builder.set_app_name(app_name);
            builder.set_credentials_cache(credentials_cache);
            builder.set_credentials_provider(credentials_provider);
            builder.set_sleep_impl(sleep_impl);
            builder.set_endpoint_url(self.endpoint_url);
            builder.set_use_fips(use_fips);
@@ -719,5 +763,13 @@ mod loader {
            let conf = base_conf().app_name(app_name.clone()).load().await;
            assert_eq!(Some(&app_name), conf.app_name());
        }

        #[cfg(aws_sdk_orchestrator_mode)]
        #[tokio::test]
        async fn disable_default_credentials() {
            let config = from_env().no_credentials().load().await;
            assert!(config.credentials_cache().is_none());
            assert!(config.credentials_provider().is_none());
        }
    }
}
+1 −3
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@ pub use assume_role::{AssumeRoleProvider, AssumeRoleProviderBuilder};
mod assume_role;

use crate::connector::expect_connector;
use aws_credential_types::cache::CredentialsCache;
use aws_sdk_sts::config::Builder as StsConfigBuilder;
use aws_smithy_types::retry::RetryConfig;

@@ -22,8 +21,7 @@ impl crate::provider_config::ProviderConfig {
            .http_connector(expect_connector(self.connector(&Default::default())))
            .retry_config(RetryConfig::standard())
            .region(self.region())
            .time_source(self.time_source())
            .credentials_cache(CredentialsCache::no_caching());
            .time_source(self.time_source());
        builder.set_sleep_impl(self.sleep());
        builder
    }
+2 −1
Original line number Diff line number Diff line
@@ -11,11 +11,12 @@ use aws_sigv4::http_request::SignableBody;
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::byte_stream;
use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
use aws_smithy_runtime_api::client::interceptors::context::{
    BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut,
};
use aws_smithy_runtime_api::client::interceptors::Interceptor;
use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, LoadedRequestBody};
use aws_smithy_runtime_api::client::orchestrator::LoadedRequestBody;
use aws_smithy_types::config_bag::ConfigBag;
use bytes::Bytes;
use http::header::{HeaderName, HeaderValue};
+1 −1
Original line number Diff line number Diff line
@@ -15,13 +15,13 @@ use aws_sigv4::http_request::SignableBody;
use aws_smithy_async::time::{SharedTimeSource, StaticTimeSource};
use aws_smithy_runtime::client::retries::strategy::NeverRetryStrategy;
use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
use aws_smithy_runtime_api::client::interceptors::context::{
    BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut,
};
use aws_smithy_runtime_api::client::interceptors::{
    disable_interceptor, Interceptor, InterceptorRegistrar, SharedInterceptor,
};
use aws_smithy_runtime_api::client::orchestrator::ConfigBagAccessors;
use aws_smithy_runtime_api::client::retries::DynRetryStrategy;
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
use aws_smithy_types::config_bag::{ConfigBag, FrozenLayer, Layer};
Loading