scratchstack_aws_signature/migration.rs
1//! # Migrating from 0.10 to 0.11
2//!
3//! Version 0.11 brings significant changes to the scratchstack-aws-signature crate. These changes
4//! are intended to make the crate more ergonomic (easier for consumers to use) and more efficient
5//! (less copying of data).
6//!
7//! Unfortunately, this means that the 0.11 version is not backwards compatible with the 0.10
8//! version.
9//!
10//! ## Changes
11//!
12//! ### Elimination of `Request` type.
13//! The main change is the elimination of the `scratchstack_aws_signature::Request` type. Instead,
14//! `http::Request` is used directly and there is no longer a need to copy data from one `Request`
15//! type to the other.
16//!
17//! With this, there is also no need to use the
18//! [`GetSigningKeyRequest`][crate::GetSigningKeyRequest] type in the
19//! validation code. (This type is used to pass get signing key requests.)
20//!
21//! This sample code from 0.10:
22//! ```ignore
23//! let http_req = http::Request::get("https://example.com").body(())?;
24//! let sig_req = scratchstack_aws_signature::Request::from_http_request_parts(
25//! &http_req.into_parts().0, None);
26//! let gsk_req = sig_req.to_get_signing_request(SigningKeyKind::KSigning, REGION, SERVICE)?;
27//! let (principal, signing_key) = get_signing_key_service.call(gsk_req).await?;
28//! sig4_verify(&sig_req, &signing_key, None, REGION, SERVICE)?;
29//! ```
30//!
31//! Would be written in 0.11:
32//! ```ignore
33//! let http_req = http::Request::get("https://example.com").body(())?;
34//! let (parts, body, auth) = sigv4_validate_request(
35//! req, ®ION, &SERVICE, &mut get_signing_key_service, Utc::now(),
36//! NO_ADDITIONAL_SIGNED_HEADERS, SignatureOptions::default())?;
37//! ```
38//!
39//! ### Compile-time key type checking
40//! In 0.10, keys of different types were all stored as the `SigningKey` type with a discriminator,
41//! `SigningKeyKind`, indicating the underlying key type at runtime. This made it impossible to
42//! use compile-time checks to ensure that the correct key type was used.
43//!
44//! In 0.11, the `SigningKey` type has been replaced with a distinct key type for each key type:
45//! * [`KSecretKey`][crate::KSecretKey]: The raw secret key prefixed with `"AWS4"`.
46//! * [`KDateKey`](crate::KDateKey): Key derived `KSecretKey` and the current UTC date.
47//! * [`KRegionKey`](crate::KRegionKey): Key derived from `KDateKey` and the region.
48//! * [`KServiceKey`](crate::KServiceKey): Key derived from `KRegionKey` and the service.
49//! * [`KSigningKey`](crate::KSigningKey): Key derived from `KServiceKey` and the string
50//! "aws4_request".
51//!
52//! These types have fixed sizes. [`KSecretKey`][crate::KSecretKey] has a const parameter that
53//! specifies the maximum secret key size (including the `"AWS4"` prefix), which defaults to 44
54//! (the size of AWS-issued secret keys).
55//!
56//! ### Signing key functions changed
57//! Previously, `get_signing_key_fn()` was used to convert a function into a
58//! [Tower `Service`][tower::Service] that could be used to get signing keys. This is now called
59//! [`service_for_signing_key_fn()`][crate::service_for_signing_key_fn].
60//!
61//! In addition, the signature of the function passed in has changed. Previously, parameters to
62//! the function were broken out separately:
63//! ```ignore
64//! async fn get_signing_key(
65//! kind: SigningKeyKind,
66//! access_key: String,
67//! session_token: Option<String>,
68//! request_date: DateTime<Utc>,
69//! region: String,
70//! service: String)
71//! -> Result<(PrincipalActor, SigningKey), SignatureError>
72//! ```
73//!
74//! These parameters are now encapsulated in the (non-exhaustive)
75//! [`GetSigningKeyRequest`][crate::GetSigningKeyRequest] type, and the tuple of
76//! `(PrincipalActor, SigningKey)` is now encapsulated in the
77//! [`GetSigningKeyResponse`][crate::GetSigningKeyResponse] type. The function signature is now:
78//! ```
79//! # use scratchstack_aws_signature::{GetSigningKeyRequest, GetSigningKeyResponse};
80//! use tower::BoxError;
81//!
82//! async fn get_signing_key(req: GetSigningKeyRequest) -> Result<GetSigningKeyResponse, BoxError>
83//! # {
84//! # Ok(GetSigningKeyResponse::default())
85//! # }
86//! ```
87//!
88//! Both of these types have builder APIs to construct them.
89//!
90//! ### Principal types updated
91//! This crate uses the [`Principal`][scratchstack_aws_principal::Principal] type from
92//! scratchstack_aws_principal v0.4. Previously, the `PrincipalActor` from v0.3 of that crate was
93//! used. In v0.4, only actor principals are supported; v0.3 attempted to support both actor and
94//! policy principals, but this was riddled with implementation errors.
95//!
96//! ### Type-dependencies from other crates exposed
97//! This crate now uses types two other crates in its APIs: [`scratchstack_aws_principal`] and
98//! [`scratchstack_errors`]. To reduce the possibility of accidentally using a different version
99//! of these crates, they are re-exported here under `principal` and `errors` modules, respectively.
100
101use std::str::FromStr;