serverless: Unable to set IdentitySource to empty value / null

The AWS::ApiGateway::Authorizer translation contains a bug.

The property IdentitySource is only required when caching is enabled.

However, the serverless framework is setting a default value whenever it is undefined in the serverless.yml

Instead the logic should be updated to the following:

    if (typeof identitySource === 'undefined' && resultTtlInSeconds !== 0) {
      identitySource = 'method.request.header.Authorization';
    }
serverless.yml
provider:
  name: aws
  runtime: nodejs14.x
  timeout: 10
  memorySize: 256
  role: LambdaExecutionRole

functions:
  authorizer:
    handler: src/auth.authorize
  authHandler:
    handler: src/auth.handle
    events:
      - http:
          path: auth
          method: get
          authorizer:
            name: authorizer
            type: request
            resultTtlInSeconds: 0 # should disable caching

resources:
  Resources:
    LambdaExecutionRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: foo-role
        Path: /
        ManagedPolicyArns:
          - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action: sts:AssumeRole
serverless deploy -v --conceal output
omitting proprietary output. command was successful

Installed version

Serverless: Running "serverless" installed locally (in service node_modules)
Framework Core: 1.83.3 (local)
Plugin: 3.8.4
SDK: 2.3.2
Components: 2.34.9

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 8
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Hey @pgrzesik & others who are also facing the same issue and looking for a solution. This is what I did:

Instead of using the authorizer configuration provided by default on serverless framework, I went ahead and created a customer resource as below:

resources:
    Resources:
        CustomAuthorizer:
            Type: AWS::ApiGateway::Authorizer
            Properties:
            AuthorizerResultTtlInSeconds: 0
            AuthorizerUri: !Join
                - ""
                - - "arn:"
                - !Ref "AWS::Partition"
                - ":apigateway:"
                - !Ref "AWS::Region"
                - ":lambda:path/2015-03-31/functions/"
                - !GetAtt
                    - AuthorizerLambdaFunction
                    - Arn
                - /invocations
            Name: authorizer
            RestApiId: !Ref ApiGatewayRestApi
            Type: REQUEST

And consume this authorizer in my lambda configuration:

functions:
  estimates:
    handler: EstimatesV2/index.estimates
    events:
      - http:
          path: /v1/estimates/{proxy+}
          method: ANY
          cors: ${file(./resource/CORSHeaders.yml)}
          authorizer:
            type: request
            authorizerId:
              Ref: CustomAuthorizer

This way, I was able to create the API Gateway Authorizer as a custom resource without the identitySource and consume it in the lambda function

Thanks for clarification @samuelAle 🙇 I believe in order to be consitent, the desired behavior should be that the Framework does not set any default values for identitySource but rather checks if resultTtlInSeconds is non-zero and throws an error if identitySource is not defined - as mentioned, it will be consistent with the way it currently works for httpApi authorizers and I believe as it should be from beginning.

So, the potential implementation proposal in my opinion should be like this:

  1. Introduce a deprecation in current major version (2.x) that from new major, the identitySource won’t be set by default and if they want to keep the previous behavior, they need to set it explicitly to method.request.header.Authorization. The deprecation should not be emitted if user already explicitly specifies the indentitySource.
  2. With the next major, we should drop setting the default and remove the deprecation, while also introducing the logic that will throw an error if resultTtlInSeconds is non-zero and identitySource is missing.

What do you think @samuelAle ?

I would suspect that if any of them, it would be serverless-plugin-split-stacks as it deals with raw CloudFormation and it might interfere with the Framework’s logic to strip nulls

It seems that’s the case, it hooks here: https://github.com/dougmoscrop/serverless-plugin-split-stacks/blob/258d2263352044b2ca4e96a19eeba94ec0ef4d7f/split-stacks.js#L30

where the logic that strips null values is executed right after after:aws:package:finalize:mergeCustomProviderResources

Apologies for the late reply. I think this strategy you mention is practical. Let’s move forward with that.

Yes, even when caching is disabled, AWS API Gateway will reject any requests that do not contain the specified IdentitySource.

Hello @samuelAle, thanks for reporting. I’m wondering if we should set the default value at all. In case of httpApi, we throw an error when the identitySource is not defined when caching is enabled (via resultTtlInSeconds), what is your opinion on that?