Description:
My expectation was that when using the Auth functionality in SAM against an API and Function, when no default
authorizer is configured then the Authorizer would be assigned against the Functions path
I've also noticed that when using a Default Authorizer, all methods on the API get the Authorizer assigned, configuring
NONE authorizer against an API Event does not prevent the authorizer getting assigned.
Steps to reproduce the issue:
Given a SAM Template that includes a an inline swagger document, an Authorizer and Auth configured on the DELETE and
POST events
template.yaml
---
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: python3.6
MemorySize: 128
Timeout: 15
Resources:
Create:
Type: AWS::Serverless::Function
Properties:
CodeUri: example
Handler: service.example
Events:
Create:
Type: Api
Properties:
Method: post
Path: /
RestApiId: !Ref API
Auth:
Authorizer: ExampleAuth
List:
Type: AWS::Serverless::Function
Properties:
CodeUri: example
Handler: service.example
Events:
Create:
Type: Api
Properties:
Method: get
Path: /
RestApiId: !Ref API
Delete:
Type: AWS::Serverless::Function
Properties:
CodeUri: example
Handler: service.example
Events:
AddTenant:
Type: Api
Properties:
Method: delete
Path: /{id}
RestApiId: !Ref API
Auth:
Authorizer: ExampleAuth
Retrieve:
Type: AWS::Serverless::Function
Properties:
CodeUri: example
Handler: service.example
Events:
AddTenant:
Type: Api
Properties:
Method: post
Path: /{id}
RestApiId: !Ref API
Auth:
Type: AWS::Serverless::Function
Properties:
CodeUri: example
Handler: service.example
API:
Type: AWS::Serverless::Api
Properties:
Name: ExampleAPI
EndpointConfiguration: REGIONAL
StageName: v1
Auth:
Authorizers:
ExampleAuth:
FunctionPayloadType: TOKEN
FunctionArn: !GetAtt Auth.Arn
Identity:
Header: Authorization
ValidationExpression: Bearer.*
ReauthorizeEvery: 0
DefinitionBody:
swagger: "2.0"
info:
title: Example
version: "1"
parameters:
id:
name: id
in: path
required: true
type: string
paths:
/:
post:
parameters:
- in: body
name: item
schema:
type: object
responses:
"201":
description: Created
x-amazon-apigateway-integration:
type: aws_proxy
httpMethod: POST
passthroughBehavior: when_no_match
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Create.Arn}/invocations
get:
responses:
"200":
description: Got
x-amazon-apigateway-integration:
type: aws_proxy
httpMethod: POST
passthroughBehavior: when_no_match
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${List.Arn}/invocations
/{id}:
get:
parameters:
- $ref: '#/parameters/id'
responses:
"200":
description: Got
x-amazon-apigateway-integration:
type: aws_proxy
httpMethod: POST
passthroughBehavior: when_no_match
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Retrieve.Arn}/invocations
delete:
parameters:
- $ref: '#/parameters/id'
responses:
"200":
description: Deleted
x-amazon-apigateway-integration:
type: aws_proxy
httpMethod: POST
passthroughBehavior: when_no_match
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Delete.Arn}/invocations
example/service.py
def example(event, context):
print(event)
return 200
example/__init__.py
__version__ = "1.0.0"
Deploy this SAM Template
sam package --template-file template.yaml --s3-bucket "${S3_BUCKET}" > template-export.yaml
sam deploy --template-file template-export.yaml --stack-name "${STACK_NAME}" --capabilities CAPABILITY_IAM
Observed result:
No Authorizers are assigned to any of the methods


Expected result:
My expectation was that the GET Methods on the path / and /{id} would not have an authorizer assigned, but POST / and DELETE /{id} do not have authorizer assigned
We plan on adding a feature to merge your defined Swagger with the generated Swagger from SAM. This should resolve this issue also.
A workaround exists where if the name of the Authorizer defined in the SAM template matches the name of a securityDefinitions in the swagger document, AND the endpoint refers to that named security definition, then the correct authorizer will be assigned to the endpoint.
This is often what is desired, because if you have security requirements for the endpoint, you probably want to define them (as best you can) in the swagger doc.
SAM snippet below:
myApi:
Type: AWS::Serverless::Api
Properties:
EndpointConfiguration: REGIONAL
StageName: master
DefinitionBody:
swagger: '2.0'
info:
title: Test
version: 1.0.0
description: Only a test
schemes:
- https
paths:
"/sayHello":
get:
operationId: hello
description: Says "Hello"
produces:
- text/html
responses:
'200':
description: OK
default:
description: Error
security:
- keyAuth: [] # refers to security definition in this swagger doc
x-amazon-apigateway-integration:
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Function.Arn}/invocations
httpMethod: POST
type: aws_proxy
securityDefinitions:
keyAuth: #matches name of Auth/Authorizer defined on the Api
description: Authentication will be performed using a custom authenticator
type: apiKey
name: Authorization
in: header
Auth:
Authorizers:
keyAuth: # Name of this authorizer; becomes the name of the authorizer in API Gateway console
Identity:
Headers:
- Authorization
ReauthorizeEvery: 600
FunctionPayloadType: REQUEST
FunctionArn: !Ref CustomAuthArn
The result of the above is that the authorizer is created with expected properties in the API, and the endpoint is configured to use that authorizer.
Untested are the effects of setting the Serverless::Function/Events/Auth/Authorizer to NONE or setting the DefaultAuthorizer property on the Serverless::Api/Auth/Authorizers
Most helpful comment
We plan on adding a feature to merge your defined Swagger with the generated Swagger from SAM. This should resolve this issue also.