Installation

The AWS API Gateway Lambda Enforcer works using API Gateway's Lambda authorizer. The enforcer is provided as a Node.js NPM package that can be integrated into an existing Lambda authorizer or used to create a brand new Lambda authorizer.

Prerequisites

  1. An AWS REST API Gateway
  2. Node.js and NPM

Installation

Installing the enforcer consists of three main steps:

  1. Building and deploying the authorizer to AWS Lambda.
  2. Connecting the Lambda authorizer to API Gateway.
  3. Configuring first party resources in API Gateway.

Building and Deploying the Authorizer

  1. Install the enforcer package in your Node.js authorizer project.
npm install @humansecurity/aws-api-gateway-lambda-authorizer-enforcer
  1. Integrate the enforcer into your authorizer code. The following index.ts file can be used as a basis.
// index.ts
import { Enforcer, Config, Res } from "@humansecurity/aws-api-gateway-lambda-authorizer-enforcer";

const pxConfig = {
  px_app_id: "<APP_ID>",
  px_cookie_secret: "<COOKIE_SECRET>",
  px_auth_token: "<AUTH_TOKEN>",
  px_custom_first_party_prefix: "/<STAGE_NAME>/<APP_ID_SUFFIX>/"
  ...
};

// initialize config outside the handler
const config = new Config(pxConfig);

// define an authorizer handler
export const handler = async (req: APIGatewayRequestAuthorizerEvent): Promise<Res> => {
  // create a new enforcer
  const enforcer = new Enforcer(config);
  // call enforce and await the response
  // as early as possible in the Lambda flow
  let response = await enforcer.enforce(req);

  // if a response exists, return it immediately
  // as no further processing is required
  if (response) {
    return response;
  }

  // include your custom authorization logic
  response = {
    principalId: "*",
    policyDocument: {
      Version: "2012-10-17",
      Statement: [
        {
          Action: "execute-api:Invoke",
          Effect: "Allow",
          Resource: req.methodArn
        }
      ]
    },
    context: {}
  };

  // after creating your response, call postEnforce
  await enforcer.postEnforce(req, response);
  // return the response from the handler
  return response;
};
  1. Package and deploy the Lambda code. (Here, we use esbuild to compile the TypeScript file to ./dist/index.js, which can be deployed to the Lambda.)
esbuild ./index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js

Connecting the Lambda Authorizer to API Gateway

  1. Create a Lambda authorizer in your API gateway with the following features:
    • Type: REQUEST
    • Cache: no cache
aws apigateway create-authorizer \
--rest-api-id <rest api id> \
--name <name> \
--type REQUEST \
--authorizer-uri <uri to lambda> \
--authorizer-credentials <IAM Role arn> \
--authorizer-result-ttl-in-seconds 0
  1. Configure custom response page so that the enforcer can return the captcha pages properly. If the enforcer decides to block it returns "Deny" response and sets the authorizer context.pxResponseBody with the block page (HTML or JSON). Therefore, you should change the API Gateway response to display this response body instead of the default.
aws apigateway put-gateway-response \
--rest-api-id <rest api id> \
--response-type ACCESS_DENIED \
--response-templates 'text/html=$context.authorizer.pxResponseBody,application/json=$context.authorizer.pxResponseBody'
  1. Enable CORS for the relevant resources in the API Gateway. Check the box to enable CORS for the Access Denied authorizer response as well.

📘

Enabling Auto-ABR

If your front-end JavaScript makes XHR calls to the API Gateway and you would like to use the Auto-ABR functionality, be sure to add the API Gateway domain to the custom ABR domains variable in the front-end JavaScript snippet. See here for more information.

Configure First Party Resources in API Gateway

  1. Unless the first party feature is disabled, first party resources must be configured in the API Gateway. The resource type should be HTTP_PROXY, as they should proxy to HUMAN Security servers. Add the following three main resources:
    • sensor script
    • captcha script
    • xhr requests
pathdestinationmethod
/<APP_ID_SUFFIX>/init.jshttps://client.perimeterx.net/<APP_ID>/main.min.jsGET
/<APP_ID_SUFFIX>/captcha/{proxy+}https://captcha.px-cdn.net/<APP_ID>/{proxy}GET
/<APP_ID_SUFFIX>/xhr/{proxy+}https://collector-<APP_ID>.perimeterx.net/{proxy}ANY
  • <APP_ID> - the application ID provided by HUMAN Security (e.g., PX1234).
  • <APP_ID_SUFFIX> - your application ID without the PX prefix (e.g., 1234).
first_party_router.png

🚧

Custom First Party Endpoints

If any custom first party endpoints are configured in the Lambda code, these endpoints should be added to the above resources in the API Gateway as well.

  1. If needed, enable CORS for the API Gateway first party resources as well.
  2. Deploy and stage the API Gateway.