question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`SignatureV4` is calculating a different signature to AWS, and I don't understand why

See original GitHub issue

I am following this guide for signing HTTP requests using @aws-sdk/signature-v4@3.39.0 to an Amazon OpenSearch Service.

When I copy the exact sample code and export the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY variables of my authorised user, the PUT index/type/id request to add a document is successful:

201 Created
Response body: {"_index":"products","_type":"_doc","_id":"2","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}

However, when I change the request to instead hit the GET index/_search endpoint, I get:

403 Forbidden
Response body: {"message":"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."}

The user is fully authorised against the index:

    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::**:user/aws-elasticbeanstalk-ec2-user"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-southeast-2:**:domain/mydomain/*"
    },

I was wondering how I can rectify my signature, as I have followed Create a canonical request for Signature Version 4 and can’t see why the SignatureV4 builder would produce any errors for the GET request vs the PUT request.

Here is my modified code from the guide:

const { HttpRequest } = require('@aws-sdk/protocol-http')
const { defaultProvider } = require('@aws-sdk/credential-provider-node')
const { SignatureV4 } = require('@aws-sdk/signature-v4')
const { NodeHttpHandler } = require('@aws-sdk/node-http-handler')
const { Sha256 } = require('@aws-crypto/sha256-browser')

const region = ''
const domain = ''
const index = 'products'
const type = '_search'
const createBody = (query) => ({
  query: {
    multi_match: {
      query,
      type: 'phrase',
      fields: [
        'tags',
        'name',
        'category',
        'maker'
      ]
    }
  },
  highlight: {
    pre_tags: [''],
    post_tags: [''],
    fields: {
      tags: {},
      name: {},
      category: {},
      maker: {}
    }
  }
})

searchIndex('sh').then(() => process.exit())

async function searchIndex (query) {
  const request = new HttpRequest({
    body: JSON.stringify(createBody(query)),
    headers: {
      'Content-Type': 'application/json',
      host: domain
    },
    hostname: domain,
    method: 'GET',
    path: index + '/' + type
  })

  const signer = new SignatureV4({
    credentials: defaultProvider(),
    region: region,
    service: 'es',
    sha256: Sha256
  })

  const signedRequest = await signer.sign(request)

  const client = new NodeHttpHandler()
  const { response } = await client.handle(signedRequest)
  console.log(response.statusCode + ' ' + response.body.statusMessage)

  let responseBody = ''
  return new Promise((resolve) => {
    response.body.on('data', (chunk) => {
      responseBody += chunk
    })
    response.body.on('end', () => {
      console.log('Response body: ' + responseBody)
      resolve(responseBody)
    })
  }, (error) => {
    console.log('Error: ' + error)
  })
}

SDK version number

@aws-crypto/sha256-browser@^2.0.0 @aws-sdk/credential-provider-node@^3.39.0 @aws-sdk/node-http-handler@^3.38.0 @aws-sdk/protocol-http@^3.38.0 @aws-sdk/signature-v4@^3.39.0

Is the issue in the browser/Node.js/ReactNative?

Node.js

Details of the browser/Node.js/ReactNative version

node -v: v14.18.1

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:4
  • Comments:5

github_iconTop GitHub Comments

4reactions
kylelaker-ccpocommented, Nov 9, 2021

I am experiencing the same behavior running in AWS Lambda on Node.js 14 with all @aws-sdk/* dependencies at v3.40.0. A PUT request to add the items works successfully; however, a GET (specifically, a _search) with a body returns the “different signature” error message. Credentials are being retrieved using the fromEnv() function in @aws-sdk/credential-providers@3.40.0 for both GET and PUT.

Performing a GET request without a body, such as {index}/_doc/{id} does worksuccessfully. Having no real knowledge of the inner workings of the SignatureV4 class, this seems to be a bug in the way that GET requests that contain a body are handled.

To transform the GET into a working test, the body was omitted and the path was changed to a specific document’s ID.

3reactions
michelleparentcommented, Nov 11, 2021

Ran into a similar 403 error but with POST request. For us, we had URL query parameters that weren’t being passed into the signed request correctly, they were only being appended to the path. For some reason, the HTTP request signing guide for OpenSearch doesn’t tell you to set the query parameter in new HttpRequest() which surprisingly solved our issue!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Authenticating Requests (AWS Signature Version 4)
Upon receiving the request, Amazon S3 calculates the signature by using the ... how to derive a signing key in different programming languages,...
Read more >
Examples: Signature Calculations in AWS Signature Version 4
This section provides examples of signature calculations written in Java and C#. The code samples send the following requests and use the HTTP...
Read more >
Troubleshoot SigV4 signature mismatch errors with IAM ...
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method.".
Read more >
Signature Calculations for the Authorization Header
For information about other Regions, see Regions and Endpoints in the AWS General Reference. You can use either path-style or virtual hosted– ...
Read more >
Calculating Signatures - AWS Documentation
The best way to learn how to sign requests is to see the. ... learn how to sign requests is to read the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found