aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.39k stars 2.11k forks source link

InvalidSignatureException on API 'get' call despite similar calls working #13505

Open abduaddis1 opened 2 weeks ago

abduaddis1 commented 2 weeks ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

REST API

Amplify Version

v6

Amplify Categories

api

Backend

Amplify CLI

Environment information

``` # Put output below this line System: OS: macOS 14.3 CPU: (8) arm64 Apple M2 Memory: 1.31 GB / 24.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 21.7.3 - /opt/homebrew/bin/node Yarn: 1.22.22 - /opt/homebrew/bin/yarn npm: 10.5.0 - /opt/homebrew/bin/npm Watchman: 2024.05.06.00 - /opt/homebrew/bin/watchman Browsers: Brave Browser: 125.1.66.118 Chrome: 126.0.6478.61 Edge: 126.0.2592.61 Safari: 17.3 npmPackages: @aws-amplify/react-native: ^1.0.18 => 1.0.28 @aws-amplify/ui-react-native: ^2.1.2 => 2.1.6 @babel/core: ^7.20.0 => 7.24.5 @react-native-async-storage/async-storage: 1.21.0 => 1.21.0 @react-native-community/netinfo: 11.1.0 => 11.1.0 @react-navigation/native: ^6.1.6 => 6.1.17 @react-navigation/native-stack: ^6.9.18 => 6.9.26 @react-navigation/stack: ^6.3.16 => 6.3.29 @types/react: ~18.2.45 => 18.2.79 HelloWorld: 0.0.1 aws-amplify: ^6.0.18 => 6.2.0 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/data: undefined () aws-amplify/data/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () expo: ~50.0.19 => 50.0.19 expo-av: ~13.10.5 => 13.10.6 expo-blur: ~12.9.2 => 12.9.2 expo-cached-image: ^50.0.6 => 50.0.6 expo-constants: ~15.4.6 => 15.4.6 expo-file-system: ~16.0.9 => 16.0.9 expo-image-picker: ~14.7.1 => 14.7.1 expo-linear-gradient: ^12.7.2 => 12.7.2 expo-linking: ~6.2.2 => 6.2.2 expo-router: ~3.4.10 => 3.4.10 expo-status-bar: ~1.11.1 => 1.11.1 expo-video-thumbnails: ~7.9.0 => 7.9.0 install: ^0.13.0 => 0.13.0 react: 18.2.0 => 18.2.0 react-dom: 18.2.0 => 18.2.0 react-native: 0.73.6 => 0.73.6 react-native-gesture-handler: ~2.14.0 => 2.14.1 react-native-get-random-values: ~1.9.0 => 1.9.0 react-native-image-picker: ^7.1.2 => 7.1.2 react-native-modal: ^13.0.1 => 13.0.1 react-native-reanimated: ~3.6.2 => 3.6.3 react-native-reanimated-carousel: ^3.5.1 => 3.5.1 react-native-responsive-screen: ^1.4.2 => 1.4.2 react-native-safe-area-context: 4.8.2 => 4.8.2 react-native-screens: ~3.29.0 => 3.29.0 react-native-toast-message: ^2.2.0 => 2.2.0 responsive-screen: 0.1.0 responsive-screen-orientation-change: 0.1.0 responsive-screen-styled-components: 0.1.0 typescript: ^5.1.3 => 5.4.5 uuid: ^10.0.0 => 10.0.0 (9.0.1, 8.3.2, 7.0.3) uuidv4: ^6.2.13 => 6.2.13 npmGlobalPackages: @aws-amplify/cli: 12.10.1 expo-cli: 6.3.10 npm: 10.5.0 ```

Describe the bug

I set up a REST API with a Lambda proxy that is written using Python and FLASK. I was getting errors upon testing a call of the API from my front-end, and upon looking at cloudwatch logs saw that I was getting an 'InvalidSignatureException':

"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"

upon a 'get' call for this API. I have written a 'POST' method in the same API that works, which I can call from my front-end. Additionally, I have another REST API for which a nearly identical 'GET' call from the front-end will work as well. I also have tested the function using amplify mock function, with the following event.json:

{    
    "path": "/userapi/getProfilePicPath",
    "httpMethod": "GET",
    "queryStringParameters": "",
    "body": "{\"user_id\": \"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\"}", <-- my actual user sub
    "headers": {
        "Content-Type": "application/json"
      }
}

upon which the Lambda does return the expected values.

The following code is the call on the front-end that leads to the error:

export async function getProfileData(userId: string): Promise<{ profilePicturePath: string | null, firstName: string | null } | null> {
    try {
        const getProfileDataResult = await get({
            apiName: 'inclineUserApi',
            path: '/userapi/getProfilePicPath',
            options: {
                body: {
                    'userId': userId
                }
            }
        }).response;

And the following is the actual code for the lambda proxy attached to the API:

 import awsgi
from flask_cors import CORS
from flask import Flask, jsonify, request
import mysql.connector

import os
import pprint
BASE_ROUTE = "/userapi"

app = Flask(__name__)

CORS(app)

# MySQL database configuration
db_config = {
    'host': os.environ['host'],
    'user': os.environ['user'],
    'password': os.environ['db_pass'],
    'database': os.environ['db_name']
}

///CALLING THE POST ENDPOINT BELOW WORKS FROM THE FRONT END
@app.route(BASE_ROUTE + '/insertProfilePic', methods=['POST'])
def insert_profile_pic():
    user_path = request.json.get("profile_path")
    user_id = request.json.get("user_id")
    user_email = request.json.get("user_email")

    try:
    /// Logic logic logic

        else:
            # Handle the case when the user doesn't exist
            return jsonify({"error": "User not found"}), 404

        connection.commit()

        results = {
            "message": "Profile picture URL updated successfully",
            "user_email": user_email
        }
        toRespond = jsonify(results)
        return toRespond

    except mysql.connector.Error as error:
        connection.rollback()
        print(f"Error updating profile picture URL: {error}")
        return jsonify({"error": "Failed to update profile picture URL"}), 500

    finally:
        if connection.is_connected():
            cursor.close()

///CALLING THIS ENDPOINT GIVES THE INVALID SIGNATURE EXCEPTION
@app.route(BASE_ROUTE + '/getProfilePicPath', methods=['GET'])
def get_profile_pic_path():
    user_id = request.json.get("user_id")

    try:
        connection = mysql.connector.connect(**db_config)
        cursor = connection.cursor(dictionary=True)

        # Query the User table to retrieve the profile picture path and first name
        query = "SELECT profile_picture_url, first_name FROM User WHERE user_id = %s"
        cursor.execute(query, (user_id,))
        result = cursor.fetchone()

        if result:
            profile_picture_path = result['profile_picture_url']
            first_name = result['first_name']
            return jsonify({"profile_picture_path": profile_picture_path, "first_name": first_name}), 200
        else:
            return jsonify({"error": "User not found"}), 404

    except mysql.connector.Error as error:
        return jsonify({"error": str(error)}), 500

    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

def handler(event, context):
    return awsgi.response(app, event, context)

@app.route(BASE_ROUTE, methods=['GET'])
def list_env(): 
    pprint.pprint(db_config)
    return jsonify(db_config)

A call to the POST method in the above API works fine, with no InvalidSignatureException issues.

I also have another API in my application, which has a similar GET call, but this time has a user_id variable as a path parameter, and this one seems to work fine:


 import awsgi
from flask_cors import CORS
from flask import Flask, jsonify, request
import mysql.connector
import uuid
import json
BASE_ROUTE = "/feed"

app = Flask(__name__)

CORS(app)

# MySQL database configuration
db_config = {
///DB CONFIG
}

@app.route(BASE_ROUTE + '/getFeedSlides/<user_id>', methods=['GET'])
def get_feed_items(user_id):
    try:
        connection = mysql.connector.connect(**db_config)
        cursor = connection.cursor(dictionary=True)
       ///Logic logic logic

        return toRespond

    except mysql.connector.Error as error:
        return jsonify(error=str(error)), 500

    finally:
        if connection.is_connected():
            cursor.close()

My values of userId for the GET call that returns an InvalidSignatureException have been both a user email and a user cognito sub that is returned from fetchUserAttributes(). The log warning is shown below

Expected behavior

The GET call should return with a status of OK and user profile information in the body of the request

Reproduction steps

  1. Start react-native project with expo and aws-amplify
  2. Add Amplify API with Lambda proxy in Python 3.12 runtime
  3. Write lambda proxy function similarly to code examples shown in details
  4. Call lambda proxy from front-end with 'get' method from aws-amplify/api

Code Snippet

// Put your code below this line.

Log output

The error I am getting in the API gateway logs is as follows: ``` Gateway 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 Canonical String for this request should have been 'GET /dev/userapi/getProfilePicPath content-type:application/json; charset=UTF-8 host:g2wndr4bv3.execute-api.us-east-1.amazonaws.com x-amz-date:20240618T144213Z x-amz-security-token:IQoJb3JpZ.... ```

aws-exports.js

/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_cognito_identity_pool_id": "us-east-1:f6604ed0-XXXX-XXXX-XXXX-25857ecXXXXX",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": "us-east-1_xxXXXXXXX",
    "aws_user_pools_web_client_id": "2XXXXXXXXXXXXXXXXXXXXXXXXX",
    "oauth": {},
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [],
    "aws_cognito_signup_attributes": [
        "EMAIL"
    ],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ],
    "aws_cloud_logic_custom": [
        {
            "name": "inclineFeedApi",
            "endpoint": "https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev",
            "region": "us-east-1"
        },
        {
            "name": "inclineUserApi",
            "endpoint": "https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev",
            "region": "us-east-1"
        },
        {
            "name": "getLibraryApi",
            "endpoint": "https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev",
            "region": "us-east-1"
        }
    ],
    "aws_user_files_s3_bucket": "incline-user-profile-bucketXXXXXX-dev",
    "aws_user_files_s3_bucket_region": "us-east-1"
};

export default awsmobile;

Manual configuration

No response

Additional configuration

No response

Mobile Device

iPhone15

Mobile Operating System

iOS17.4

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

cwomack commented 2 weeks ago

Hello, @abduaddis1 and sorry to hear you're running into this. Can you clarify how you've configured the authorization rules on your lambda proxy and any additional configuration/setup steps you took on it?

abduaddis1 commented 2 weeks ago

Hello, @abduaddis1 and sorry to hear you're running into this. Can you clarify how you've configured the authorization rules on your lambda proxy and any additional configuration/setup steps you took on it?

Hello,

Authorization on my API is as follows:

{
  "version": 1,
  "paths": {
    "/userapi": {
      "name": "/userapi",
      "lambdaFunction": "inclineUserFunction",
      "permissions": {
        "setting": "private",
        "auth": [
          "create",
          "read",
          "update",
          "delete"
        ],
        "groups": {
          "admincustomers": [
            "create",
            "read",
            "update",
            "delete"
          ],
          "employeecustomers": [
            "create",
            "read",
            "update",
            "delete"
          ]
        }
      }
    }
  }
}

I am unfamiliar on how to get the exact authorization rules for my lambda proxy, but the following is my lambda proxy's cloudformation template config:

``` { "AWSTemplateFormatVersion": "2010-09-09", "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.10.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}", "Parameters": { "CloudWatchRule": { "Type": "String", "Default": "NONE", "Description": " Schedule Expression" }, "deploymentBucketName": { "Type": "String" }, "env": { "Type": "String" }, "s3Key": { "Type": "String" }, "host": { "Type": "String" }, "user": { "Type": "String" }, "dbPass": { "Type": "String" }, "dbName": { "Type": "String" } }, "Conditions": { "ShouldNotCreateEnvResources": { "Fn::Equals": [ { "Ref": "env" }, "NONE" ] } }, "Resources": { "LambdaFunction": { "Type": "AWS::Lambda::Function", "Metadata": { "aws:asset:path": "./src", "aws:asset:property": "Code" }, "Properties": { "Code": { "S3Bucket": { "Ref": "deploymentBucketName" }, "S3Key": { "Ref": "s3Key" } }, "Handler": "index.handler", "FunctionName": { "Fn::If": [ "ShouldNotCreateEnvResources", "inclineUserFunction", { "Fn::Join": [ "", [ "inclineUserFunction", "-", { "Ref": "env" } ] ] } ] }, "Environment": { "Variables": { "ENV": { "Ref": "env" }, "REGION": { "Ref": "AWS::Region" }, "host": { "Ref": "host" }, "user": { "Ref": "user" }, "db_pass": { "Ref": "dbPass" }, "db_name": { "Ref": "dbName" } } }, "Role": { "Fn::GetAtt": [ "LambdaExecutionRole", "Arn" ] }, "Runtime": "python3.12", "Layers": [], "Timeout": 25 } }, "LambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": { "Fn::If": [ "ShouldNotCreateEnvResources", "inclinebusinessLambdaRoleXXXXXXXX", { "Fn::Join": [ "", [ "inclinebusinessLambdaRoleXXXXXXXX", "-", { "Ref": "env" } ] ] } ] }, "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] } } }, "lambdaexecutionpolicy": { "DependsOn": [ "LambdaExecutionRole" ], "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": "lambda-execution-policy", "Roles": [ { "Ref": "LambdaExecutionRole" } ], "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": { "Fn::Sub": [ "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", { "region": { "Ref": "AWS::Region" }, "account": { "Ref": "AWS::AccountId" }, "lambda": { "Ref": "LambdaFunction" } } ] } } ] } } } }, "Outputs": { "Name": { "Value": { "Ref": "LambdaFunction" } }, "Arn": { "Value": { "Fn::GetAtt": [ "LambdaFunction", "Arn" ] } }, "Region": { "Value": { "Ref": "AWS::Region" } }, "LambdaExecutionRole": { "Value": { "Ref": "LambdaExecutionRole" } }, "LambdaExecutionRoleArn": { "Value": { "Fn::GetAtt": [ "LambdaExecutionRole", "Arn" ] } } } } ```

I also have the following cloudformation template for my API:

``` { "Description": "API Gateway Resource for AWS Amplify CLI", "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "authinclinebusinessauthUserPoolId": { "Type": "String", "Default": "authinclinebusinessauthUserPoolId" }, "authuserPoolGroupsadmincustomersGroupRole": { "Type": "String", "Default": "authuserPoolGroupsadmincustomersGroupRole" }, "authuserPoolGroupsemployeecustomersGroupRole": { "Type": "String", "Default": "authuserPoolGroupsemployeecustomersGroupRole" }, "functioninclineUserFunctionName": { "Type": "String", "Default": "functioninclineUserFunctionName" }, "functioninclineUserFunctionArn": { "Type": "String", "Default": "functioninclineUserFunctionArn" }, "env": { "Type": "String" } }, "Resources": { "admincustomersGroupuserapiPolicy": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": [ { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/POST/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/GET/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PUT/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PATCH/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/DELETE/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/POST/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/GET/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PUT/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PATCH/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/DELETE/userapi/*" ] ] } ] } ], "Version": "2012-10-17" }, "PolicyName": "inclineUserApi-userapi-admincustomers-group-policy", "Roles": [ { "Fn::Join": [ "-", [ { "Ref": "authinclinebusinessauthUserPoolId" }, "admincustomersGroupRole" ] ] } ] } }, "employeecustomersGroupuserapiPolicy": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": [ { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/POST/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/GET/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PUT/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PATCH/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/DELETE/userapi" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/POST/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/GET/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PUT/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/PATCH/userapi/*" ] ] }, { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] }, "/DELETE/userapi/*" ] ] } ] } ], "Version": "2012-10-17" }, "PolicyName": "inclineUserApi-userapi-employeecustomers-group-policy", "Roles": [ { "Fn::Join": [ "-", [ { "Ref": "authinclinebusinessauthUserPoolId" }, "employeecustomersGroupRole" ] ] } ] } }, "functioninclineUserFunctionPermissioninclineUserApi": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Ref": "functioninclineUserFunctionName" }, "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Join": [ "", [ "arn:aws:execute-api:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "inclineUserApi" }, "/*/*/*" ] ] } } }, "inclineUserApi": { "Type": "AWS::ApiGateway::RestApi", "Properties": { "Body": { "swagger": "2.0", "info": { "version": "2018-05-24T17:52:00Z", "title": "inclineUserApi" }, "host": { "Fn::Join": [ "", [ "apigateway.", { "Ref": "AWS::Region" }, ".amazonaws.com" ] ] }, "basePath": { "Fn::If": [ "ShouldNotCreateEnvResources", "/Prod", { "Fn::Join": [ "", [ "/", { "Ref": "env" } ] ] } ] }, "schemes": [ "https" ], "paths": { "/userapi": { "options": { "consumes": [ "application/json" ], "produces": [ "application/json" ], "responses": { "200": { "description": "200 response", "headers": { "Access-Control-Allow-Origin": { "type": "string" }, "Access-Control-Allow-Methods": { "type": "string" }, "Access-Control-Allow-Headers": { "type": "string" } } } }, "x-amazon-apigateway-integration": { "responses": { "default": { "statusCode": "200", "responseParameters": { "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", "method.response.header.Access-Control-Allow-Origin": "'*'" } } }, "requestTemplates": { "application/json": "{\"statusCode\": 200}" }, "passthroughBehavior": "when_no_match", "type": "mock" } }, "x-amazon-apigateway-any-method": { "consumes": [ "application/json" ], "produces": [ "application/json" ], "parameters": [ { "in": "body", "name": "RequestSchema", "required": false, "schema": { "$ref": "#/definitions/RequestSchema" } } ], "responses": { "200": { "description": "200 response", "schema": { "$ref": "#/definitions/ResponseSchema" } } }, "x-amazon-apigateway-integration": { "responses": { "default": { "statusCode": "200" } }, "uri": { "Fn::Join": [ "", [ "arn:aws:apigateway:", { "Ref": "AWS::Region" }, ":lambda:path/2015-03-31/functions/", { "Ref": "functioninclineUserFunctionArn" }, "/invocations" ] ] }, "passthroughBehavior": "when_no_match", "httpMethod": "POST", "type": "aws_proxy" }, "security": [ { "sigv4": [] } ] } }, "/userapi/{proxy+}": { "options": { "consumes": [ "application/json" ], "produces": [ "application/json" ], "responses": { "200": { "description": "200 response", "headers": { "Access-Control-Allow-Origin": { "type": "string" }, "Access-Control-Allow-Methods": { "type": "string" }, "Access-Control-Allow-Headers": { "type": "string" } } } }, "x-amazon-apigateway-integration": { "responses": { "default": { "statusCode": "200", "responseParameters": { "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'", "method.response.header.Access-Control-Allow-Origin": "'*'" } } }, "requestTemplates": { "application/json": "{\"statusCode\": 200}" }, "passthroughBehavior": "when_no_match", "type": "mock" } }, "x-amazon-apigateway-any-method": { "consumes": [ "application/json" ], "produces": [ "application/json" ], "parameters": [ { "in": "body", "name": "RequestSchema", "required": false, "schema": { "$ref": "#/definitions/RequestSchema" } } ], "responses": { "200": { "description": "200 response", "schema": { "$ref": "#/definitions/ResponseSchema" } } }, "x-amazon-apigateway-integration": { "responses": { "default": { "statusCode": "200" } }, "uri": { "Fn::Join": [ "", [ "arn:aws:apigateway:", { "Ref": "AWS::Region" }, ":lambda:path/2015-03-31/functions/", { "Ref": "functioninclineUserFunctionArn" }, "/invocations" ] ] }, "passthroughBehavior": "when_no_match", "httpMethod": "POST", "type": "aws_proxy" }, "security": [ { "sigv4": [] } ] } } }, "securityDefinitions": { "sigv4": { "type": "apiKey", "name": "Authorization", "in": "header", "x-amazon-apigateway-authtype": "awsSigv4" } }, "definitions": { "RequestSchema": { "type": "object", "required": [ "request" ], "properties": { "request": { "type": "string" } }, "title": "Request Schema" }, "ResponseSchema": { "type": "object", "required": [ "response" ], "properties": { "response": { "type": "string" } }, "title": "Response Schema" } } }, "Description": "", "FailOnWarnings": true, "Name": "inclineUserApi" } }, "inclineUserApiDefault4XXResponse5af1ca21": { "Type": "AWS::ApiGateway::GatewayResponse", "Properties": { "ResponseType": "DEFAULT_4XX", "RestApiId": { "Ref": "inclineUserApi" }, "ResponseParameters": { "gatewayresponse.header.Access-Control-Allow-Origin": "'*'", "gatewayresponse.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", "gatewayresponse.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", "gatewayresponse.header.Access-Control-Expose-Headers": "'Date,X-Amzn-ErrorType'" } } }, "inclineUserApiDefault5XXResponse5af1ca21": { "Type": "AWS::ApiGateway::GatewayResponse", "Properties": { "ResponseType": "DEFAULT_5XX", "RestApiId": { "Ref": "inclineUserApi" }, "ResponseParameters": { "gatewayresponse.header.Access-Control-Allow-Origin": "'*'", "gatewayresponse.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", "gatewayresponse.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", "gatewayresponse.header.Access-Control-Expose-Headers": "'Date,X-Amzn-ErrorType'" } } }, "DeploymentAPIGWinclineUserApieaab7d92": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { "Ref": "inclineUserApi" }, "Description": "The Development stage deployment of your API.", "StageName": { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] } }, "DependsOn": [ "inclineUserApiDefault4XXResponse5af1ca21", "inclineUserApiDefault5XXResponse5af1ca21" ] } }, "Conditions": { "ShouldNotCreateEnvResources": { "Fn::Equals": [ { "Ref": "env" }, "NONE" ] } }, "Outputs": { "RootUrl": { "Description": "Root URL of the API gateway", "Value": { "Fn::Join": [ "", [ "https://", { "Ref": "inclineUserApi" }, ".execute-api.", { "Ref": "AWS::Region" }, ".amazonaws.com/", { "Fn::If": [ "ShouldNotCreateEnvResources", "Prod", { "Ref": "env" } ] } ] ] } }, "ApiName": { "Description": "API Friendly name", "Value": "inclineUserApi" }, "ApiId": { "Description": "API ID (prefix of API URL)", "Value": { "Ref": "inclineUserApi" } } } } ```

If there is another way to view the authorization rules on my lambda proxy or other information you need, please let me know.

cwomack commented 5 days ago

@abduaddis1, thank you for the follow up. Any chance you can share a screenshot or further details on the network logs when this happens? Trying to determine the best way to reproduce this. Thanks!