feat(lambda-events): support X509 custom authorizer in IoT events#1114
feat(lambda-events): support X509 custom authorizer in IoT events#1114
Conversation
jlizen
left a comment
There was a problem hiding this comment.
See https://github.com/aws/aws-lambda-rust-runtime/pull/1114/changes#r2880358265 re: semver concerns
| #[serde(default)] | ||
| pub server_name: Option<String>, | ||
| #[serde(default)] | ||
| pub x509_certificate_pem: Option<String>, |
There was a problem hiding this comment.
Confirming that this looks good per: https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth-509cert.html
lambda-events/src/event/iot/mod.rs
Outdated
| pub client_id: Option<String>, | ||
| pub password: Base64Data, | ||
| #[serde(default)] | ||
| pub password: Option<Base64Data>, |
There was a problem hiding this comment.
This is indeed base64 data as described in the docs.
However, this is a breaking change to convert it from a String to Base64Data (which dereferences to Vec<u8>.
I sympathize with wanting to deserialize it directly as base64 with no extra hop, but I don't think we can justify this sort of breaking change when String would continue working fine, and is not really a "bug" insofar as String is a common base64 representation.
Is there a possibility of making it generic, with a default parameter instead?
Ie something like:
pub struct IoTCoreMqttContext<T = String> {
...
#[serde(default)]
pub password: Option<T>
}
and then passing that T with a default value up through other events that include this one? That would let you "opt it" to it by specifying it in your lambda event:
async fn function_handler(
client: &aws_sdk_ses::Client,
event: LambdaEvent<IoTCoreMqttContext<Base64Data>>,
) -> ..
It's a bit awkward, and we could certainly cut to just using the b64 data directly next major version, just that might be a moment.
Another option if you don't mind the extra hop is to expose a .as_base_64() helper that casts it after initial parsing.
There was a problem hiding this comment.
I'm not sure to understand, I just make it optional it was already a Base64Data type.
There was a problem hiding this comment.
Ah, my mistake, I read too quickly.
So the concern is, custom x509 authorizers don't send a password, which fails to parse against the existing schema?
Unfortunately this still is a breaking change for something that works for existing consumers, schema support for passwordless x509 support is more of an enhancement. So, the conclusion would be similar, except the generic would stay defaulting to Base64Data, while allowing the caller to declare in their handler IoTCoreCustomAuthorizerRequester<Option<Base64Data>>.
There are some alternatives like:
- add a type alias for the generic with Option for ergonomics (similar to above but might be nicer to name?)
- add a concrete IotCoreCustomAuthorizerRequestV2 that always uses option, no generic (and mark the old as deprecated and docs(hidden), but don't break it)
- (bad idea, probably?) have some default for this base64 deserialization that resolves to an empty vec
There was a problem hiding this comment.
You DO have impl Default available for Base64Data already, it looks like, so I wouldn't object to just annotating it with serde(default) without the option, if that is sufficient for your use case, to avoid failing deserializing and instead get the empty vec. It's not the best, fairly confusing. But that certainly is simpler than messing with generics.
There was a problem hiding this comment.
Looks good, but could we get a note on the semantics in the doc comment on field / struct? Specifically, this will result in it parsing a missing password as an empty vec, and then when reserialized it will show as password : "" (ie, empty string)
There was a problem hiding this comment.
I can take a look at merging this in tomorrow, though, which should get it in time to go out with our next release
There was a problem hiding this comment.
it's done and thanks for your reactivity ! 😃
c27b8d4 to
80aa551
Compare
Make IoTCoreMqttContext.password optional to support X509/mutual TLS custom authorizers where AWS IoT does not send username or password fields. Add x509_certificate_pem and principal_id fields to IoTCoreTlsContext for X509 certificate-based authentication. Add test fixture and test for the X509 authorizer payload.
80aa551 to
ea25ada
Compare
jlizen
left a comment
There was a problem hiding this comment.
Thanks for the contribution! This will go out next release.
✍️ Description of changes:
🔏 By submitting this pull request
cargo +nightly fmt.cargo clippy --fix.