Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[request]: RDS generate-db-auth-token for IAM authentication #147

Closed
2 tasks
allan2 opened this issue Jul 9, 2021 · 5 comments
Closed
2 tasks

[request]: RDS generate-db-auth-token for IAM authentication #147

allan2 opened this issue Jul 9, 2021 · 5 comments
Labels
feature-request A feature should be added or improved.

Comments

@allan2
Copy link

allan2 commented Jul 9, 2021

This feature request is for generate-db-auth-token in RDS to enable IAM authentication.

Granting rds_iam to a user to enable IAM authentication disables password authentication so this would be helpful to stay with IAM auth.

The typical usage is setting the environment variable

export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region us-west-2 --username iamuser)"

which is then used to authenticate using your chosen method, e.g. psql or JetBrains AWS Toolkit.

[1] generate-db-auth-token on AWS Docs
[2] How do I connect to my RDS PostgreSQL instance using IAM authentication?


Maintainers notes

  • Include this example in the RDS docs
  • add a customization to add this to the RDS client
@rcoh rcoh added the feature-request A feature should be added or improved. label Jul 14, 2021
@allan2
Copy link
Author

allan2 commented Oct 26, 2021

There doesn't seem to be a way to maintain a connection to RDS through IAM without this. The token only lives for 15 minutes.

@rcoh
Copy link
Contributor

rcoh commented Oct 26, 2021

Hello, sorry for the long delay! This is actually an unmodeled operation (which is why we aren't generating it). Now that we support presigned urls (#157), you can use aws-sig-auth directly to generate the presigned URL

use aws_smithy_http::body::SdkBody;
use aws_types::region::{Region, SigningRegion};
use aws_types::{Credentials, SigningService};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use aws_sig_auth::signer::{self, SigningError, OperationSigningConfig, HttpSignatureType, RequestConfig};
fn generate_rds_iam_token(
    db_hostname: &str,
    region: Region,
    port: u16,
    db_username: &str,
    credentials: &Credentials,
) -> Result<String, SigningError> {
    let signer = signer::SigV4Signer::new();
    let mut operation_config = OperationSigningConfig::default_config();
    operation_config.signature_type = HttpSignatureType::HttpRequestQueryParams;
    operation_config.expires_in = Some(Duration::from_secs(15 * 60));
    let request_config = RequestConfig {
        request_ts: SystemTime::now(),
        region: &SigningRegion::from(region),
        service: &SigningService::from_static("rds-db"),
        payload_override: None,
    };
    let mut request = http::Request::builder()
        .uri(format!(
            "http://{db_hostname}:{port}/?Action=connect&DBUser={db_user}",
            db_hostname = db_hostname,
            port = port,
            db_user = db_username
        ))
        .body(SdkBody::empty())
        .expect("valid request");
    let _signature = signer.sign(
        &operation_config,
        &request_config,
        &credentials,
        &mut request,
    )?;
    let mut uri = request.uri().to_string();
    assert!(uri.starts_with("http://"));
    let uri = uri.split_off("http://".len());
    Ok(uri)
}

@allan2
Copy link
Author

allan2 commented Oct 28, 2021

This is amazing! I have RDS IAM auth working now.

Shall I make a PR for an example with rust-postgres?

//

I did get this error when trying to use the ? operator,
My function wrapping the generate_rds_iam_token() call returns Result<(), Box<dyn Error>>.

error[E0277]: the size for values of type `dyn std::error::Error + Send + Sync` cannot be known at compilation time
   --> src\pg.rs:33:80
    |
33  |     let token = aws_auth::generate_rds_iam_token(host, region, port, user, &creds)?;
    |                                                                                   ^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn std::error::Error + Send + Sync`
    = note: required because of the requirements on the impl of `std::error::Error` for `Box<dyn std::error::Error + Send + Sync>`
    = note: required because of the requirements on the impl of `From<Box<dyn std::error::Error + Send + Sync>>` for `Box<dyn std::error::Error>`
    = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, Box<dyn std::error::Error + Send + Sync>>>` for `Result<(), Box<dyn std::error::Error>>`
note: required by `from_residual`
   --> C:\Users\Al\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\ops\try_trait.rs:339:5
    |
339 |     fn from_residual(residual: R) -> Self;

To get around this, I used

let token = generate_rds_iam_token(...).map_err(|e| e as Box<dyn Error>)?;`

@rcoh
Copy link
Contributor

rcoh commented Oct 28, 2021

that would be awesome! the final home of it would be here: https://github.com/awslabs/smithy-rs/tree/main/aws/sdk/examples/rds/src/bin

@rcoh rcoh closed this as completed Oct 28, 2021
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved.
Projects
None yet
Development

No branches or pull requests

2 participants