Installation

Prerequisites

The HUMAN Azure Front Door + Functions App enforcer requires access to the following Azure services:

  • Front Door (Classic, Standard, or Premium Tier)
  • Function App

📘

Note

Requires NodeJS v16.x or higher.

How the Enforcer Works

The Azure Enforcer combines Azure's Front Door CDN caching functionality with the Azure Function App's ability to run serverless code in the cloud.

azure_enforcer_diagram
  1. The client sends a request to Azure Front Door.
  2. Front Door sends the incoming request to the Function App origin group.
  3. If the enforcer in the Function App passes the request, the Azure Function proxies the request back to the same Front Door domain.
  4. If not found in the cache, the Front Door Rule Set sends the request to the origin server.

📘

Note

The 2a flow exists to reduce Function App invocations in the case of First Party requests.

Installation

Functions App

1. Create a Function App.

In the Azure Portal, create a new Function App resource. Provide a name and resource group for the Function App.

  • Select Publish: Code
  • Select Runtime: Node.js
  • Select Version: 18 LTS
  • Select the region, OS, and hosting plan you prefer

2. Configure and compile the JavaScript code.

Importing as SDK into an Existing Function App

If you're utilizing the Functions App for processing HTTP requests from your Front Door already, you can install the Azure Enforcer as an SDK into your JavaScript project.

npm i --save perimeterx-azure-js-sdk

Refer to the API documentation and the example in the example folder of the library for how to best integrate with your project.

Creating a New Function

If you're creating a brand new HTTP trigger function, use the Azure Enforcer template available in GitHub.

  1. From the root of the template, install dependencies by running npm install.
  2. Modify the EnforcerFunction/config.ts file with your desired configuration.
  3. Build the project by running npm run build.
  4. The dist folder will contain the compiled index.js file that will be used for the Function App.

3. Configure and deploy Function App.

You can deploy to Azure by running the Azure Functions Core Tools command to publish the Function App.

func azure functionapp publish <APP_NAME>

The Azure Enforcer also provides host.json and function.json files as examples of working Function App configurations. Feel free to use these JSONs as provided, or modify your existing Function App to conform to the following settings:

  • The route prefix is set to an empty string (see the host.json file). See here for more information.
  • The route trigger is set to {*route}, which translates to all routes (see the function.json file).
  • The method trigger is set to all possible methods (see the function.json file).
  • The authorization level is set to function (see the function.json file). This means invoking the function requires an API key. See here for more information.
enforcer_function_integration

Deploy the compiled JavaScript code to the Azure portal via the Azure Functions Core Tools, the Azure VS Code extension, or simply by copy-pasting these files to the new Function.

Front Door (Standard Tier)

1. Add origin groups to your Azure Front Door.

Add the origin groups with the origin host names below to your Azure Front Door. Each origin group can have a single origin.

  • HSClient: client.perimeterx.net
  • HSCaptcha: captcha.px-cdn.net
  • HSCollector: collector-<APP_ID>.perimeterx.net
  • HSEnforcer: <FUNCTION_APP_NAME>.azurewebsites.net

Health probes and session affinity can be disabled for these origin groups as there is a single origin per group.

fd_origin_groups

2. Add the following Rule Set to your Azure Front Door.

A Front Door Rule Set allows for changing the origin group of the incoming request based on certain parameters. The Rule Set for the Enforcer serves to proxy first party requests to the appropriate Human Security backend (HSClient, HSCaptcha, or HSCollector), as well as proxy unverified requests through the enforcer in the Function App. The Rule Set should contain the following rules in this order:

  1. HSFirstPartyHeaders: Adds necessary headers to first party requests. The default first party prefix as well as any custom first party prefixes or routes should be added here.
hs_first_party_headers
ComponentNameFields
ConditionRequest PathOperator: Begins WithValue: /[APP_ID_NO_PX]/String transform: None
ActionRequest HeaderOperator: AppendHeader name: x-px-first-partyHeader value: 1
ActionRequest HeaderOperator: AppendHeader name: x-px-enforcer-true-ipHeader value: {client_ip}
  1. HSFirstPartyClient: Reroutes first-party sensor script requests directly to the HSClient origin to reduce Function App invocations. The default first party sensor route as well as any custom first party sensor routes (based on the custom first party prefix and custom first party sensor endpoint configurations) should be added here.
hs_first_party_client
ComponentNameFields
ConditionRequest PathOperator: EqualValue: /[APP_ID_NO_PX]/init.jsString transform: None
ActionURL RewriteSource pattern: /[APP_ID_NO_PX]/init.jsDestination: /[APP_ID]/main.min.jsPreserve unmatched path: No
ActionRoute configuration overrideOverride origin group: YesOrigin group: HSClientForwarding protocol: Match incoming requestCaching: Disabled

Stop evaluating remaining rules: True

  1. HSFirstPartyCaptcha: Reroutes first-party captcha script requests directly to the HSCaptcha origin to reduce Function App invocations. The default first party sensor route as well as any custom first party sensor routes (based on the custom first party prefix and custom first party captcha endpoint configurations) should be added here.
hs_first_party_captcha
ComponentNameFields
ConditionRequest PathOperator: Begins withValue: /[APP_ID_NO_PX]/captchaString transform: None
ActionURL RewriteSource pattern: /[APP_ID_NO_PX]/captchaDestination: /[APP_ID]Preserve unmatched path: Yes
ActionRoute configuration overrideOverride origin group: YesOrigin group: HSCaptchaForwarding protocol: Match incoming requestCaching: Disabled

Stop evaluating remaining rules: True

  1. HSFirstPartyXHR: Reroutes first-party XHR requests directly to the HSCollector origin to reduce Function App invocations. The default first party sensor route as well as any custom first party sensor routes (based on the custom first party prefix and custom first party XHR endpoint configurations) should be added here.
hs_first_party_xhr
ComponentNameFields
ConditionRequest PathOperator: Begins withValue: /[APP_ID_NO_PX]/xhrString transform: None
ActionURL RewriteSource pattern: /[APP_ID_NO_PX]/xhrDestination: /Preserve unmatched path: Yes
ActionRoute configuration overrideOverride origin group: YesOrigin group: HSCollectorForwarding protocol: Match incoming requestCaching: Disabled

Stop evaluating remaining rules: True

  1. HSFilterExtension: Filters static content requests to reduce Function App invocations. This corresponds to the filter by extension configuration.
hs_filtered_extensions
ComponentNameFields
ConditionRequest MethodOperator: EqualRequest method: GET
ConditionRequest file extensionOperator: RegExValue: ^\.?(css)|(bmp)|(tif)|(ttf)|(docx)|(woff2)|(pict)|(tiff)|(eot)|(xlsx)|(jpg)|(csv)|(eps)|(woff)|(xls)|(jpeg)|(doc)|(ejs)|(otf)|(pttx)|(gif)|(pdf)|(swf)|(svg)|(ps)|(ico)|(pls)|(midi)|(svgz)|(class)|(png)|(ppt)|(mid)|(webp)|(jar)|(json)$(bmp)(tif)(ttf)(docx)(woff2)(pict)(tiff)(eot)(xlsx)(jpg)(csv)(eps)(woff)(xls)(jpeg)(doc)(ejs)(otf)(pttx)(gif)(pdf)(swf)(svg)(ps)(ico)(pls)(midi)(svgz)(class)(png)(ppt)(mid)(webp)(jar)(json)$`String transform: None
ActionRoute configuration overrideOverride origin group: NoCaching: EnabledQuery string caching behavior: Ignore Query StringCompression: EnabledCache behavior: Honor origin

Stop evaluating remaining rules: True

  1. HSUnenforcedRequest: Routes requests that have not yet been processed by the enforcer to the HSEnforcer origin.
hs_unvalidated_request
ComponentNameFields
ConditionRequest HeaderHeader name: x-enforcer-authOperator: Not EqualHeader Value: [SECRET_KEY]String transform: Trim
ActionRequest HeaderOperator: OverwriteHeader name: x-functions-keyHeader value: [FUNCTIONS_KEY]
ActionRoute configuration overrideOverride origin group: YesOrigin group: HSEnforcerForwarding protocol: Match incoming requestCaching: Disabled

Stop evaluating remaining rules: True

  • The condition checks if the x-enforcer-auth header is equal to some [SECRET_KEY]. This header signifies to Front Door that the request has been processed by the enforcer. The value can be configured to be whatever string you like; however, it must be configured identically in both the Front Door rule and the Function App.
  • The condition adds an x-function-key header. This header is what allows Front Door to trigger the Function App. The [FUNCTIONS_KEY] value should be the Function App's default function key. See the HTTP Trigger Authorization Levels for more information.

3. Associate the Rule Set with the routes you want to protect on your Front Door Endpoints.

This activates the Rule Set on the Front Door endpoint. For more information, see how to configure Front Door endpoints.

Front Door (Classic Tier)

1. Add the Enforcer backend pool to your Azure Front Door.

Add a new backend pool to your Azure Front Door setup. The backend pool should have a single backend host name that points to the Azure Function App.

  • HSEnforcer: <FUNCTION_APP_NAME>.azurewebsites.net

Health probe can be disabled for this backend pool as there is a single backend.

hs_enforcer_backend_pool.png

2. Add the HSEnforcerRule Rules Engine to your Azure Front Door.

A Front Door Rules Engine allows for changing the backend pool of the incoming request based on certain parameters. Create a new Rules Engine named HSEnforcedRule.

hs_enforced_rule.png

This Rules Engine will proxy unverified requests through the enforcer in the Function App. It should include two rules in this order:

  1. HSFilteredExtensions: Routes filtered extensions to directly to the origin rather than having them pass through the Function App enforcer. Notice that first party requests must still be proxied to the Function App.
hs_filtered_extensions.png
ComponentNameFields
ConditionRequest file extensionOperator: ContainsValue (replace commas with line breaks): css, bmptif, ttf, docx, woff2, pict, tiff, eot, xlsx, jpg, csv, eps, woff, xls, jpeg, doc, ejs, otf, pttx, gif, pdf, swf, svg, ps, ico, pls, midi, svgz, class, png, ppt, mid, webp, jar, jsonTransform: None
ConditionRequest MethodOperator: EqualRequest method: GET
ConditionRequest PathOperator: Not Begins WithValue (replace commas with line breaks): /[APP_ID_NO_PX], [APP_ID_NO_PX], /[CUSTOM_FIRST_PARTY_ROUTES], [CUSTOM_FIRST_PARTY_ROUTES]Transform: None
ComponentNameFields
ActionRouting configurationRoute type: ForwardBackend pool: originFowarding protocol: HTTPS onlyURL rewrite: DisabledCaching: EnabledCaching behavior: Ignore query stringsDynamic compression: EnabledUse default cache duration: Yes

Stop evaluating remaining rules: True

  1. HSUnenforcedRequest: Routes requests that have not yet been processed by the enforcer to the enforcer origin.
hs_unenforced_request.png
ComponentNameFields
ConditionRequest HeaderHeader name: x-enforcer-authOperator: Not EqualHeader Value: [SECRET_KEY]Transform: Trim
ActionRequest HeaderOperator: AppendHeader name: x-functions-keyHeader value: [FUNCTIONS_KEY]
ActionRoute configurationRoute type: ForwardBackend pool: HSEnforcerForwarding protocol: HTTPS onlyCaching: Disabled

📘

Note

  • The condition checks if the x-enforcer-auth header is equal to some [SECRET_KEY]. This header signifies to Front Door that the request has been processed by the enforcer. The value can be configured to be whatever string you like; however, it must be configured identically in both the Front Door rule and the Function App.
  • The condition adds an x-function-key header. This header is what allows Front Door to trigger the Function App. The [FUNCTIONS_KEY] value should be the Function App's default function key. See the HTTP Trigger Authorization Levels for more information.

3. Create a routing rule that routes to your desired origin and call the HSEnforcerRule Rule Set.

The routing rule should direct whichever paths you want to protect to the origin backend pool. Associating the HSEnforcerRule Rule Set with the routing rule will ensure these requests pass through the enforcer Function App prior to reaching your origin.

enforced_routing_rule.png afd_designer.png