Skip to content

Commit 57459f0

Browse files
authored
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._
1 parent fbeaab9 commit 57459f0

File tree

71 files changed

+1425
-892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1425
-892
lines changed

aws/rust-runtime/aws-config/src/default_provider/credentials.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,14 @@ mod test {
250250
.await
251251
.unwrap()
252252
.with_provider_config($provider_config_builder)
253-
.$func(|conf| async {
254-
crate::default_provider::credentials::Builder::default()
255-
.configure(conf)
256-
.build()
257-
.await
253+
.$func(|conf| {
254+
let conf = conf.clone();
255+
async move {
256+
crate::default_provider::credentials::Builder::default()
257+
.configure(conf)
258+
.build()
259+
.await
260+
}
258261
})
259262
.await
260263
}

aws/rust-runtime/aws-config/src/lib.rs

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,17 @@ mod loader {
171171
use crate::profile::profile_file::ProfileFiles;
172172
use crate::provider_config::ProviderConfig;
173173

174+
#[derive(Default, Debug)]
175+
enum CredentialsProviderOption {
176+
/// No provider was set by the user. We can set up the default credentials provider chain.
177+
#[default]
178+
NotSet,
179+
/// The credentials provider was explicitly unset. Do not set up a default chain.
180+
ExplicitlyUnset,
181+
/// Use the given credentials provider.
182+
Set(SharedCredentialsProvider),
183+
}
184+
174185
/// Load a cross-service [`SdkConfig`](aws_types::SdkConfig) from the environment
175186
///
176187
/// This builder supports overriding individual components of the generated config. Overriding a component
@@ -181,7 +192,7 @@ mod loader {
181192
pub struct ConfigLoader {
182193
app_name: Option<AppName>,
183194
credentials_cache: Option<CredentialsCache>,
184-
credentials_provider: Option<SharedCredentialsProvider>,
195+
credentials_provider: CredentialsProviderOption,
185196
endpoint_url: Option<String>,
186197
region: Option<Box<dyn ProvideRegion>>,
187198
retry_config: Option<RetryConfig>,
@@ -348,7 +359,33 @@ mod loader {
348359
mut self,
349360
credentials_provider: impl ProvideCredentials + 'static,
350361
) -> Self {
351-
self.credentials_provider = Some(SharedCredentialsProvider::new(credentials_provider));
362+
self.credentials_provider = CredentialsProviderOption::Set(
363+
SharedCredentialsProvider::new(credentials_provider),
364+
);
365+
self
366+
}
367+
368+
// TODO(enableNewSmithyRuntimeLaunch): Remove the doc hidden from this function
369+
#[doc(hidden)]
370+
/// Don't use credentials to sign requests.
371+
///
372+
/// Turning off signing with credentials is necessary in some cases, such as using
373+
/// anonymous auth for S3, calling operations in STS that don't require a signature,
374+
/// or using token-based auth.
375+
///
376+
/// # Examples
377+
///
378+
/// Turn off credentials in order to call a service without signing:
379+
/// ```no_run
380+
/// # async fn create_config() {
381+
/// let config = aws_config::from_env()
382+
/// .no_credentials()
383+
/// .load()
384+
/// .await;
385+
/// # }
386+
/// ```
387+
pub fn no_credentials(mut self) -> Self {
388+
self.credentials_provider = CredentialsProviderOption::ExplicitlyUnset;
352389
self
353390
}
354391

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

573-
let credentials_cache = self.credentials_cache.unwrap_or_else(|| {
574-
let mut builder = CredentialsCache::lazy_builder().time_source(
575-
aws_credential_types::time_source::TimeSource::shared(conf.time_source()),
576-
);
577-
builder.set_sleep(conf.sleep());
578-
builder.into_credentials_cache()
579-
});
610+
let credentials_provider = match self.credentials_provider {
611+
CredentialsProviderOption::Set(provider) => Some(provider),
612+
CredentialsProviderOption::NotSet => {
613+
let mut builder =
614+
credentials::DefaultCredentialsChain::builder().configure(conf.clone());
615+
builder.set_region(region.clone());
616+
Some(SharedCredentialsProvider::new(builder.build().await))
617+
}
618+
CredentialsProviderOption::ExplicitlyUnset => None,
619+
};
620+
621+
let credentials_cache = if credentials_provider.is_some() {
622+
Some(self.credentials_cache.unwrap_or_else(|| {
623+
let mut builder = CredentialsCache::lazy_builder().time_source(
624+
aws_credential_types::time_source::TimeSource::shared(conf.time_source()),
625+
);
626+
builder.set_sleep(conf.sleep());
627+
builder.into_credentials_cache()
628+
}))
629+
} else {
630+
None
631+
};
580632

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

593-
let credentials_provider = if let Some(provider) = self.credentials_provider {
594-
provider
595-
} else {
596-
let mut builder = credentials::DefaultCredentialsChain::builder().configure(conf);
597-
builder.set_region(region.clone());
598-
SharedCredentialsProvider::new(builder.build().await)
599-
};
600-
601645
let ts = self.time_source.unwrap_or_default();
602646

603647
let mut builder = SdkConfig::builder()
604648
.region(region)
605649
.retry_config(retry_config)
606650
.timeout_config(timeout_config)
607-
.credentials_cache(credentials_cache)
608-
.credentials_provider(credentials_provider)
609651
.time_source(ts)
610652
.http_connector(http_connector);
611653

612654
builder.set_app_name(app_name);
655+
builder.set_credentials_cache(credentials_cache);
656+
builder.set_credentials_provider(credentials_provider);
613657
builder.set_sleep_impl(sleep_impl);
614658
builder.set_endpoint_url(self.endpoint_url);
615659
builder.set_use_fips(use_fips);
@@ -719,5 +763,13 @@ mod loader {
719763
let conf = base_conf().app_name(app_name.clone()).load().await;
720764
assert_eq!(Some(&app_name), conf.app_name());
721765
}
766+
767+
#[cfg(aws_sdk_orchestrator_mode)]
768+
#[tokio::test]
769+
async fn disable_default_credentials() {
770+
let config = from_env().no_credentials().load().await;
771+
assert!(config.credentials_cache().is_none());
772+
assert!(config.credentials_provider().is_none());
773+
}
722774
}
723775
}

aws/rust-runtime/aws-config/src/sts.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pub use assume_role::{AssumeRoleProvider, AssumeRoleProviderBuilder};
1212
mod assume_role;
1313

1414
use crate::connector::expect_connector;
15-
use aws_credential_types::cache::CredentialsCache;
1615
use aws_sdk_sts::config::Builder as StsConfigBuilder;
1716
use aws_smithy_types::retry::RetryConfig;
1817

@@ -22,8 +21,7 @@ impl crate::provider_config::ProviderConfig {
2221
.http_connector(expect_connector(self.connector(&Default::default())))
2322
.retry_config(RetryConfig::standard())
2423
.region(self.region())
25-
.time_source(self.time_source())
26-
.credentials_cache(CredentialsCache::no_caching());
24+
.time_source(self.time_source());
2725
builder.set_sleep_impl(self.sleep());
2826
builder
2927
}

aws/rust-runtime/aws-inlineable/src/glacier_interceptors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use aws_sigv4::http_request::SignableBody;
1111
use aws_smithy_http::body::SdkBody;
1212
use aws_smithy_http::byte_stream;
1313
use aws_smithy_runtime_api::box_error::BoxError;
14+
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
1415
use aws_smithy_runtime_api::client::interceptors::context::{
1516
BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut,
1617
};
1718
use aws_smithy_runtime_api::client::interceptors::Interceptor;
18-
use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, LoadedRequestBody};
19+
use aws_smithy_runtime_api::client::orchestrator::LoadedRequestBody;
1920
use aws_smithy_types::config_bag::ConfigBag;
2021
use bytes::Bytes;
2122
use http::header::{HeaderName, HeaderValue};

aws/rust-runtime/aws-inlineable/src/presigning_interceptors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ use aws_sigv4::http_request::SignableBody;
1515
use aws_smithy_async::time::{SharedTimeSource, StaticTimeSource};
1616
use aws_smithy_runtime::client::retries::strategy::NeverRetryStrategy;
1717
use aws_smithy_runtime_api::box_error::BoxError;
18+
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
1819
use aws_smithy_runtime_api::client::interceptors::context::{
1920
BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut,
2021
};
2122
use aws_smithy_runtime_api::client::interceptors::{
2223
disable_interceptor, Interceptor, InterceptorRegistrar, SharedInterceptor,
2324
};
24-
use aws_smithy_runtime_api::client::orchestrator::ConfigBagAccessors;
2525
use aws_smithy_runtime_api::client::retries::DynRetryStrategy;
2626
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
2727
use aws_smithy_types::config_bag::{ConfigBag, FrozenLayer, Layer};

aws/rust-runtime/aws-runtime/src/auth/sigv4.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ use aws_smithy_runtime_api::box_error::BoxError;
1212
use aws_smithy_runtime_api::client::auth::{
1313
AuthSchemeEndpointConfig, AuthSchemeId, HttpAuthScheme, HttpRequestSigner,
1414
};
15-
use aws_smithy_runtime_api::client::identity::{Identity, IdentityResolver, IdentityResolvers};
16-
use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, HttpRequest};
15+
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
16+
use aws_smithy_runtime_api::client::identity::{
17+
Identity, IdentityResolvers, SharedIdentityResolver,
18+
};
19+
use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
1720
use aws_smithy_types::config_bag::{ConfigBag, Storable, StoreReplace};
1821
use aws_smithy_types::Document;
1922
use aws_types::region::{Region, SigningRegion};
@@ -94,10 +97,10 @@ impl HttpAuthScheme for SigV4HttpAuthScheme {
9497
SCHEME_ID
9598
}
9699

97-
fn identity_resolver<'a>(
100+
fn identity_resolver(
98101
&self,
99-
identity_resolvers: &'a IdentityResolvers,
100-
) -> Option<&'a dyn IdentityResolver> {
102+
identity_resolvers: &IdentityResolvers,
103+
) -> Option<SharedIdentityResolver> {
101104
identity_resolvers.identity_resolver(self.scheme_id())
102105
}
103106

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCustomizableOperationDecorator.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ class CustomizableOperationTestHelpers(runtimeConfig: RuntimeConfig) :
2222
.resolve("user_agent::AwsUserAgent"),
2323
"BeforeTransmitInterceptorContextMut" to RuntimeType.beforeTransmitInterceptorContextMut(runtimeConfig),
2424
"ConfigBag" to RuntimeType.configBag(runtimeConfig),
25-
"ConfigBagAccessors" to RuntimeType.smithyRuntimeApi(runtimeConfig)
26-
.resolve("client::orchestrator::ConfigBagAccessors"),
25+
"ConfigBagAccessors" to RuntimeType.configBagAccessors(runtimeConfig),
2726
"http" to CargoDependency.Http.toType(),
2827
"InterceptorContext" to RuntimeType.interceptorContext(runtimeConfig),
2928
"SharedTimeSource" to CargoDependency.smithyAsync(runtimeConfig).withFeature("test-util").toType()

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import software.amazon.smithy.model.traits.HttpQueryTrait
1717
import software.amazon.smithy.model.traits.HttpTrait
1818
import software.amazon.smithy.model.transform.ModelTransformer
1919
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
20+
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustSettings
2021
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
2122
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
2223
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationSection
@@ -113,7 +114,7 @@ class AwsPresigningDecorator internal constructor(
113114
/**
114115
* Adds presignable trait to known presignable operations and creates synthetic presignable shapes for codegen
115116
*/
116-
override fun transformModel(service: ServiceShape, model: Model): Model {
117+
override fun transformModel(service: ServiceShape, model: Model, settings: ClientRustSettings): Model {
117118
val modelWithSynthetics = addSyntheticOperations(model)
118119
val presignableTransforms = mutableListOf<PresignModelTransform>()
119120
val intermediate = ModelTransformer.create().mapShapes(modelWithSynthetics) { shape ->
@@ -369,8 +370,7 @@ class AwsPresignedFluentBuilderMethod(
369370
}
370371
""",
371372
"AlternateSerializer" to alternateSerializer(operationShape),
372-
"ConfigBagAccessors" to RuntimeType.smithyRuntimeApi(codegenContext.runtimeConfig)
373-
.resolve("client::orchestrator::ConfigBagAccessors"),
373+
"ConfigBagAccessors" to RuntimeType.configBagAccessors(runtimeConfig),
374374
"FrozenLayer" to smithyTypes.resolve("config_bag::FrozenLayer"),
375375
"Layer" to smithyTypes.resolve("config_bag::Layer"),
376376
"RuntimePlugin" to RuntimeType.runtimePlugin(codegenContext.runtimeConfig),

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialCaches.kt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
7979
rustTemplate(
8080
"""
8181
/// Returns the credentials cache.
82-
pub fn credentials_cache(&self) -> #{SharedCredentialsCache} {
83-
self.inner.load::<#{SharedCredentialsCache}>().expect("credentials cache should be set").clone()
82+
pub fn credentials_cache(&self) -> #{Option}<#{SharedCredentialsCache}> {
83+
self.inner.load::<#{SharedCredentialsCache}>().cloned()
8484
}
8585
""",
8686
*codegenScope,
@@ -145,9 +145,8 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
145145
if (runtimeMode.defaultToOrchestrator) {
146146
rustTemplate(
147147
"""
148-
layer.store_put(
149-
layer.load::<#{CredentialsCache}>()
150-
.cloned()
148+
if let Some(credentials_provider) = layer.load::<#{SharedCredentialsProvider}>().cloned() {
149+
let cache_config = layer.load::<#{CredentialsCache}>().cloned()
151150
.unwrap_or_else({
152151
let sleep = layer.load::<#{SharedAsyncSleep}>().cloned();
153152
|| match sleep {
@@ -158,11 +157,10 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
158157
}
159158
None => #{CredentialsCache}::lazy(),
160159
}
161-
})
162-
.create_cache(layer.load::<#{SharedCredentialsProvider}>().cloned().unwrap_or_else(|| {
163-
#{SharedCredentialsProvider}::new(#{DefaultProvider})
164-
}))
165-
);
160+
});
161+
let shared_credentials_cache = cache_config.create_cache(credentials_provider);
162+
layer.store_put(shared_credentials_cache);
163+
}
166164
""",
167165
*codegenScope,
168166
)

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.config.Confi
1515
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
1616
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
1717
import software.amazon.smithy.rust.codegen.core.rustlang.rust
18+
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
1819
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
1920
import software.amazon.smithy.rust.codegen.core.rustlang.writable
2021
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
@@ -138,24 +139,24 @@ class CredentialsIdentityResolverRegistration(
138139
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
139140
when (section) {
140141
is ServiceRuntimePluginSection.AdditionalConfig -> {
141-
rustTemplate(
142-
"""
143-
cfg.set_identity_resolvers(
144-
#{IdentityResolvers}::builder()
145-
.identity_resolver(
146-
#{SIGV4_SCHEME_ID},
147-
#{CredentialsIdentityResolver}::new(self.handle.conf.credentials_cache())
148-
)
149-
.build()
150-
);
151-
""",
152-
"SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
153-
.resolve("auth::sigv4::SCHEME_ID"),
154-
"CredentialsIdentityResolver" to AwsRuntimeType.awsRuntime(runtimeConfig)
155-
.resolve("identity::credentials::CredentialsIdentityResolver"),
156-
"IdentityResolvers" to RuntimeType.smithyRuntimeApi(runtimeConfig)
157-
.resolve("client::identity::IdentityResolvers"),
158-
)
142+
rustBlockTemplate("if let Some(credentials_cache) = self.handle.conf.credentials_cache()") {
143+
section.registerIdentityResolver(this, runtimeConfig) {
144+
rustTemplate(
145+
"""
146+
#{SIGV4_SCHEME_ID},
147+
#{SharedIdentityResolver}::new(
148+
#{CredentialsIdentityResolver}::new(credentials_cache),
149+
),
150+
""",
151+
"SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
152+
.resolve("auth::sigv4::SCHEME_ID"),
153+
"CredentialsIdentityResolver" to AwsRuntimeType.awsRuntime(runtimeConfig)
154+
.resolve("identity::credentials::CredentialsIdentityResolver"),
155+
"SharedIdentityResolver" to RuntimeType.smithyRuntimeApi(runtimeConfig)
156+
.resolve("client::identity::SharedIdentityResolver"),
157+
)
158+
}
159+
}
159160
}
160161
else -> {}
161162
}

0 commit comments

Comments
 (0)