Open trevjonez opened 1 year ago
Thanks for the question. Can you share more information about the specific SDK operation you're trying to create a presigned URL for? You're correct that we don't expose pre-signing capabilities and instead generate them for a few specific services. We may be able to add it for API Gateway depending on the use case.
My usecase is I believe very similar to the SO answer.
I want to sign a wss://API_ID.execute-api.REGION.amazonaws.com/STAGE?potentiallyWithQueryArgs=true
URL so that I can use AWS_IAM
as the auth type.
In my case it will be from the JVM most likely using OKHttp as the client implementation.
Current best looking workaround I think will be using the com.amazonaws.auth.AWS4Signer
from the android aws core sdk. But I do think having some sort of public API similar to what the android sdk provides would be appropriate for the kotlin SDK.
Hi and sorry for the delay in our response.
This is already somewhat possible with the Kotlin SDK, here is an example. You will need to @OptIn(InternalApi::class)
to call signer.sign(...)
. We will discuss as a team whether that API should be made public.
val signer = DefaultAwsSigner
val parsedUrl = Url.parse("wss://$API_ID.execute-api.$REGION.amazonaws.com/$STAGE")
val req = HttpRequest(method = HttpMethod.GET, url = parsedUrl)
val credentialsProvider = // your AWS credentials provider
val signingConfig = AwsSigningConfig {
algorithm = AwsSigningAlgorithm.SIGV4
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS
credentials = credentialsProvider.resolve()
region = "us-west-2"
service = "execute-api"
}
val signedUrl = signer.sign(req, signingConfig).output.url
// use signedUrl as needed...
What sort of things would you like to see changed to make it easier to sign URLs?
There are a few AWS services, such as Lambda function URLs, that aren't an AWS SDK call - they're an HTTPS endpoint that requires Sigv4 for AWS_IAM auth.
Struggling to see how to use the Kotlin AWS SDK for this - it isn't a general-purpose "HTTP Client". Its often preferable to use other Http clients to make those REST/HTTPS/whatever requests (there are many other non-SDK considerations - marshalling request/response payloads, etc) - but the sensitive logic on signing is baked into the SDK code, assumes that the request will be made by the SDK HTTP client. One could, of course, re-implement the signing logic, though that seems fragile and not an effective use of time when it already exists(ish).
Perhaps the signing logic could be decoupled from the HttpRequest such that is can be used elsewhere?
I think HttpRequest
is the correct abstraction for signing. It is formed by an HTTP method, URL endpoint, and optional request headers / body. You can create an HttpRequest
from a Lambda function URL and then sign it by doing something similar to my example code above.
After signing, if you don't want to use our SDK's HTTP client to complete the request, you can convert the request to your desired HTTP client's request type.
Do you have a different idea of what a decoupled signer would look like? What should it take as input?
A few thoughts now that we managed to make this work:
1) It isn't clear that signing, specifically DefaultAwsSigner
, is intended to be part of the SDK public API; its from an ancillary aws.smithy.kotlin:aws-signing-default
dependency, which makes if fuzzy as to whether its stable for consumption (or exposed for consumption by the SDK). It comes across as "hey, we found this random transitive dependency and made it work" rather than a supported part of the API.
2) DefaultAwsSigner
changes logging behaviour when used from SDK vs standalone; when used standalone there is no telemetryProvider registered, hence no logging provider, hence no debug/trace log output emitted;
3) There doesn't appear to be a way to have an unsigned payload - the code expects a pre-calculated hash, or hashes the payload;
4) The shouldSignHeader
predicate in AwsSigningConfig
is poorly documented: The default predicate is to not reject signing any headers (i. e., _ -> true).
- double negative, "reject" is odd. Perhaps something like "The default predicate signs all headers".
A documentation page on patterns for manually signing requests, e.g. lambda function URLs etc, would go a long way here.
@cloudshiftchris Thanks for the detailed feedback. We've added some backlog tasks to clean up the documentation and improve functionality when using the signer standalone.
Describe the issue
Currently trying to build an ApiGateway websocket driven app that is using IAM for auth and need a way to sign a
wss
URL in order to connect.Steps to Reproduce
This SO answer gives a good description of what I am wanting to achieve.
Current behavior
All of the signing details are buried in the Smithy SDK as an implementation detail of the things that provide pre-signing options. (IE: S3)
AWS Kotlin SDK version used
0.29.0-beta
Platform (JVM/JS/Native)
JVM
Operating System and version
N/A