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’].