-
Notifications
You must be signed in to change notification settings - Fork 6
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
Add support for Serverless OpenSearch signing #90
Conversation
cc1207d
to
69829b4
Compare
@dblock I've tested it already, but if you have time a second testing before merging would be great. |
69829b4
to
eb957fe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this against my instance of OpenSearch Serverless and it works.
The isServerlessOpenSearch
rubs me the wrong way. The interceptor code didn't have "es" hard-coded anywhere before this (only in samples), so it theoretically works with any service. Picking "aoss" gets super specific now to a service. I feel like an additional level of indirection of shouldIncludeContentLength()
or a subclasses version of the interceptor with methods like copyHeaders
would be cleaner. Or maybe we need to switch/case 'es', 'aoss', or supply some kind of configuration options in the constructor?
// copy everything back | ||
request.setHeaders(mapToHeaderArray(signedRequest.headers())); | ||
} else { | ||
// copy everything back, don't override headers as no all of them were used for signing the request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no -> not
Why is this different for serverless? What headers should not be removed? Does the serverless version not work against managed service?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TL;DR: Content-Length
.
For Managed OpenSearch we include Content-Length
in the signature when it's different that 0
, so it ends up in signedRequest
so we just override all the headers and that's it. In the case of OpenSearch Sls we don't include it in the signature, if we override all headers we get rid of it and OpenSearch Sls doesn't like that. In order to preserve it then add back headers that are included in the request while keeping the original headers. It's not possible to do this for Managed OpenSearch because you'd then have it for content-length
equals 0
which I understand we shouldn't, so test fails, but I didn't test against an actual instance, maybe I should before we merge this.
return (HTTP.CONTENT_LEN.equalsIgnoreCase(header.getName()) | ||
&& "0".equals(header.getValue())) // Strip Content-Length: 0 | ||
&& (("0".equals(header.getValue())) || isServerlessOpenSearch)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something doesn't add up here for the managed service. Maybe we didn't need Content-Length
for it if we included x-amz-content-sha256: UNSIGNED-PAYLOAD
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow you, if you don't want to sign the payload, why using the interceptor? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signing headers?
With TLS signing more or less data (body vs. headers) shouldn't really matter, as long as something is signed the server can ensure that the payload came from who claimed to send it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CHANGELOG typo is a must ;)
Also add to README that both Amazon Managed OpenSearch and OpenSearch Serverless are supported and an example of usage (with "oass")?
CHANGELOG.md
Outdated
@@ -1,5 +1,7 @@ | |||
### 2.2.1 (Next) | |||
|
|||
* [#90](https://github.com/acm19/aws-request-signing-apache-interceptor/pull/90): Add support for Serverless OpeanSearch - [@acm19](https://github.com/acm19). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: OpeanSearch -> OpenSearch
We use the terminology of "OpenSearch Serverless" and "Managed OpenSearch".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks.
4a799f1
to
165d63c
Compare
I was expecting it ;) A bit of context, originally I thought of creating an interface, something like: interface HeaderFilter {
boolean shouldSkip(header);
Header[] computeFinalHeader(originalHeader, signedHeaders);
} Pass it over to the signer. That's generic enough. But it felt a bit over engineered, introducing some extra complexity. Then I thought, this is still beta and can change better make a simple as possible, add a special case for |
Adds support for signing Serverless OpenSearch requests as described: https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless-clients.html#serverless-signing. Requirements: * You must specify the service name as aoss. * You can't include Content-Length as a signed header, otherwise you'll get an invalid signature error. * Uses Aws4Signer while serverless uses Aws4UnsignedPayloadSigner. Removes rule to have `final` for all parameters as it create verbose code while not enforcing strong enough protection. All parameters are consider immutable as a good practice anyway. Resolves: #88
165d63c
to
b7e2798
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to hold this a bit. The server side is looking into aligning services Sigv4 and enabling content-length signing. We shouldn't need the special case.
return (HTTP.CONTENT_LEN.equalsIgnoreCase(header.getName()) | ||
&& "0".equals(header.getValue())) // Strip Content-Length: 0 | ||
&& (("0".equals(header.getValue())) || isServerlessOpenSearch)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signing headers?
With TLS signing more or less data (body vs. headers) shouldn't really matter, as long as something is signed the server can ensure that the payload came from who claimed to send it.
Closing in favor of #94. |
Adds support for signing Serverless OpenSearch requests as described: https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless-clients.html#serverless-signing.
Requirements:
Removes rule to have
final
for all parameters as it create verbose code while not enforcing strong enough protection. All parameters are consider immutable as a good practice anyway.Issue #, if available:
Description of changes:
Pull Request Checklist:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.