How to restrict access to API gateway

I’ve a lambda function with API Gateway with several routes. Its working great, but I want to restrict the access only for users within my company.

Currently I can access the API from a browser

https://gg5ereew0.execute-api.us-east-1.amazonaws.com/test/pets

This is allowing a public access which I don’t want.
There are several methods to restrict access to API according to AWS Documentation here, but I am not sure which is the easiest one to implement.

MyApiGateway:
  Type: AWS::Serverless::Api
  Properties:
    Name:
      !Sub
      - '${TheEnv}-${TheAppNameForResources}-api'
      - TheEnv: !Ref Environment
        TheAppNameForResources: !Ref AppNameForResources
        TheBucketRegion: !Ref AWS::Region
    TracingEnabled: true
    OpenApiVersion: 3.0.2
    Cors:
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
      AllowMethods: "'*'"
      AllowOrigin: "'*'"
    StageName: test
    Auth:
      ResourcePolicy:
        CustomStatements:
          - Effect: Allow
            Principal: "*"
            Action: "execute-api:Invoke"
            Resource: "execute-api:us-east-1:xxxxxxx4:qkmigyu020/test/GET/pets"

MyLambdaFunction:
  Type: AWS::Serverless::Function
  Properties:
    Description: >
      Currently does not support S3 upload event.
    Handler: app.lambda_handler
    Runtime: python3.12
    FunctionName:
      !Sub
        - "${TheEnv}-${TheAppNameForResources}-get-v1"
        - TheEnv: !Ref Environment
          TheAppNameForResources: !Ref AppNameForResources
    CodeUri: .
    MemorySize: 10240
    Role: !GetAtt MyLambdaExecutionRole.Arn
    Events:
      MyPaymentAPIEvent:
        Type: Api
        Properties:
          RestApiId:
            Ref: MyApiGateway
          Path: /pets
          Method: GET


MyLambdaExecutionRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName:
      !Sub
      - "${TheAppNameForResources}-${TheEnvName}-lambda-execution-role"
      - TheAppNameForResources: !Ref AppNameForResources
        TheEnvName: !Ref Environment
    AssumeRolePolicyDocument:
      Statement:
        - Effect: Allow
          Principal:
          Service: ['lambda.amazonaws.com', 'apigateway.amazonaws.com']
          Action: ['sts:AssumeRole']
    Policies:
      - PolicyName:
          !Sub
          - "${TheAppNameForResources}-${TheEnvName}-lambda-execution-role-policy"
          - TheAppNameForResources: !Ref AppNameForResources
            TheEnvName: !Ref Environment
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - 'logs:CreateLogGroup'
                - 'logs:CreateLogStream'
                - 'logs:PutLogEvents'
                - 'batch:SubmitJob'
                - 'batch:DescribeJobs'
                - 'batch:CancelJob'
                - 'apiGateway:Invoke'
                - 'S3:*'

I bit confused where exactly I should look to restrict the API access.

Any help in understanding this much appreciated.

  • There are many ways documented for managing access to an API Gateway endpoint. Are you running into a particular problem?

    – 




  • Yes, in my ResourcePolicy under “AWS::Serverless::Api”, I added Resource: “execute-api:us-east-1:xxxxxxx4:qkmigyu020/test/GET/pets”. Before that I had “AWS: !Sub ‘arn:aws:iam::${AWS::AccountId}:root'” which allowed access to API to all. With this addition, I am not getting “Message”:”User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:********4″. So I am not sure how to restict access to API to users only within my AWS DEV account. Thanks

    – 




  • I tried the solution posted in stackoverflow.com/questions/51736671/… and I am able to create API key successfully. I also see that my API endpoints now list the API key. However when I tried to call the API from browser along with “key” parameter I am getting “forbidden” error. z2z1q04qx6.execute-api.us-east-1.amazonaws.com/test/…. I don’t know where I am going wrong here. I was told that I need to check for the API key in my lambda code which I did. api_key_from_event = event[‘headers’][‘x-api-key’].

    – 

Leave a Comment