I am having issues getting the methodArn
from a request object in an authorizer lambda I have defined. I am using serverless with golang. Here is a redacted setup of the code that I have.
main.go - the authorizer handler function
func Handler(request events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
// I have tried logging the entire request to cloud watch, see further down for the sample
// i have code here to verify a jwt token
return nil, nil
}
serverless.yml - my serverless setup to register the function and define the authorizer
functions:
permission_verify:
handler: bin/handlers/permission/verify
package:
patterns:
- "!./**"
- ./bin/**
provider:
httpApi:
authorizers:
custom:
functionName: permission_verify
type: request
With the above setup I am able to use the authorizer in other microservices to verify jwt
tokens but now I would like to add more functionality to the authorizer and with that I need the methodArn
on the request to be present.
Here is the output from cloud watch after hitting an endpoint that uses the authorizer
cloud watch - the request json
{
"type": "REQUEST",
"methodArn": "",
"resource": "",
"path": "",
"httpMethod": "",
"headers": {
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"authorization": "redacted",
"content-length": "redacted",
"content-type": "application/json",
"host": "redacted",
"postman-token": "redacted",
"user-agent": "PostmanRuntime/7.31.3",
"x-amzn-trace-id": "redacted",
"x-forwarded-for": "redacted",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
},
"queryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"path": "",
"accountId": "redacted",
"resourceId": "",
"stage": "$default",
"requestId": "redacted",
"identity": {
"apiKey": "",
"sourceIp": ""
},
"resourcePath": "",
"httpMethod": "",
"apiId": "redacted"
}
}
I have scoured the internet looking for an explanation and cause for having no information about the calling lambda in the request to no avail. It has been quite a bit of time, any help would be immensely appreciated.
I found a solution that worked using REST
instead of HTTP
. I had to redo all my functions and define the serverless like the following;
serverless.yaml
custom:
authorizer:
type: token
identitySource: method.request.header.Authorization
identityValidationExpression: Bearer (.*)
name: permission_verify
# if this is in a different service, you can replace the name property with 'arn' having the arn of the function
functions:
permission_verify:
handler: bin/handlers/permission/verify
permission_read:
events:
-http: # i had httpApi before
method: get
path: /
authorizer: ${self:custom.authorizer}
This allowed me to change the function signature to something like below, and after checking the cloud watch logs, I was able to get the method ARN.
func Handler(request events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error)
Here is an example of what I got in cloud watch;
{
"type": "TOKEN",
"authorizationToken": "Bearer <redacted>",
"methodArn": "arn:aws:execute-api:us-east-1:redacted/PUT/"
}
In summary, the cause of this was just inconsistent serverless config that did not fit the purpose of what I required. I'd say IMO, it is easy to think that serverless is a fool proof way of defining infrastructure but it's not and it's good to understand what you're going for against what is offered.