Description
Problem
When using the AWSSignatureV4 with DynamoDB, I ran into an issue where I was sometimes successfully retrieving an item from DynamoDB, but other times, I was receiving this error:
{"__type":"com.amazon.coral.service#InvalidSignatureException","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."}
Root Cause
According to the AWS documentation, the canonical headers need to be in order (similar to the query params):
Build the canonical headers list by sorting the (lowercase) headers by character code and then iterating through the header names.
There are a few places where the library already hardcodes the two headers host;x-amz-date
but in one spot, the library tries to read from a table of headers using pairs (see https://github.com/adobe-apiplatform/api-gateway-aws/blob/master/src/lua/api-gateway/aws/AwsV4Signature.lua#L61).
According to lua documentation, traversing using pairs
does not preserve order of the table, and this can lead to a case where the canonical headers are in the wrong order:
x-amz-date:20210316T224733Z
host:dynamodb.us-east-1.amazonaws.com
instead of the correct ordering of:
host:dynamodb.us-east-1.amazonaws.com
x-amz-date:20210316T224733Z
Proposed Solution
Since the library is already hardcoding the Signed-Headers, the easiest fix would be to simply change from a traversal of all headers and simply look for the 'host' and 'x-amz-date' headers explicitly in order. This is the solution that I am running locally which seems to work (although I am currently testing some more to verify the fix). There are definitely more elegant solutions which are less rigid, but wanted to share the simplest possible solution in case anyone else is blocked on this.