Unverified Commit de4be56e authored by ysaito1001's avatar ysaito1001 Committed by GitHub
Browse files

Add support for environment token provider for services whose SigV4 signing...

Add support for environment token provider for services whose SigV4 signing names are `bedrock` (#4241)

## Motivation and Context
Adds support for environment token provider for AWS services whose SigV4
service signing name matches `bedrock`. Setting this environment
variable, `AWS_BEARER_TOKEN_BEDROCK`, allows SDKs to prefer the
`httpBearerAuth` auth scheme and to retrieve a `Token` value from the
said environment.

## Description
Customers would use the environment variable in question like so:
```
    // export AWS_BEARER_TOKEN_BEDROCK=my-token

    let sdk_config = aws_config::defaults(BehaviorVersion::latest()).load().await;

    let bedrock_client = aws_sdk_bedrock::Client::new(&sdk_config);
    // call an operation on `bedrock_client`...
```
Under the hood, this is equivalent roughly to
```
    let sdk_config = aws_config::defaults(BehaviorVersion::latest()).load().await;
    let bedrock_config = aws_sdk_bedrock::config::Builder::from(sdk_config)
        .auth_scheme_preference([HTTP_BEARER_AUTH_SCHEME_ID])
        .token_provider(Token::new("my-token", None))
        .build();

    let bedrock_client = aws_sdk_bedrock::Client::from_conf(bedrock_config);
    // call an operation on `bedrock_client`...
```
This behind-the-scenes convenience is implemented in `impl
From<&SdkConfig> for Builder`, similar to how a service-specific
environment is implemented for the [endpoint
URL](https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html#ss-endpoints-envar).

However, `impl From<&SdkConfig> for Builder` implies that customers need
to create a service client from `SdkConfig` (typically through
[ConfigLoader::load](https://docs.rs/aws-config/latest/aws_config/struct.ConfigLoader.html#method.load))
in order to take advantage of the environment variable. If customers
create the service client directly from the service config builder, the
environment variable will not be applied, i.e.
```
    // export AWS_BEARER_TOKEN_BEDROCK=my-token

    let bedrock_config = aws_sdk_bedrock::Config::builder()
        // other configurations
        .build();

    let bedrock_client = aws_sdk_bedrock::Client::from_conf(bedrock_config);
    // `bedrock_client` neither prefers HTTP_BEARER_AUTH_SCHEME_ID nor sets a Token with my-token.
```

## Testing
- Added integration tests for `bedrockruntime` (whose model is already
checked in to `aws/sdk/aws-models`)

## Checklist
- [x] For changes to the AWS SDK, generated SDK code, or SDK runtime
crates, I have created a changelog entry Markdown file in the
`.changelog` directory, specifying "aws-sdk-rust" in the `applies_to`
key.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 0642b3b8
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
---
applies_to:
- aws-sdk-rust
authors:
- ysaito1001
references:
- smithy-rs#4241
breaking: false
new_feature: true
bug_fix: false
---
Add support for environment token provider for AWS services whose SigV4 service signing name matches `bedrock`. Setting this environment variable, `AWS_BEARER_TOKEN_BEDROCK`, allows SDKs to prefer the `httpBearerAuth` auth scheme and to retrieve a Token value from the said environment. Customers would use the environment variable as follows:
```
// export AWS_BEARER_TOKEN_BEDROCK=my-token
let sdk_config = aws_config::defaults(BehaviorVersion::latest()).load().await;
let bedrock_client = aws_sdk_bedrock::Client::new(&sdk_config);
// call an operation on `bedrock_client`...
```
Under the hood, this is equivalent roughly to
```
let sdk_config = aws_config::defaults(BehaviorVersion::latest()).load().await;
let bedrock_config = aws_sdk_bedrock::config::Builder::from(sdk_config)
    .auth_scheme_preference([HTTP_BEARER_AUTH_SCHEME_ID])
    .token_provider(Token::new("my-token", None))
    .build();
let bedrock_client = aws_sdk_bedrock::Client::from_conf(bedrock_config);
// call an operation on `bedrock_client`...
```
However, note that if customers create the service client directly from the service config builder, the environment variable will not be applied:
```
// export AWS_BEARER_TOKEN_BEDROCK=my-token
let bedrock_config = aws_sdk_bedrock::Config::builder()
    // other configurations
    .build();
let bedrock_client = aws_sdk_bedrock::Client::from_conf(bedrock_config);
// `bedrock_client` neither prefers HTTP_BEARER_AUTH_SCHEME_ID nor sets a Token with my-token.
```
+21 −38
Original line number Diff line number Diff line
@@ -341,7 +341,7 @@ dependencies = [

[[package]]
name = "aws-smithy-runtime-api"
version = "1.8.6"
version = "1.8.7"
dependencies = [
 "aws-smithy-async",
 "aws-smithy-types",
@@ -527,9 +527,9 @@ dependencies = [

[[package]]
name = "cc"
version = "1.2.30"
version = "1.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
dependencies = [
 "shlex",
]
@@ -1181,7 +1181,7 @@ dependencies = [
 "httpdate",
 "itoa",
 "pin-project-lite",
 "socket2 0.5.10",
 "socket2",
 "tokio",
 "tower-service",
 "tracing",
@@ -1324,9 +1324,9 @@ dependencies = [

[[package]]
name = "io-uring"
version = "0.7.9"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
dependencies = [
 "bitflags",
 "cfg-if",
@@ -1749,9 +1749,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"

[[package]]
name = "rand"
version = "0.9.2"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
dependencies = [
 "rand_chacha",
 "rand_core 0.9.3",
@@ -1816,9 +1816,9 @@ dependencies = [

[[package]]
name = "redox_syscall"
version = "0.5.17"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
dependencies = [
 "bitflags",
]
@@ -1909,9 +1909,9 @@ dependencies = [

[[package]]
name = "rustc-demangle"
version = "0.1.26"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"

[[package]]
name = "rustc_version"
@@ -2107,9 +2107,9 @@ dependencies = [

[[package]]
name = "serde_json"
version = "1.0.141"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
 "itoa",
 "memchr",
@@ -2195,16 +2195,6 @@ dependencies = [
 "windows-sys 0.52.0",
]

[[package]]
name = "socket2"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
dependencies = [
 "libc",
 "windows-sys 0.59.0",
]

[[package]]
name = "spki"
version = "0.6.0"
@@ -2358,9 +2348,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"

[[package]]
name = "tokio"
version = "1.47.0"
version = "1.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
dependencies = [
 "backtrace",
 "bytes",
@@ -2371,9 +2361,9 @@ dependencies = [
 "pin-project-lite",
 "signal-hook-registry",
 "slab",
 "socket2 0.6.0",
 "socket2",
 "tokio-macros",
 "windows-sys 0.59.0",
 "windows-sys 0.52.0",
]

[[package]]
@@ -2727,12 +2717,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"

[[package]]
name = "windows-sys"
version = "0.52.0"
@@ -2757,7 +2741,7 @@ version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
 "windows-targets 0.53.3",
 "windows-targets 0.53.2",
]

[[package]]
@@ -2778,11 +2762,10 @@ dependencies = [

[[package]]
name = "windows-targets"
version = "0.53.3"
version = "0.53.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
dependencies = [
 "windows-link",
 "windows_aarch64_gnullvm 0.53.0",
 "windows_aarch64_msvc 0.53.0",
 "windows_i686_gnu 0.53.0",
+28 −19
Original line number Diff line number Diff line
@@ -894,31 +894,13 @@ mod loader {
                TriStateOption::ExplicitlyUnset => None,
            };

            let token_provider = match self.token_provider {
                Some(provider) => Some(provider),
                None => {
                    #[cfg(feature = "sso")]
                    {
                        let mut builder =
                            crate::default_provider::token::DefaultTokenChain::builder()
                                .configure(conf.clone());
                        builder.set_region(region.clone());
                        Some(SharedTokenProvider::new(builder.build().await))
                    }
                    #[cfg(not(feature = "sso"))]
                    {
                        None
                    }
                }
            };

            let profiles = conf.profile().await;
            let service_config = EnvServiceConfig {
                env: conf.env(),
                env_config_sections: profiles.cloned().unwrap_or_default(),
            };
            let mut builder = SdkConfig::builder()
                .region(region)
                .region(region.clone())
                .retry_config(retry_config)
                .timeout_config(timeout_config)
                .time_source(time_source)
@@ -950,6 +932,30 @@ mod loader {
                }
            };

            let token_provider = match self.token_provider {
                Some(provider) => {
                    builder.insert_origin("token_provider", Origin::shared_config());
                    Some(provider)
                }
                None => {
                    #[cfg(feature = "sso")]
                    {
                        let mut builder =
                            crate::default_provider::token::DefaultTokenChain::builder()
                                .configure(conf.clone());
                        builder.set_region(region);
                        Some(SharedTokenProvider::new(builder.build().await))
                    }
                    #[cfg(not(feature = "sso"))]
                    {
                        None
                    }
                    // Not setting `Origin` in this arm, and that's good for now as long as we know
                    // it's not programmatically set in the shared config.
                    // We can consider adding `Origin::Default` if needed.
                }
            };

            builder.set_endpoint_url(endpoint_url);
            builder.set_behavior_version(self.behavior_version);
            builder.set_http_client(self.http_client);
@@ -989,9 +995,12 @@ mod loader {

            let auth_scheme_preference =
                if let Some(auth_scheme_preference) = self.auth_scheme_preference {
                    builder.insert_origin("auth_scheme_preference", Origin::shared_config());
                    Some(auth_scheme_preference)
                } else {
                    auth_scheme_preference::auth_scheme_preference_provider(&conf).await
                    // Not setting `Origin` in this arm, and that's good for now as long as we know
                    // it's not programmatically set in the shared config.
                };

            builder.set_request_checksum_calculation(request_checksum_calculation);
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ pub enum AwsCredentialFeature {
    CredentialsHttp,
    /// An operation called using credentials resolved from the instance metadata service (IMDS)
    CredentialsImds,
    /// An operation called using a Bearer token resolved from service-specific environment variables
    BearerServiceEnvVars,
}

impl Storable for AwsCredentialFeature {
+4 −0
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@ use aws_smithy_types::config_bag::{Storable, StoreAppend};
pub enum AwsSdkFeature {
    /// Indicates that an operation was called by the S3 Transfer Manager
    S3Transfer,
    /// Calling an SSO-OIDC operation as part of the SSO login flow, when using the OAuth2.0 device code grant
    SsoLoginDevice,
    /// Calling an SSO-OIDC operation as part of the SSO login flow, when using the OAuth2.0 authorization code grant
    SsoLoginAuth,
}

impl Storable for AwsSdkFeature {
Loading