awslabs / aws-sdk-rust

AWS SDK for the Rust Programming Language
https://awslabs.github.io/aws-sdk-rust/
Apache License 2.0
2.97k stars 244 forks source link

AWS STS Documentation incorrect. Suggests Credentials meet provideCredentials crate #737

Open spf5000 opened 1 year ago

spf5000 commented 1 year ago

Describe the bug

Currently on the aws-sdk-sts documentation for the Credentials struct, it shows an impl for the aws_credentials_types ProvideCredentials trait. However it appears that the modeled version from STS does not implement this trait and is referencing the Credentials struct in aws_credentials_types.

Expected Behavior

I'd expect the STS modeled credentials to either implement ProvideCredentials or not document this as a trait implementation.

Current Behavior

The docs show the ProvideCredentials trait is implemented, but it can't compile

Reproduction Steps

async fn get_credentials_helper() -> Box<dyn ProvideCredentials {
    let shared_config = aws_config::load_from_env().await;
    let client = Client::new(&shared_config);
    let req = client
        .assume_role()
        .role_arn("myAwesomeRole")
        .role_session_name("Test");
    let creds: &StsCreds = req.send()
        .await.unwrap()
        .credentials()
        .unwrap();

    Box::new(creds)
}

Possible Solution

No response

Additional Information/Context

No response

Version

aws_credentials_types = v0.54.1
aws_sdk_sts = v0.24.0

Environment details (OS name and version, etc.)

Amazon Linux 2 aarch64

Logs

No response

Velfi commented 1 year ago

Hey @spf5000, thanks for submitting this issue. We'll add it to our backlog.

ysaito1001 commented 1 year ago

Hi, aws_sdk_sts::Credentials is a re-export of aws_credential_types::Credentials. Since the latter implements the ProvideCredentials trait, the former implements that trait automatically.

We've been able to compile the code in the reproduction steps with aws_credentials_types = 0.54.1 and aws_sdk_sts = 0.24.0.

Could you provide us with the compiler error message you are seeing so that we can better understand what could be the issue on your end?

github-actions[bot] commented 1 year ago

Greetings! It looks like this issue hasn’t been active in longer than a week. We encourage you to check if this is still an issue in the latest release. Because it has been longer than a week since the last update on this, and in the absence of more information, we will be closing this issue soon. If you find that this is still a problem, please feel free to provide a comment or add an upvote to prevent automatic closure, or if the issue is already closed, please feel free to open a new one.

rcoh commented 1 year ago

I'd add as a follow up—rather than using the STS credentials directly, I'd recommend using the credentials providers in aws-config as they implement best practices around caching, expiry, and secrets handling.

spf5000 commented 1 year ago

Sorry for the slow replies here. Below is a full example reproducing this issue:

src/main.rs:

use aws_credential_types::provider::ProvideCredentials;
use aws_sdk_sts::model::Credentials;
use aws_sdk_sts::Client;

fn main() {
    println!("Hello, world!");

    get_credentials_helper();
}

#[tokio::main]
async fn get_credentials_helper() -> Box<dyn ProvideCredentials> {
    let shared_config = aws_config::load_from_env().await;
    let client = Client::new(&shared_config);
    let req = client
        .assume_role()
        .role_arn("myAwesomeRole")
        .role_session_name("Test");
    let creds: &Credentials = req.send()
        .await.unwrap()
        .credentials()
        .unwrap();

    Box::new(creds.clone())
}

Cargo.toml:

[package]
name = "rust-sdk-bug"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
aws-credential-types = "0.54.1"
aws-sdk-sts = "0.24.0"
tokio = { version = "1", features = ["full"] }
aws-config = "0.54.1"

Compiler error:

   Compiling rust-sdk-bug v0.1.0 (/local/home/seaflinn/ws/rust-sdk-bug)
error[E0277]: the trait bound `aws_sdk_sts::model::Credentials: aws_credential_types::provider::ProvideCredentials` is not satisfied
  --> src/main.rs:24:5
   |
24 |     Box::new(creds.clone())
   |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `aws_credential_types::provider::ProvideCredentials` is not implemented for `aws_sdk_sts::model::Credentials`
   |
   = help: the following other types implement trait `aws_credential_types::provider::ProvideCredentials`:
             Arc<(dyn aws_credential_types::provider::ProvideCredentials + 'static)>
             AssumeRoleProvider
             CredentialProcessProvider
             CredentialsProviderChain
             DefaultCredentialsChain
             EcsCredentialsProvider
             EnvironmentVariableCredentialsProvider
             ImdsCredentialsProvider
           and 8 others
   = note: required for the cast from `aws_sdk_sts::model::Credentials` to the object type `dyn aws_credential_types::provider::ProvideCredentials`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `rust-sdk-bug` due to previous error
spf5000 commented 1 year ago

To be clear, I understand that I can leverage the Credentials struct in aws_credential_types, but I'm trying to implement a simple function that will return a Box<dyn ProvideCredentials> that way I can update this function with different credential providers if/as needed without callers of the function being tied to a specific ProvideCredentials implementation. I know I can copy over the data from the aws_sdk_sts::model::Credentials into a aws_credentias_types::Credentials struct, but the documentation (and re-export) suggests that I shouldn't have to.

spf5000 commented 1 year ago

I've also tried updating the aws_sdk_sts::model::Credentials to use aws_credential_types::Credentials and I've tried removing the export and the explicit type assignment in let creds: &Credentials = req.send() (ex: let creds: = req.send(), but I'm still seeing the same compiler error. I'm using the 1.67 rust compiler (rustc) as well if that helps.

jdisanti commented 1 year ago

You should be able to use AssumeRoleProvider instead of making manual STS calls, and that is preferable since it automatically refreshes expired credentials.

We haven't gotten to making the STS crate's credentials implement ProvideCredentials, and probably won't for a long time.

spf5000 commented 1 year ago

Makes sense. Any plans to clarify that in the documentation? Adding a link from the STS crate might help avoid future confusion from folks.

rcoh commented 1 year ago