Review API Gateway authentication configuration

Attach appropriate authentication to protected API routes and verify actual permission checks.

Description

Without effective authentication and authorization, protected API functions may be available to unintended callers. IAM authentication or other access controls may apply even without an Authorizer resource, so check the API’s purpose and actual method and route configuration.

Declaring an authorizer does not apply authentication to a route. It must be attached according to the API type; a Lambda authorizer for a WebSocket API can be used only on the $connect route.

Potential impact

  • Operations that require authentication may be available to unverified callers.
  • Authenticating a connection without checking permissions for later messages can allow operations beyond the intended scope.

Remediation

Select authentication appropriate for the API type and callers, and attach it to protected methods or routes. For a WebSocket API, connect the Lambda authorizer through CUSTOM authentication and AuthorizerId on the $connect route, and prepare Lambda invocation permissions. Check permissions for subsequent operations in the application and test allowed and denied cases.

Examples

This excerpt defines a WebSocket API and an authorizer. Replace the Lambda ARN with the actual function and configure invocation permissions and the $connect route separately. Prevent query-string tokens from entering logs and use WSS connections.

Before

yaml
Resources:
  DevWebSocket:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: dev-websocket
      ProtocolType: WEBSOCKET
      RouteSelectionExpression: $request.body.action

Only the API definition is shown; route authentication settings are absent from this excerpt. Check the intended public use and authentication of the actual routes.

After

yaml
Resources:
  DevWebSocket:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: dev-websocket
      ProtocolType: WEBSOCKET
      RouteSelectionExpression: $request.body.action

  DevAuthorizer:
    Type: AWS::ApiGatewayV2::Authorizer
    Properties:
      Name: request-authorizer
      ApiId: !Ref DevWebSocket
      AuthorizerType: REQUEST
      IdentitySource:
        - route.request.querystring.token
      AuthorizerUri: arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:auth/invocations

This adds a REQUEST authorizer. The declaration alone does not enable authentication; attach it to the $connect route.

References