AWS IAM Authorization for AWS::Serverless::Function for Api Event Type

api-gateway
iam

#1

We are currently using API Keys to secure access to our API Gateway. However, we are moving to an IAM model with access/secret key. I understand that swagger does not allow us to do this (we currently have api_key set in swagger to enable API Key authentication).

I have created the policy needed for the various operations as:

  SvcAccountPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub 'iam-${EnvTag}'
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - 'execute-api:Invoke'
            Resource:
              - !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/GET/*'
              - !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/POST/*'
              - !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/PUT/*'
              - !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SomeApi}/*/DELETE/*'
      Users:
        - !Ref userSvcAcct

My lambda function is shown below. I am still new to cloud formation, and would love some help on what I can do to add a lambda authorizer to this ( I believe it will be in the Events->ApiPost/Get etc section), that would allow me to use secret/access key.

  FtpUserMgmtLambda:
    Type: AWS::Serverless::Function
    Properties:
      Description: Lambda handler function for FTP user management
      Handler: 'handler.UserManagementHandler::handleRequest'
      Runtime: java8
      MemorySize: 512
      Timeout: 300
      FunctionName: !Ref LambdaFunctionName
      Role: !GetAtt UserMgmtLambdaRole.Arn
      CodeUri:
        Bucket: !Ref LambdaCodeS3Bucket
        Key: !Ref LambdaCodeFileName
      VpcConfig:
        SomeConfig stuff here
      Environment:
        Variables:
          dbPort: !Ref UserStoreDbPort
          dbUser: !Ref UserStoreDbUserId
          dbName: !Ref UserStoreDbName
          environment: !Ref EnvTag
          basepath: 'somepath'
      Events:
        ApiPost:
          Type: Api
          Properties:
            RestApiId: !Ref SomeApi
            Path: /path
            Method: POST
            Auth: <<Dont know what to do here! HELP>>
        ApiGet:
          Type: Api
          Properties:
            RestApiId: !Ref SomeApi
            Path: /path
            Method: GET
            Auth: *<<Dont know what to do here! HELP>>*
      Tags:
        Name: !Ref LambdaFunctionName
        function: lambda function that manages ftp users

I looked at https://forum.serverless.com/t/solved-api-gateway-how-to-set-authorization-in-method-request-to-aws-iam/ but don’t think it solves my conundrum. If it does, I am unsure how to apply. Appreciate any help…

Thank you
Karthik


#2

Fixed this through Swagger. Example code as under:
indent preformatted text by 4 spaces
```

swagger: “2.0”
info:
version: “2017-10-17T17:47:44Z”
title: “User-Mgt-API”
basePath: “/${environment}”
schemes:
- “https”
paths:
/ftpuser:
post:
x-amazon-apigateway-auth:
type: aws_iam
produces:
- “application/json”
responses:
200:
description: “When create user request successful”
schema:
$ref: “#/definitions/Empty”
400:
description: “When API vallidation error happens”
schema:
ref: "#/definitions/Empty" x-amazon-apigateway-integration: responses: default: statusCode: "200" uri: Fn::Sub: arn:aws:apigateway:{AWS::Region}:lambda:path/2015-03-31/functions/${FtpUserMgmtLambda.Arn}/invocations
passthroughBehavior: “when_no_match”
httpMethod: “POST”
contentHandling: “CONVERT_TO_TEXT”
type: “aws_proxy”
definitions:
Empty:
type: “object”
title: “Empty Schema”

Then in the cloudformation, added the following to the serverless API definition to process the swagger file. 

`FtpUserMgmtApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: !Ref ApiName
      StageName: !Ref ApiDeploymentStageName
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: !Sub s3://${swaggerS3Location}
`