Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper signing of requests to aws resources through http

I have a lambda function that is writing some data to an Elasticsearch domain I have also set up through AWS. Currently the access policy on my domain is just to allow my own IP address to work with the domain

{"Version": "2012-10-17", "Statement": [{
 "Effect": "Allow", "Principal": {"AWS": "*"},
 "Action": "es:*",
 "Resource": "arn:aws:es:us-east-1:$ACCOUNT:domain/DOMAIN/*",
 "Condition": { "IpAddress": { "aws:SourceIp": $MYIP } }
}]}

I found the aws4 library for signing http requests. I'm using it as such:

axios(aws4.sign({
    host: process.env.ES_ENDPOINT,
    method: "post",
    url: `https://${process.env.ES_ENDPOINT}/foobot/foobot`,
    data,
}))

This was actually working before without the aws4.sign piece as I had the ES domain completely open, but now I've applied the IP address policy above.

Now, I continually get an error like this in response:

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

Is there something else I need to do to properly sign the request?

like image 375
Explosion Pills Avatar asked Oct 27 '25 10:10

Explosion Pills


1 Answers

This actually has to do with the two libraries, axios and aws4. aws4 will sign based off of a normal NodeJS http request, and in a POST request with a body the body is required to properly sign the request.

This is fixed pretty simply by also passing in body and path

axios(aws4.sign({
    host: process.env.ES_ENDPOINT,
    method: "POST",
    url: `https://${process.env.ES_ENDPOINT}/foobot/foobot`,
    data,
    body: JSON.stringify(data),
    path: "/foobot/foobot",
}))
like image 182
Explosion Pills Avatar answered Oct 29 '25 23:10

Explosion Pills



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!