How can I copy authorizer context to a request integration parameter?

I have a custom authorizer that emits context information that I’d like to pass in a header to an HTTP API backend.

According to the AWS docs, I should be able to reference context.authorizer.key in the request integration headers, like this:

As a new user, I don’t have sufficient karma to post all the links / images for the research I’ve done, so this will be a bit awkward.

I’ve tried poking around and have even dug into the code, but it doesn’t seem like there is a way to do what I’m describing with the current Serverless AWS provider. Using:

    events:
      - http:
          path: /echo
          method: get
          authorizer:
            name: authorizer
            type: request
          integration: http-proxy
          request:
            uri: https://example.com/
            method: get
            parameters:
              headers:
                SomeKey: context.authorizer.someKey

really doesn’t work, as it creates a Method Request header definition that looks like this:

HTTP Request Headers

Name        Required  Caching
SomeKey  [ ]               [ ]

and an Integration Request definition that looks like this:

Name        Mapped From                                 Caching
SomeKey  method.request.header.SomeKey  [ ]

The relevant bit in the CloudFormation seems to be:

    "ApiGatewayMethodEchoGet": {
      "Type": "AWS::ApiGateway::Method",
      "Properties": {
        "HttpMethod": "GET",
        "RequestParameters": {
          "method.request.header.SomeKey": "context.authorizer.someKey"
        },
        "ResourceId": {
          "Ref": "ApiGatewayResourceEcho"
        },
        "RestApiId": {
          "Ref": "ApiGatewayRestApi"
        },
        "ApiKeyRequired": false,
        "AuthorizationType": "CUSTOM",
        "AuthorizerId": {
          "Ref": "AuthorizerApiGatewayAuthorizer"
        },
        "Integration": {
          "IntegrationHttpMethod": "GET",
          "Type": "HTTP_PROXY",
          "Uri": "https://example.com/",
          "RequestParameters": {
            "integration.request.header.SomeKey": "method.request.header.SomeKey"
          }
        },
        "MethodResponses": []
      },
      "DependsOn": "AuthorizerApiGatewayAuthorizer"
    },

which I think should look more like this:

    "ApiGatewayMethodEchoGet": {
      "Type": "AWS::ApiGateway::Method",
      "Properties": {
        "HttpMethod": "GET",
        "RequestParameters": {
        },
        "ResourceId": {
          "Ref": "ApiGatewayResourceEcho"
        },
        "RestApiId": {
          "Ref": "ApiGatewayRestApi"
        },
        "ApiKeyRequired": false,
        "AuthorizationType": "CUSTOM",
        "AuthorizerId": {
          "Ref": "AuthorizerApiGatewayAuthorizer"
        },
        "Integration": {
          "IntegrationHttpMethod": "GET",
          "Type": "HTTP_PROXY",
          "Uri": "https://example.com/",
          "RequestParameters": {
            "integration.request.header.SomeKey": "context.authorizer.someKey"
          }
        },
        "MethodResponses": []
      },
      "DependsOn": "AuthorizerApiGatewayAuthorizer"
    },

The serverless docs page for API Gateway is silent on this topic.

What am I missing?

This looks like it’s related but possibly not the exact right part of the code: https://github.com/serverless/serverless/blob/c9a6b75d49502cb429ad34ef4a917f6d286db60e/lib/plugins/aws/package/compile/events/apiGateway/lib/method/integration.js#L209

Thanks for the question! This should be possible by returning a “context” object in the policy returned by your authorizer. That context is then pushed over to the Lambda function you trigger. An example of this can be found here: https://github.com/fernando-mc/serverlessjams/blob/master/backend/auth.py

In the case in that function generate_policy() generates the IAM policy used to authorizer the access to the Lambda Function that handles the API endpoint. But it also adds a “context” object to the policy which in this case contains scopes for the API. You can use that context object to send things other than scopes though.

I hope this helps! If you want to learn more about it there is a section on Lambda Authorizers and Protected APIs in the latter half of this free course - https://serverless.com/learn/courses/serverless-for-frontend-developers/

Thanks @fernando-mc … I’m having no problem with returning the context object from my authorizer, the problem is that there doesn’t seem to be a way to pass the value from the context as a header to my HTTP backend. API Gateway documents a way to do this (I showed it in the image in my original post) but the Serverless Framework doesn’t seem to describe a way to take an HTTP header in the integration request from the context.

Sorry about the delayed reply @tmglb, I was out for a bit and just getting caught up today! I’m not sure on how to configure that - I haven’t done it before myself. Have you already asked this question in the Community Slack, sometimes other folks have already done things like this?

You can join the Slack here - serverless.com/slack

Hey @tmglb, did you find a solution to this problem? I’m having the same issue trying to pass context from the custom authorizer. I tried a search in the Slack and I can see the question being asked but no answers.

I did eventually get context from the custom authorizer to work, though I couldn’t exactly say why.

I had binaryMediaTypes: */* and allegedly this was interfering with request processing. Removing it was one of the steps that was required to make things work.

One other important thing to note is that apparently the custom authorizer is not invoked if you use the Test button, so if you are not seeing authorizer context when using that path, that’s possibly why. I learned this the very hard way :neutral_face: .