Skip to content

How do I troubleshoot signature mismatch errors when making SigV4 signed requests with IAM authentication to API Gateway?

5 minute read
0

I receive a 403 error when I make a Signature Version 4 (SigV4) signed request to Amazon API Gateway with AWS Identity and Access Management (IAM) authentication.

Resolution

API Gateway endpoints using IAM authentication return 403 errors for several reasons. Use the following sections to identify and resolve the cause based on the error message you receive.

Confirm IAM authentication

Confirm that the API request using IAM authentication is signed with SigV4. To sign the request, follow the SigV4 signing process. If the API request isn't signed, then you receive the following error:

"Missing Authentication Token."

To resolve this error, add the missing signature and resend the request.

Verify IAM credentials

Verify that the access key and secret key are correct. To check your credentials, complete the following steps:

  1. Open the IAM console.
  2. In the navigation pane, choose Users.
  3. Select your user.
  4. Choose the Security credentials tab to review your access keys.

If the access key is incorrect, then you receive the following error:

"The security token included in the request is invalid."

To resolve this error, confirm that the IAM entity used to sign the request has execute-api:Invoke permissions. To add the permission, attach an IAM policy that includes the execute-api:Invoke action to the IAM entity. For policy examples, see IAM policy examples for API execution permissions.

If the execute-api:Invoke permission is missing, then the request fails with the following error:

"User: arn:aws:iam::xxxxxxxxxxxx:user/username is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:<region>:xxxxxxxxxxxx:<api-id>/stage/method/path because no identity-based policy allows the execute-api:Invoke action."

Resolve signature mismatch

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, confirm that you're using the most recent AWS CLI version.

If the secret access key is incorrect, then you receive the following error:

"The request signature we calculated does not match the signature you provided."

The secret access key and access key come in a pair. To validate the secret access key and access key and to isolate any potential issue during the signing process, test the request with the curl command.

For an IAM user, run the following curl command:

curl -v --aws-sigv4 'aws:amz:REGION:execute-api' --user 'AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY' API_Gateway_endpoint

Note: Replace REGION with your AWS Region. Replace AWS_ACCESS_KEY_ID with your IAM user access key ID. Replace AWS_SECRET_ACCESS_KEY with your IAM user secret access key. Replace API_Gateway_endpoint with your API Gateway endpoint URL.

For an IAM role, first obtain the temporary credentials by running the following assume-role AWS CLI command:

aws sts assume-role --role-arn ROLE_ARN --role-session-name SESSION_NAME

Note: Replace ROLE_ARN with the Amazon Resource Name (ARN) of the IAM role you want to assume. Replace SESSION_NAME with a name to identify the session.

Then use the temporary credentials returned in the previous action to run the following command:

curl -v --aws-sigv4 'aws:amz:REGION:execute-api' --user 'AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY' --header "x-amz-security-token: AWS_SESSION_TOKEN" API_Gateway_endpoint

Note: Replace REGION with your AWS Region. Replace AWS_ACCESS_KEY_ID with the access key ID from the assume-role output. Replace AWS_SECRET_ACCESS_KEY with the secret access key from the assume-role output. Replace AWS_SESSION_TOKEN with the session token from the assume-role output. Replace API_Gateway_endpoint with your API Gateway endpoint URL.

When API Gateway receives a signed request, it recalculates the signature. If the request parameter or payload differs from what generated the original signature, API Gateway gets a different result.

Compare the canonical request and string-to-sign obtained from your signing process with the value returned in the error message. Modify the signing process if there are any differences. For guidance on correcting the signing process, see Troubleshoot Signature Version 4 signing for AWS API requests.

Use the following example as a reference when you compare your canonical request against the value returned in the error message:

GET                                                      -------- HTTP method
/                                                        -------- Path. For API stage endpoint, it should be /{stage-name}/{resource-path}
                                                         -------- Query string key-value pair. Leave it blank if the request doesn't have any query string
content-type:application/json                            -------- Header key-value pair. One header per line
host:0123456789.execute-api.us-east-1.amazonaws.com      -------- Host and x-amz-date are required headers for all signed requests
x-amz-date:20220806T024003Z

content-type;host;x-amz-date                             -------- A list of signed headers
d167e99c53f15b0c105101d468ae35a3dc9187839ca081095e340f3649a04501        -------- Hash of the payload

The following is an example canonical error response:

<ErrorResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
  <Error>
    <Type>Sender</Type>
    <Code>SignatureDoesNotMatch</Code>
    <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 canonical string for this request should have been 'GET / Action=ListGroupsForUser&MaxItems=100&UserName=Test&Version=2010-05-08&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential
=AKIAIOSFODNN7EXAMPLE%2F20120223%2Fus-east-1%2Fiam%2Faws4_request&X-Amz-Date=20120223T063000Z&X-Amz-SignedHeaders=host
host:iam.amazonaws.com

host
<hashed-value>'

The String-to-Sign should have been
'AWS4-HMAC-SHA256
20120223T063000Z
20120223/us-east-1/iam/aws4_request
<hashed-value>'
</Message>
  </Error>
  <RequestId>4ced6e96-5de8-11e1-aa78-a56908bdf8eb</RequestId>
</ErrorResponse>

Note: For API Gateway headers, only the host and x-amz-date headers are required.

Fix the API request header

Confirm that the SigV4 authorization header has the correct format. The header must look like the following:

Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,
SignedHeaders=host;range;x-amz-date,
Signature=example-generated-signature

If the format is incorrect or parameters are missing, then update the authorization header in your signing code to include the following parameters:

  • Credential
  • SignedHeaders
  • Signature

Missing or incorrect parameters result in the following errors:

  • "Authorization header requires 'Credential' parameter."
  • "Authorization header requires 'Signature' parameter."
  • "Authorization header requires 'SignedHeaders' parameter."

Confirm that the SigV4 authorization request includes the request date. To add the date, include either the HTTP Date header or the x-amz-date header in your request. For more information, see Create a signed AWS API request. If the date header is missing, then you receive the following error:

"Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header."