21 releases (breaking)

Uses new Rust 2021

new 0.47.0 Aug 9, 2022
0.46.0 Jul 22, 2022
0.15.0 Jun 29, 2022
0.9.0 Mar 17, 2022
0.0.26-alpha Nov 24, 2021
Download history 22397/week @ 2022-04-22 25967/week @ 2022-04-29 27154/week @ 2022-05-06 28810/week @ 2022-05-13 23116/week @ 2022-05-20 23794/week @ 2022-05-27 30930/week @ 2022-06-03 31364/week @ 2022-06-10 33956/week @ 2022-06-17 30462/week @ 2022-06-24 32281/week @ 2022-07-01 34389/week @ 2022-07-08 35462/week @ 2022-07-15 34954/week @ 2022-07-22 37236/week @ 2022-07-29 32587/week @ 2022-08-05

147,872 downloads per month
Used in 381 crates (310 directly)

Apache-2.0

370KB
7K SLoC

aws-sig-auth

This crate implements a standalone request signer for AWS services. For examples, see docs.rs.

This crate is part of the AWS SDK for Rust and the smithy-rs code generator. In most cases, it should not be used directly.


lib.rs:

AWS Signature Authentication Package

This crate may be used to generate presigned URLs for unmodeled behavior such as rds-iam-token or to sign requests to APIGateway-based services with IAM authorization.

Examples

Generate RDS IAM Token

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,
    timestamp: SystemTime,
) -> 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: timestamp,
        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)
}

// You will need to get `credentials` from a credentials provider ahead of time
# let credentials = Credentials::new("AKIDEXAMPLE", "secret", None, None, "example");
let token = generate_rds_iam_token(
    "prod-instance.us-east-1.rds.amazonaws.com",
    Region::from_static("us-east-1"),
    3306,
    "dbuser",
    &credentials,
    // this value is hard coded to create deterministic signature for tests. Generally,
    // `SystemTime::now()` should be used
    UNIX_EPOCH + Duration::from_secs(1635257380)
).expect("failed to generate token");
# // validate against token generated by the aws CLI
# assert_eq!(token, "prod-instance.us-east-1.rds.amazonaws.com:3306/?Action=connect&DBUser=dbuser&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20211026%2Fus-east-1%2Frds-db%2Faws4_request&X-Amz-Date=20211026T140940Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=9632f5f4fcd2087a3c523f55f72d2fe97fad03b71a0a23b8c1edfb104e8072d1");

Sign a request for APIGateway execute-api

use aws_sig_auth::signer::{OperationSigningConfig, RequestConfig, SigV4Signer};
use aws_smithy_http::body::SdkBody;
use aws_types::credentials::ProvideCredentials;
use aws_types::region::{Region, SigningRegion};
use aws_types::SigningService;
use std::error::Error;
use std::time::SystemTime;
async fn sign_request(
    mut request: &mut http::Request<SdkBody>,
    region: Region,
    credentials_provider: &impl ProvideCredentials,
) -> Result<(), Box<dyn Error + Send + Sync>> {
    let now = SystemTime::now();
    let signer = SigV4Signer::new();
    let request_config = RequestConfig {
        request_ts: now,
        region: &SigningRegion::from(region),
        service: &SigningService::from_static("execute-api"),
        payload_override: None,
    };
    signer.sign(
        &OperationSigningConfig::default_config(),
        &request_config,
        &credentials_provider.provide_credentials().await?,
        &mut request,
    )?;
    Ok((()))
}

Dependencies

~15MB
~340K SLoC