> This page is for Applications Protection.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.humansecurity.com/llms.txt.

# Akamai EdgeWorker v4 configuration options

Each Enforcer has a set of **configuration options** that control the Enforcer's functionality and features. While some are required, many of these are optional configurations that you can use to customize the Enforcer's behavior. You can reference available configurations with this article. You can add and maintain configurations with Akamai Property Manager variables.

> **Note**
>
> While all Enforcers come with the same set of required configurations, the optional configurations available for each may differ. We recommend updating to the latest Enforcer version to ensure you have access to the latest features and configurations.

Every variable will always precede with `PMUSER_` (i.e. `PX_APP_ID` becomes `PMUSER_PX_APP_ID`). Akamai Property rules reference the Akamai Property variables dynamically whenever possible. However, sometimes changes to the Akamai Property variables also need changes to the Akamai Property rules, such as for `PX_APP_ID` and `PX_FILTER_BY_EXTENSION`. Be sure to double-check the Property rules when making variable changes to ensure they are aligned.

## Deployment

Whenever you update the Enforcer's configuration, you must rebuild the Worker for the changes to take effect. To do so:

1. Run `npm run build:worker`.
2. Upload and activate the newly generated bundle.

[Custom functions](#custom-functions) must be implemented directly within the Akamai EdgeWorker code in `example/src/customFunctions.ts` or equivalent source file used for bundling.

## Quick reference

#### Basic functionality

| Feature name                           | Key                 | Type    | Default                           | Description                                                                                                                           |
| :------------------------------------- | :------------------ | :------ | :-------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
| [Application ID](#PX_APP_ID)           | `PX_APP_ID`         | String  | `""`                              | HUMAN Application ID                                                                                                                  |
| [Authentication token](#PX_AUTH_TOKEN) | `PX_AUTH_TOKEN`     | String  | `""`                              | HUMAN authentication token                                                                                                            |
| [Cookie secret](#PX_COOKIE_SECRET)     | `PX_COOKIE_SECRET`  | String  | `""`                              | HUMAN cookie secret                                                                                                                   |
| [Backend domain](#PX_BACKEND_DOMAIN)   | `PX_BACKEND_DOMAIN` | String  | `sapi-<PX_APP_ID>.perimeterx.net` | Domain to which HUMAN requests are sent                                                                                               |
| [S2S timeout](#PX_S2S_TIMEOUT)         | `PX_S2S_TIMEOUT`    | Integer | `1000`                            | Total time, in milliseconds, that the Enforcer will wait for the Risk API request to return before timing out and passing the request |

#### Basic features

| Feature name                           | Key                  | Type             | Default     | Description                                                                                                                                |
| :------------------------------------- | :------------------- | :--------------- | :---------- | :----------------------------------------------------------------------------------------------------------------------------------------- |
| [Logger](#PX_LOGGER_SEVERITY)          | `PX_LOGGER_SEVERITY` | String           | `"error"`   | The threshold above which logs on a particular event are received.                                                                         |
| [Client IP extraction](#PX_IP_HEADERS) | `PX_IP_HEADERS`      | Array of strings | `[]`        | Header names that are trusted to contain the true client IP. This is required when there are proxies between the Enforcer and your server. |
| [Module enable](#PX_MODULE_ENABLED)    | `PX_MODULE_ENABLED`  | Boolean          | `true`      | Whether the HUMAN Enforcer module is enabled                                                                                               |
| [Module mode](#PX_MODULE_MODE)         | `PX_MODULE_MODE`     | String           | `"monitor"` | The HUMAN Enforcer's operation mode                                                                                                        |

#### Optional

| Feature name                                                                             | Key                                                       | Type              | Default                      | Description                                                                                                                   |
| :--------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :---------------- | :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------- |
| [Advanced blocking response (ABR)](#advanced-blocking-response-abr)                      | [`PX_ABR_ENABLED`](#PX_ABR_ENABLED)                       | Boolean           | `true`                       | Whether JSON block responses are returned for `Accept: application/json` requests.                                            |
| [Bypass monitor header](#bypass-monitor-header)                                          | [`PX_BYPASS_MONITOR_HEADER`](#PX_BYPASS_MONITOR_HEADER)   | String            | `x-px-block`                 | Header name that triggers the blocking workflow even in [monitor mode](#PX_MODULE_MODE).                                      |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_EXTRACT_ENABLED`](#PX_CI_EXTRACT_ENABLED)         | Boolean           | `false`                      | Whether to enable Credential Intelligence.                                                                                    |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_EXTRACT_DETAILS`](#PX_CI_EXTRACT_DETAILS)         | Object            | —                            | JSON object defining login endpoints for credential extraction. See [details](#PX_CI_EXTRACT_DETAILS).                        |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_COMPROMISED_HEADER`](#PX_CI_COMPROMISED_HEADER)   | String            | `px-compromised-credentials` | Header name set on the incoming request when credentials are compromised.                                                     |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_AS2S_HEADER_ENABLED`](#PX_CI_AS2S_HEADER_ENABLED) | Boolean           | `false`                      | Whether to attach the `additional_s2s` payload and URL as headers on the original request.                                    |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_SEND_RAW_USERNAME`](#PX_CI_SEND_RAW_USERNAME)     | Boolean           | `false`                      | Whether to send the raw username on the `additional_s2s` activity.                                                            |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_LS_REPORTING_METHOD`](#PX_CI_LS_REPORTING_METHOD) | String            | `status`                     | **Deprecated.** Use [`PX_CI_EXTRACT_DETAILS.login_successful_reporting_method`](#login_successful_reporting_method) instead.  |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_LS_STATUS`](#PX_CI_LS_STATUS)                     | Integer\[]        | `200`                        | **Deprecated.** Use [`PX_CI_EXTRACT_DETAILS.login_successful_statuses`](#login_successful_statuses) instead.                  |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_LS_BODY_REGEX`](#PX_CI_LS_BODY_REGEX)             | String            | `""`                         | **Deprecated.** Use [`PX_CI_EXTRACT_DETAILS.login_successful_body_regex`](#login_successful_body_regex) instead.              |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_LS_HEADER_NAME`](#PX_CI_LS_HEADER_NAME)           | String            | `""`                         | **Deprecated.** Use [`PX_CI_EXTRACT_DETAILS.login_successful_header_name`](#login_successful_header_name) instead.            |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_LS_HEADER_VALUE`](#PX_CI_LS_HEADER_VALUE)         | String            | `""`                         | **Deprecated.** Use [`PX_CI_EXTRACT_DETAILS.login_successful_header_value`](#login_successful_header_value) instead.          |
| [Credentials Intelligence](#credentials-intelligence)                                    | [`PX_CI_VERSION`](#PX_CI_VERSION)                         | String            | `both`                       | **Deprecated.** Use [`PX_CI_EXTRACT_DETAILS.protocol`](#protocol) instead.                                                    |
| [CORS support](#cors-support)                                                            | [`PX_CORS_SUPPORT_ENABLED`](#PX_CORS_SUPPORT_ENABLED)     | Boolean           | `false`                      | Whether to enable CORS support.                                                                                               |
| [Custom cookie header](#custom-cookie-header)                                            | [`PX_CUSTOM_COOKIE_HEADER`](#PX_CUSTOM_COOKIE_HEADER)     | String            | `x-px-cookies`               | Custom name for the header that contains HUMAN cookies.                                                                       |
| [Enforced routes](#enforced-routes)                                                      | [`PX_ENFORCED_ROUTES`](#PX_ENFORCED_ROUTES)               | String (`RegExp`) | `[]`                         | Regular expression for routes enforced even in [monitor mode](#PX_MODULE_MODE).                                               |
| [Filters](#filters)                                                                      | [`PX_FILTER_BY_EXTENSION`](#PX_FILTER_BY_EXTENSION)       | String            | Common static extensions     | Comma-separated list of file extensions ignored by the Enforcer. See [details](#PX_FILTER_BY_EXTENSION).                      |
| [Filters](#filters)                                                                      | [`PX_FILTER_BY_HTTP_METHOD`](#PX_FILTER_BY_HTTP_METHOD)   | String            | `HEAD,TRACE`                 | Comma-separated list of HTTP methods ignored by the Enforcer.                                                                 |
| [Filters](#filters)                                                                      | [`PX_FILTER_BY_IP`](#PX_FILTER_BY_IP)                     | String            | empty                        | Comma-separated list of IP addresses or CIDR ranges ignored by the Enforcer.                                                  |
| [Filters](#filters)                                                                      | [`PX_FILTER_BY_ROUTE`](#PX_FILTER_BY_ROUTE)               | String (`RegExp`) | `[]`                         | Regular expression for routes ignored by the Enforcer.                                                                        |
| [Filters](#filters)                                                                      | [`PX_FILTER_BY_USER_AGENT`](#PX_FILTER_BY_USER_AGENT)     | String (`RegExp`) | `[]`                         | Regular expression for user agents ignored by the Enforcer.                                                                   |
| [First party](#first-party)                                                              | [`PX_FIRST_PARTY_ENABLED`](#PX_FIRST_PARTY_ENABLED)       | Boolean           | `true`                       | Whether to enable first party mode.                                                                                           |
| [GraphQL support](#graphql-support)                                                      | [`PX_GRAPHQL_ENABLED`](#PX_GRAPHQL_ENABLED)               | Boolean           | `true`                       | Whether to extract GraphQL operation data from requests that match [GraphQL routes](#PX_GRAPHQL_ROUTES).                      |
| [GraphQL support](#graphql-support)                                                      | [`PX_GRAPHQL_ROUTES`](#PX_GRAPHQL_ROUTES)                 | String (`RegExp`) | `/^/graphql$/i`              | Regular expression for routes treated as GraphQL endpoints.                                                                   |
| [GraphQL support](#graphql-support)                                                      | [`PX_SENSITIVE_GQL_OP_NAMES`](#PX_SENSITIVE_GQL_OP_NAMES) | String (`RegExp`) | empty                        | Regular expression of sensitive GraphQL operation names or keywords that trigger a Risk API call.                             |
| [GraphQL support](#graphql-support)                                                      | [`PX_SENSITIVE_GQL_OP_TYPES`](#PX_SENSITIVE_GQL_OP_TYPES) | String            | empty                        | Comma-separated list of sensitive GraphQL operation types (`query`, `mutation`, `subscription`).                              |
| [GraphQL support](#graphql-support)                                                      | [`PX_GRAPHQL_KEYWORDS`](#PX_GRAPHQL_KEYWORDS)             | String (`RegExp`) | empty                        | Regular expression of keywords extracted from GraphQL queries.                                                                |
| [Header data enrichment](#header-data-enrichment)                                        | [`PX_DE_HEADER_NAME`](#PX_DE_HEADER_NAME)                 | String            | `""`                         | Header name for sending [data classification enrichment](/applications/data-classification-enrichment) values to the request. |
| [HUMAN Challenge & hard block customization](#human-challenge--hard-block-customization) | [`PX_CSS_REF`](#PX_CSS_REF)                               | String            | `""`                         | URL to a custom CSS file for the [HUMAN Challenge](/applications/customize-challenge-look-feel) block page.                   |
| [HUMAN Challenge & hard block customization](#human-challenge--hard-block-customization) | [`PX_JS_REF`](#PX_JS_REF)                                 | String            | `""`                         | URL to a custom JavaScript file loaded with the block page.                                                                   |
| [HUMAN Challenge & hard block customization](#human-challenge--hard-block-customization) | [`PX_CUSTOM_LOGO`](#PX_CUSTOM_LOGO)                       | String            | `""`                         | URL of a custom logo displayed on the block page.                                                                             |
| [Monitored routes](#monitored-routes)                                                    | [`PX_MONITORED_ROUTES`](#PX_MONITORED_ROUTES)             | String (`RegExp`) | empty                        | Regular expression for routes treated as [monitor mode](#PX_MODULE_MODE) even when actively blocking.                         |
| [PXHD cookie](#pxhd-cookie)                                                              | [`PX_SECURED_PXHD_ENABLED`](#PX_SECURED_PXHD_ENABLED)     | Boolean           | `false`                      | Whether the [`_pxhd` cookie](/applications/use-of-cookies-web-storage) includes the `Secure` attribute.                       |
| [Remote Configuration](#remote-configuration)                                            | [`PX_LOGGER_AUTH_TOKEN`](#PX_LOGGER_AUTH_TOKEN)           | String            | empty                        | Authentication token for HUMAN's logger service. **Security Settings:** Hidden                                                |
| [Remote Configuration](#remote-configuration)                                            | [`PX_RC_AUTH_TOKEN`](#PX_RC_AUTH_TOKEN)                   | String            | empty                        | JWT that authenticates with HUMAN's Remote Configuration service. **Security Settings:** Hidden                               |
| [Remote Configuration](#remote-configuration)                                            | [`PX_RC_ID`](#PX_RC_ID)                                   | String            | empty                        | Remote Configuration ID.                                                                                                      |
| [Remote Configuration](#remote-configuration)                                            | [`PX_RC_MAX_FETCH_ATTEMPTS`](#PX_RC_MAX_FETCH_ATTEMPTS)   | Integer           | `5`                          | Maximum number of attempts to fetch Remote Configuration.                                                                     |
| [Remote Configuration](#remote-configuration)                                            | [`PX_RC_RETRY_INTERVAL`](#PX_RC_RETRY_INTERVAL)           | Integer           | `1000`                       | Interval in milliseconds between Remote Configuration fetch attempts.                                                         |
| [Sensitive headers removal](#sensitive-headers-removal)                                  | [`PX_SENSITIVE_HEADERS`](#PX_SENSITIVE_HEADERS)           | String            | `cookie,cookies`             | Comma-separated list of headers removed from requests sent by the Enforcer.                                                   |
| [Sensitive routes](#sensitive-routes)                                                    | [`PX_SENSITIVE_ROUTES`](#PX_SENSITIVE_ROUTES)             | String (`RegExp`) | empty                        | Regular expression for routes that always trigger a Risk API call.                                                            |
| [URL-decode reserved characters](#url-decode-reserved-characters)                        | [`PX_DEC_URL_RESERVED_CHARS`](#PX_DEC_URL_RESERVED_CHARS) | Boolean           | `false`                      | Whether the Enforcer decodes reserved URL characters and reparses the request URL before processing.                          |
| [Users identifiers](#users-identifiers)                                                  | [`PX_JWT_COOKIE_NAME`](#PX_JWT_COOKIE_NAME)               | String            | empty                        | Name of the cookie that contains the JWT token.                                                                               |
| [Users identifiers](#users-identifiers)                                                  | [`PX_JWT_COOKIE_USERID_NAME`](#PX_JWT_COOKIE_USERID_NAME) | String            | empty                        | JWT cookie field path that contains the user ID.                                                                              |
| [Users identifiers](#users-identifiers)                                                  | [`PX_JWT_COOKIE_ADDL_FIELDS`](#PX_JWT_COOKIE_ADDL_FIELDS) | String            | empty                        | Comma-separated list of additional JWT cookie fields to extract.                                                              |
| [Users identifiers](#users-identifiers)                                                  | [`PX_JWT_HEADER_NAME`](#PX_JWT_HEADER_NAME)               | String            | empty                        | Name of the header that contains the JWT token.                                                                               |
| [Users identifiers](#users-identifiers)                                                  | [`PX_JWT_HEADER_USERID_NAME`](#PX_JWT_HEADER_USERID_NAME) | String            | empty                        | JWT header field path that contains the user ID.                                                                              |
| [Users identifiers](#users-identifiers)                                                  | [`PX_JWT_HEADER_ADDL_FIELDS`](#PX_JWT_HEADER_ADDL_FIELDS) | String            | empty                        | Comma-separated list of additional JWT header fields to extract.                                                              |

#### Custom functions

| Feature name                                                | Key                                                                                             | Type     | Default | Description                                                                                                                                                        |
| :---------------------------------------------------------- | :---------------------------------------------------------------------------------------------- | :------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Additional activity handler](#additional-activity-handler) | [`px_additional_activity_handler`](#px_additional_activity_handler)                             | Function | `null`  | Custom EdgeWorker function invoked after the async activity (`page_requested` or `block`) is sent to the HUMAN backend.                                            |
| [CORS support](#cors-support)                               | [`px_cors_create_custom_block_response_headers`](#px_cors_create_custom_block_response_headers) | Function | `null`  | Custom EdgeWorker function that returns headers to add to the block response.                                                                                      |
| [Credentials Intelligence](#credentials-intelligence)       | [`extract_credentials_callback`](#extract_credentials_callback)                                 | Function | `null`  | Custom EdgeWorker function that extracts credentials from the request when `sent_through` is `custom`.                                                             |
| [Credentials Intelligence](#credentials-intelligence)       | [`login_successful_callback`](#login_successful_callback)                                       | Function | `null`  | Custom EdgeWorker function that returns whether the login attempt was successful when `login_successful_reporting_method` is `custom`.                             |
| [Custom parameters](#custom-parameters)                     | [`px_enrich_custom_parameters`](#px_enrich_custom_parameters)                                   | Function | `null`  | Custom EdgeWorker function that returns custom parameters (`custom_param1`–`custom_param10`) to add to HUMAN activities.                                           |
| [Enforced routes](#enforced-routes)                         | [`px_custom_is_enforced_request`](#px_custom_is_enforced_request)                               | Function | `null`  | Custom EdgeWorker function that returns whether the request should be enforced.                                                                                    |
| [Filters](#filters)                                         | [`px_custom_is_filtered_request`](#px_custom_is_filtered_request)                               | Function | `null`  | Custom EdgeWorker function that returns whether the request should be filtered.                                                                                    |
| [GraphQL support](#graphql-support)                         | [`px_extract_graphql_keywords`](#px_extract_graphql_keywords)                                   | Function | `null`  | Custom EdgeWorker function that returns keywords extracted from a GraphQL query.                                                                                   |
| [Monitored routes](#monitored-routes)                       | [`px_custom_is_monitored_request`](#px_custom_is_monitored_request)                             | Function | `null`  | Custom EdgeWorker function that returns whether the request should be treated as monitored.                                                                        |
| [Response custom parameters](#response-custom-parameters)   | [`px_enrich_response_custom_parameters`](#px_enrich_response_custom_parameters)                 | Function | `null`  | Custom EdgeWorker function that returns custom parameters (`custom_param11`–`custom_param20`) extracted from the origin response to add to HUMAN async activities. |
| [Sensitive routes](#sensitive-routes)                       | [`px_custom_is_sensitive_request`](#px_custom_is_sensitive_request)                             | Function | `null`  | Custom EdgeWorker function that returns whether the request should be treated as a sensitive route.                                                                |

## Required configurations

These configurations are necessary for the Enforcer's basic functionality and features.

### Basic functionality configurations

**`PX_APP_ID`** `string` — required

Your HUMAN Application ID in the form of `PX12AB34CD`. You can copy this value from the [HUMAN Console](https://console.humansecurity.com/) in **Platform Settings > Applications Overview.** If you have multiple applications, make sure to copy the ID of the application you want the Enforcer on.

---

**`PX_AUTH_TOKEN`** `string` — required

**Security Settings:** Hidden

The application's server token needed to authorize with HUMAN's backend. You can copy this value from the [HUMAN Console](https://console.humansecurity.com/) in **Platform Settings > Applications Overview > Click the appropriate application > Server token tab.**

---

**`PX_COOKIE_SECRET`** `string` — required

**Security Settings:** Hidden

The secret used to encrypt and decrypt the risk cookie sent from the HUMAN Sensor. You can copy this value from the [HUMAN Console](https://console.humansecurity.com/) in **Sightline Cyberfraud Defense > Traffic Policy Overview > Click the appropriate application > Click the key  >  Copy value.**

If you need to rotate secrets, then adjust this configuration to be a comma-separated list of the new cookie secret followed by the old cookie secret. The array size is limited to 2 cookie secrets. For example, `newCooki3Secr3t,0ldCooki3Secr3t`.

---

**`PX_BACKEND_DOMAIN`** `string` — required, default: sapi-\<PX\_APP\_ID>.perimeterx.net

> **Warning**
>
> Do not set this value unless directed by your HUMAN Solutions Engineer.

The base URL for the HUMAN SAPI (**Risk API** and related calls). If empty, the Enforcer uses the default host for your **Application ID**.  Update `<PX_APP_ID>` with your

Application ID

. For example, `sapi-PX12345678.perimeterx.net`.

---

**`PX_S2S_TIMEOUT`** `integer` — required, default: 1000

The total time in milliseconds that the Enforcer will wait for the **Risk API** request to return before timing out and passing the request.

---

### Basic feature configurations

**`PX_LOGGER_SEVERITY`** `"none" | "error" | "debug"` — required, default: "error"

The severity at which the logger will output logs.

* `none`: The logger will not generate any logs.
* `error`:  The logger will only generate logs on fatal errors.
* `debug`: The logger will generate detailed logs for debugging purposes. Not recommended for production environments.

See [`PX_LOGGER_AUTH_TOKEN`](#PX_LOGGER_AUTH_TOKEN) for a header-based alternative.

---

**`PX_IP_HEADERS`** `string` — required, default: empty

An array of header names that are trusted to contain the true client IP. Headers are traversed in the order they're listed, and the first header value will always be used as the client IP.

Taken from [`AK_CLIENT_REAL_IP`](https://techdocs.akamai.com/property-mgr/docs/built-vars) variable by default.

For example, `true-ip,true-client-ip`.

---

**`PX_MODULE_ENABLED`** `boolean` — required, default: true

Whether the Enforcer module is enabled.

* `true`: Enable the module
* `false`: Disable  the module

---

**`PX_MODULE_MODE`** `"monitor" | "active_blocking"` — required, default: monitor

The Enforcer's operation mode.

* `monitor`: The Enforcer performs all functions without returning block responses. Useful for analyzing and adjusting Enforcer behavior without serving block pages to end users. If you have routes that must have enforcement at all times, see [Enforced routes](#enforced-routes).
* `active_blocking`: The Enforcer will return block responses as needed.

---

## Optional configurations

These configurations aren't required, but you can use them to further customize the Enforcer's behavior.

### Advanced blocking response (ABR)

**`PX_ABR_ENABLED`** `boolean` — default: true

In specific cases such as XHR post requests, a full CAPTCHA page render might not be an option. In such cases, the [Advanced Blocking Response (ABR)](/applications/set-challenge-configurations#enable-challenge-configurations#custom-abr) returns a JSON object containing all the information needed to render a customized CAPTCHA challenge implementation such as a popup modal, a section on the page, etc. This provides more flexibility and customizability in displaying the CAPTCHA challenge.

* `true`: Enable ABR
* `false`: Disable ABR

---

### Bypass monitor header

**`PX_BYPASS_MONITOR_HEADER`** `string` — default: x-px-block

Activates the full blocking flow to verify the flow works as expected if the specified header is present on the request with a value of `1`. Often used to test the Enforcer block workflow during [monitor mode](#PX_MODULE_MODE), where the Enforcer usually collects data without blocking user requests, before switching to `active_blocking`. Requests with this header will go through the entire blocking workflow despite being in monitor mode.

To disable blocking behavior on the specified header, set the value to `0`.

---

### Credentials Intelligence

These configurations let you extract and detect compromised credentials. They're closely related to [Credentials Intelligence-related features](/applications/about-the-credentials-intelligence-dashboard) in Sightline Cyberfraud Defense.

At minimum, ensure the following are configured to enable Credential Intelligence:

* [`PX_CI_EXTRACT_ENABLED`](#PX_CI_EXTRACT_ENABLED) is set to `true`
* [`PX_CI_EXTRACT_DETAILS`](#PX_CI_EXTRACT_DETAILS) is configured with at least one credential endpoint

**`PX_CI_EXTRACT_ENABLED`** `boolean` — default: false

Whether to enable the extraction and reporting of credentials from the Enforcer for Credential Intelligence.

* `true`: Enable Credential Intelligence
* `false`: Disable Credential Intelligence

---

**`PX_CI_EXTRACT_DETAILS`** `object`

> **Note**
>
> The `HumanSecurityFunctionsConfiguration` object defined within the Akamai EdgeWorker code also includes a `px_login_credentials_extraction` field for defining login endpoints that require custom logic for extracting credentials or determining login success.
>
> Each configuration endpoint should be defined once, either in the EdgeWorker with `px_login_credentials_extraction` if custom functions must be implemented, or in the Property Manager with `PX_CI_EXTRACT_DETAILS` if custom functions aren't needed.
>
> Regardless, all paths and methods for all credential extraction endpoints must be accounted for in the `PXSetCIBypassResponseProviderRule`.

An array of configuration objects for each credential endpoint. Each element in the array is an object representing a distinct endpoint to which credentials are sent and includes:

* How to identify these credential-bearing requests
* How to extract the credentials from the request
* How to determine if the request operation (login, signup, etc.) was successful based on the returned HTTP response

Click to expand the full properties list.

#### Properties

**`path`** `string` — required

The path of the request that contains the credentials. It can be either an exact path or a string in the form of a regular expression.

The `path` values in the `PX_CI_EXTRACT_DETAILS` array must match the list of paths configured in the Property Manager rule named `PXSetCIBypassResponseProviderRule`.

**`Example`**

```json Example
{
    // ...
    path: '/sign-up',
    // ...
}
```

---

**`path_type`** `"exact" | "regex"` — default: "exact"

Whether the incoming request path should be evaluated against the configured path as a regular expression or as an exact match.

* `exact`: The value set in `path` must match the request path exactly as is.
* `regex`: The value set in `path` is a regular expression to be matched against the request path.

**`Example`**

```json Example
{
    // ...
    path: '/auth/[A-Za-z0-9]{12}/login',
    path_type: 'regex',
    // ...
}
```

---

**`method`** `string` — required

The HTTP method of the request that contains the credentials. This can be set to any string representing an HTTP method.

**`Example`**

```json Example
{
    // ...
    method: 'POST',
    // ...
}
```

---

**`sent_through`** `"body" | "header" | "query-param" | "custom"` — required

Whether the credentials should be extracted from the request headers, query parameters, body, or via a defined custom callback.

* `"body"`: The credentials will be extracted according to the configured [`user_field`](#user_field) and [`pass_field`](#pass_field) values from the request body. The Enforcer parses the request body based on the following `Content-Type` request header:
  * `application/json`
  * `application/x-www-form-urlencoded`
  * `multipart/form-data`
* `"header"`: The credentials will be extracted according to the configured [`user_field`](#user_field) and [`pass_field`](#pass_field) values from the request headers.
* `"query-param"`: The credentials will be extracted according to the configured [`user_field`](#user_field) and [`pass_field`](#pass_field) values from the request query parameters.
* `"custom"`: The credentials will be extracted by invoking [`extract_credentials_callback`](#extract_credentials_callback).

**`Example`**

```json Example
{
    // ...
    sent_through: 'body',
    // ...
}
```

---

**`user_field`** `string`

**Required** if [`sent_through`](#sent_through) is set to `"body"`, `"header"`, or `"query-param"`. The name of the field containing the username in the request body, headers, or query parameters.

Supports subfields in cases of `Content-Type: application/json` bodies with nested objects. The subfields can be separated with periods. For example, the credential endpoint configuration object can include a `user_field` with the value `"user_info.username"` and a `pass_field` with the value `"authentication.password"` to support extracting the credentials.

**`Basic example`**

```json Basic example
{
    // ...
    sent_through: 'body',
    user_field: 'username',
    // ...
}
```

**`Subfields example`**

```json Subfields example
{
    "user_info": {
        "username": "user123"
    },
    "authentication": {
        "password": "P@s$w0rD!"
    }
}

```

---

**`pass_field`** `string`

**Required** if [`sent_through`](#sent_through) is set to `"body"`, `"header"`, or `"query-param"`. The name of the field, header name, or query parameter where the password can be found.

Supports subfields in cases of `Content-Type: application/json` bodies with nested objects. The subfields can be separated with periods. For example, the credential endpoint configuration object can include a `user_field` with the value `"user_info.username"` and a `pass_field` with the value `"authentication.password"` to support extracting the credentials.

**`Basic example`**

```json Basic example
{
    // ...
    sent_through: 'body',
    user_field: 'username',
    // ...
}
```

**`Subfields example`**

```json Subfields example
{
    "user_info": {
        "username": "user123"
    },
    "authentication": {
        "password": "P@s$w0rD!"
    }
}
```

---

**`protocol`** `"v2" | "multistep_sso" | "both"` — default: "both"

Whether to process credentials as part of single or multiple HTTP requests. By default, the module tries to process requests depending on which credential fields were extracted.

* `"v2"`: Both username and password are present on the same HTTP request and must be extracted successfully to trigger Credential Intelligence.
* `"multistep_sso"`: The username and password are delivered on different HTTP requests. Either the username or password, but not both, must be extracted successfully to trigger Credential Intelligence.
* `"both"`: The username and password may be present on the same HTTP request or on different HTTP requests. If either username or password is successfully extracted, the Enforcer will send the credentials according to the multistep\_sso protocol. If both username and password are successfully extracted, the Enforcer will send the credentials according to the v2 protocol.

**`Example`**

```ts Example
{
    // ...
    protocol: 'v2',
    // ...
}
```

---

**`login_successful_reporting_method`** `"status" | "body" | "header" | "custom"` — required, default: status

The method by which the Enforcer will determine whether the login request was successful.

* `"status"`: The Enforcer will determine if the login request was successful by evaluating the response status code against the [`login_successful_statuses`](#login_successful_statuses) configuration.
* `"body"`: The Enforcer will determine if the login request was successful by evaluating the response body content against the [`login_successful_body_regex`](#login_successful_body_regex) configuration.
* `"header"`: The Enforcer will determine if the login request was successful by evaluating the response headers against the [`login_successful_header_name`](#login_successful_header_name) and [`login_successful_header_value`](#login_successful_header_value) configurations.
* `"custom"`: The Enforcer will determine if the login request was successful by invoking [`login_successful_callback`](#login_successful_callback).

**`Example`**

```ts Example
{
    // ...
    login_successful_reporting_method: 'status',
    // ...
}
```

---

**`login_successful_statuses`** `integer[]` — default: \[200]

An array of HTTP statuses signifying a successful login. All other status codes will be treated as unsuccessful login attempts. Takes effect only when the [`login_successful_reporting_method`](#login_successful_reporting_method) is set to `"status"`.

**`Example`**

```ts Example
{
    // ...
    login_successful_reporting_method: 'status',
    login_successful_statuses: [200, 202],
    // ...
}
```

---

**`login_successful_body_regex`** `string`

**Required** if [`login_successful_reporting_method`](#login_successful_reporting_method) is set to `"body"`. A regular expression (or string representing a regular expression) to against which the response body will be evaluated. A match indicates a successful login.

**`Example`**

```ts Example
{
    // ...
    login_successful_reporting_method: 'body',
    login_successful_body_regex: 'Welcome, [A-Za-z0-9_]+!'
    // ...
}
```

---

**`login_successful_header_name`** `string`

**Required** if [`login_successful_reporting_method`](#login_successful_reporting_method) is set to `"header"`. A response header name signifying a successful login response. If the [`login_successful_header_value`](#login_successful_header_value) field is empty or not configured, any response containing this header name will be considered a successful login. If the [`login_successful_header_value`](#login_successful_header_value) is configured, the response header value must be an exact match.

**`Example`**

```ts Example
{
    // ...
    login_successful_reporting_method: 'header',
    login_successful_header_name: 'x-login-successful'
    // ...
}
```

---

**`login_successful_header_value`** `string`

If this value is configured, a login attempt will be considered successful only if the response contains a header name matching the [`login_successful_header_name`](#login_successful_header_name), and whose value is exactly equal to this configuration value. Takes effect only when the [`login_successful_reporting_method`](#login_successful_reporting_method) is set to `"header"`.

**`Example`**

```ts Example
{
    // ...
    login_successful_reporting_method: 'header',
    login_successful_header_name: 'x-user-status',
    login_successful_header_value: 'logged-in'
    // ...
}
```

---

---

**`PX_CI_COMPROMISED_HEADER`** `string` — default: px-compromised-credentials

The header name to be set on the incoming request if the credentials are compromised. If this header is added, its value will always be `1`. If credentials have not been identified as compromised, the header will not be added to the request.

---

**`PX_CI_AS2S_HEADER_ENABLED`** `boolean` — default: false

Whether to attach the `additional_s2s` payload and URL as headers to the original request. This is done so that the `additional_s2s` activity can be enriched with the proper `login_successful` value and sent to the provided URL at a later stage.  Enabling this configuration disables automatic sending of `additional_s2s` activity.

When set to `true`, the following headers are added to the origin request:

* `px-additional-activity`: A JSON object containing the payload of the `additional_s2s` activity. The `login_successful` and `http_status_code` fields should be set prior to sending the activity.
* `px-additional-activity-url`: The URL to which the `additional_s2s` payload should be sent as an HTTP POST request.

**`Example to handle additional_s2s at the origin`**

```js Example to handle additional_s2s at the origin
app.post('/login', (req, res) => {
    // handle login flow, resulting in variables
    // isLoginSuccessful (boolean) and responseStatusCode (number)

    if (
        req.headers['px-additional-activity'] &&
        req.headers['px-additional-activity-url']
    ) {
        handlePxAdditionalActivity(req, responseStatusCode, isLoginSuccessful);
    }
});

function handlePxAdditionalActivity(req, statusCode, isLoginSuccessful) {
    try {
        // extract url and activity from the request headers
        const url = req.headers['px-additional-activity-url'];
        const activity = JSON.parse(req.headers['px-additional-activity']);

        // enrich the activity details with added information
        activity.details['http_status_code'] = statusCode;
        activity.details['login_successful'] = isLoginSuccessful;

        if (activity.details['credentials_compromised'] && isLoginSuccessful) {
            // add raw username if credentials are compromised and login is successful (only if desired)
            activity.details['raw_username'] = req.body.username;
        } else {
            // remove raw username if login is not successful or credentials are not compromised
            delete activity.details['raw_username'];
        }

        // send the POST request
        axios.post(url, activity, {
            headers: {
                'Authorization': `Bearer ${env.PX_AUTH_TOKEN}`,
                'Content-Type': 'application/json'
            }
        });
    } catch (err) {
        console.error(`Error: ${err}`);
    }
}
```

---

**`PX_CI_SEND_RAW_USERNAME`** `boolean` — default: false

Whether to report the raw username on the `additional_s2s` activity.

* `false`: The raw username will never be reported.
* `true`: The raw username will only be reported if:
  * The credentials are compromised, and
  * The login request was successful.

---

**`PX_CI_LS_REPORTING_METHOD`** `"status" | "body" | "header" | "custom"` — deprecated, default: status

> **Warning**
>
> This configuration is deprecated. Use [`PX_CI_EXTRACT_DETAILS.login_successful_reporting_method`](#login_successful_reporting_method) instead.

The default login-success detection method applied to endpoints that don't override it. See [`login_successful_reporting_method`](#login_successful_reporting_method) for the possible values.

---

**`PX_CI_LS_STATUS`** `integer[]` — deprecated, default: 200

> **Warning**
>
> This configuration is deprecated. Use [`PX_CI_EXTRACT_DETAILS.login_successful_statuses`](#login_successful_statuses) instead.

The default HTTP status codes that indicate a successful login. This takes effect when the [`PX_CI_LS_REPORTING_METHOD`](#PX_CI_LS_REPORTING_METHOD) is set to `status`.

---

**`PX_CI_LS_BODY_REGEX`** `string` — deprecated

> **Warning**
>
> This configuration is deprecated. Use [`PX_CI_EXTRACT_DETAILS.login_successful_body_regex`](#login_successful_body_regex) instead.

The default body regular expression that indicates a successful login. This takes effect when the [`PX_CI_LS_REPORTING_METHOD`](#PX_CI_LS_REPORTING_METHOD) is set to `body`.

---

**`PX_CI_LS_HEADER_NAME`** `string` — deprecated

> **Warning**
>
> This configuration is deprecated. Use [`PX_CI_EXTRACT_DETAILS.login_successful_header_name`](#login_successful_header_name) instead.

The default response header name that indicates a successful login. This takes effect when the [`PX_CI_LS_REPORTING_METHOD`](#PX_CI_LS_REPORTING_METHOD) is set to `header`.

---

**`PX_CI_LS_HEADER_VALUE`** `string` — deprecated

> **Warning**
>
> This configuration is deprecated. Use [`PX_CI_EXTRACT_DETAILS.login_successful_header_value`](#login_successful_header_value) instead.

The default response header value that indicates a successful login. This takes effect when the [`PX_CI_LS_REPORTING_METHOD`](#PX_CI_LS_REPORTING_METHOD) is set to `header`.

---

**`PX_CI_VERSION`** `"v2" | "multistep_sso" | "both"` — deprecated, default: both

> **Warning**
>
> This configuration is deprecated. Use [`PX_CI_EXTRACT_DETAILS.protocol`](#protocol) instead.

The default credential hashing protocol applied to endpoints that do not specify a [`protocol`](#protocol) field.

* `"v2"`: Both username and password are present on the same HTTP request and must be extracted successfully to trigger Credential Intelligence.
* `"multistep_sso"`: The username and password are delivered on different HTTP requests. Either the username or password, but not both, must be extracted successfully to trigger Credential Intelligence.
* `"both"`: The username and password may be present on the same HTTP request or on different HTTP requests. If either username or password is successfully extracted, the Enforcer will send the credentials according to the multistep\_sso protocol. If both username and password are successfully extracted, the Enforcer will send the credentials according to the v2 protocol.

---

### CORS support

You can configure the Enforcer to support Cross-Origin Resource Sharing (CORS) requests. CORS is a mechanism that lets the server indicate if a request contains cross-origin resources by adding special HTTP headers to the request. These headers let the browser load these resources. Without them, the browser may block requests to these resources for security reasons instead.

In most cases, CORS employs a two-stage procedure with a preliminary “preflight” request followed by the actual request. The preflight request checks if the actual request will be responded to. To learn more about different request types, see these [examples](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#examples_of_access_control_scenarios).

You must configure the Enforcer to address both simple requests (without preflight) and more complex ones (with preflight) to support CORS requests.

See [CORS support](#cors-support-custom-functions) for custom function options.

**`PX_CORS_SUPPORT_ENABLED`** `boolean` — default: false

> **Note**
>
> Since [Akamai EdgeWorkers don't support the OPTIONS method](https://techdocs.akamai.com/edgeworkers/docs/event-handler-functions#event-handler-methods), CORS preflight requests are always filtered and won't pass through the EdgeWorker. Therefore, you must handle preflight requests elsewhere in your Akamai Property Manager or in your origin server.

Whether to enable CORS support.

* `true`: Enable CORS support
* `false`: Disable CORS support

After setting this configuration to `true`, the Enforcer:

* Automatically adds the following default CORS response headers to block responses resulting from CORS requests.
  ```
  Access-Control-Allow-Origin: <ORIGIN_REQUEST_HEADER_VALUE>  
  Access-Control-Allow-Credentials: true
  ```
* Activates the [`px_cors_create_custom_block_response_headers`](#px_cors_create_custom_block_response_headers) configuration, which lets you customize the block response headers via a custom function.

---

### Custom cookie header

**`PX_CUSTOM_COOKIE_HEADER`** `string` — default: x-px-cookies

By default, the Enforcer extracts HUMAN cookies from the `Cookie` header. However, if these cookies are transferred on a different header, then that header's name must be provided with this configuration.

---

### Enforced routes

These configurations let you define specific routes that should be enforced by HUMAN when the Enforcer is in [monitor mode](#PX_MODULE_MODE). These routes will always be subject to the full Enforcer workflow, including blocking requests if necessary.

Primitive string values are treated as path prefixes. For example, `/login` also matches `/login/callback`.

See [Enforced routes](#enforced-routes-custom-functions) for custom function options.

**`PX_ENFORCED_ROUTES`** `string` — default: empty

Routes or prefixes that should be enforced by HUMAN even when the Enforcer is in [monitor mode](#PX_MODULE_MODE).

Routes must be configured as a single regular expression (`RegExp`). For case-insensitive matching, the end the regex with the `i` flag.

---

### Filters

These configurations let you filter out certain requests or assets from the Enforcer. These values will be ignored by the Enforcer and will never be blocked.

See [Filters](#filters-custom-functions) for custom function options.

**`PX_FILTER_BY_EXTENSION`** `string` — default: .css,.bmp,.tif,.ttf,.docx,.woff2,.js,.pict,.tiff,.eot,.xlsx,.jpg,.csv,.eps,.woff,.xls,.jpeg,.doc,.ejs,.otf,.pptx,.gif,.pdf,.swf,.svg,.ps,.ico,.pls,.midi,.svgz,.class,.png,.ppt,.mid,.webp,.jar,.json,.xml

> **Note**
>
> Must match those configured in the `PXWorkerRule` and `PXStaticContentWorkerRule` in the Akamai Property Manager.

Filters out requests with the specified file extension. By default, HUMAN doesn't enforce static assets such as images and documents to minimize unncessary API calls and computation, but you can configure this list at any time.

> **Note**
>
> Filtering by extension only applies to GET and HEAD HTTP methods.

Configure as a comma-separated list.

---

**`PX_FILTER_BY_HTTP_METHOD`** `string` — default: HEAD,TRACE

> **Note**
>
> To avoid invoking the Akamai EdgeWorker in its entirety for these HTTP methods, you can also implement this by editing the `PXWorkerRule` in the Property Manager. Under the **Criteria** section, add another match as follows:
>
> * **Request Method:** Request Method
> * **Operator:** is not
> * **Value:** The HTTP methods you want to filter out (e.g. HEAD, TRACE)

Filters out requests with the specified HTTP method to avoid unnecessary traffic in the Enforcer verification flow. Configure as a comma-separated list.

---

**`PX_FILTER_BY_IP`** `string` — default: empty

Filters out requests with the specified IP address to avoid unnecessary traffic in the Enforcer verification flow. Configure IPs or CIDR ranges as a comma-separated list (for example, `1.1.1.1,2.2.2.2/8`).

---

**`PX_FILTER_BY_ROUTE`** `string` — default: empty

Filters out requests with the specified route to avoid unnecessary traffic in the Enforcer verification flow. Requests to these specified routes will never be blocked regardless of their **risk score** and will never generate risk or async activities. Primitive string values are treated as path prefixes. For example, `/login` also matches `/login/callback`. Routes must be configured as a single regular expression (`RegExp`). For case-insensitive matching, the end the regex with the `i` flag (for example, `/^(./allowed_route/?.)|(./filtered_route/?.)$/i`).

---

**`PX_FILTER_BY_USER_AGENT`** `string` — default: empty

Filters out requests with the specified user agent to avoid unnecessary traffic in the Enforcer verification flow. Primitive string values are case-sensitive and require an exact user-agent string. User agents must be configured as a single regular expression (`RegExp`). For case-insensitive matching, the end the regex with the `i` flag (for example, `/^(filtered-ua)|(filtered-user-agent)$/`).

---

### First party

These configurations let you use the Enforcer as a proxy for HUMAN servers and serve content to the browser from a first party endpoint. These are particularly useful when browser or extension restrictions that block JavaScript requests to other domains, such as adblockers, prevent the HUMAN **Sensor** from making requests to HUMAN's backend. When this happens, it significantly limits HUMAN's detection capabilities, so we recommend enabling these configurations to maintain full detection capabilities.

**`PX_FIRST_PARTY_ENABLED`** `boolean` — default: true

Whether to enable first party mode for Bot Defender or Sightline Cyberfraud Defense.

---

### GraphQL support

These configurations let the Enforcer extract [GraphQL](https://graphql.org/learn/) data from requests so that it can enforce these requests in the same way as other types of traffic.

See [GraphQL support](#graphql-support-custom-functions) for custom function options.

**`PX_GRAPHQL_ENABLED`** `boolean` — default: true

Whether to parse and report information about GraphQL operations on incoming requests. When `true`, all POST requests with routes that match the prefixes configured in [`PX_GRAPHQL_ROUTES`](#PX_GRAPHQL_ROUTES) will have their bodies parsed for GraphQL operations.

* `true`: Enable GraphQL support
* `false`: Disable GraphQL support

---

**`PX_GRAPHQL_ROUTES`** `string` — default: /^/graphql\$/i

> **Note**
>
> Must match those configured in the `PXSetGraphqlBypassResponseProviderRule` in the Akamai Property Manager.

A regular expression that matches all routes that should be considered GraphQL routes. If [`PX_GRAPHQL_ENABLED`](#PX_GRAPHQL_ENABLED) is `true`, all `POST` requests with routes that match the configured regex will have their bodies parsed for GraphQL operations. For case-insensitive matching, the regex should end with the `i` flag.

---

**`PX_SENSITIVE_GQL_OP_NAMES`** `string` — default: empty

A regular expression (`RegExp`) of operation names that should be considered sensitive. Some routes may be more prone to bot attacks than others, such as routes that execute payments or handle personal information. You can configure these routes as sensitive to ensure a more stringent protection.

If one or more GraphQL operations has a name or keyword matching this regular expression (`RegExp`), the Enforcer will trigger a **Risk API** call even if the request contains a valid, unexpired cookie. Matches against extracted GraphQL words from:

* [`PX_GRAPHQL_KEYWORDS`](#PX_GRAPHQL_KEYWORDS) configuration
* [`px_extract_graphql_keywords`](#px_extract_graphql_keywords) configuration

For case-insensitive matching, the regex should end with the `i` flag. For example, `/^(LoginOperation|SignIn)$/i`.

---

**`PX_SENSITIVE_GQL_OP_TYPES`** `query | mutation | subscription` — default: empty

A comma-separated list of operation types that should be considered sensitive. Some routes may be more prone to bot attacks than others, such as routes that execute payments or handle personal information. You can configure these routes as sensitive to ensure a more stringent protection.

If one or more GraphQL operations on an HTTP request has a type matching this list, the Enforcer will trigger a **Risk API** call even if the request contains a valid, unexpired cookie.

---

**`PX_GRAPHQL_KEYWORDS`** `string` — default: empty

A regular expression (`RegExp`) of keywords to identify important terms from GraphQL operation queries. These keywords are used to determine the purpose of the operation (such as login, checkout, or search) and can also be used to specify which operations should be considered sensitive. Any matching patterns will be extracted and reported to HUMAN. See [`PX_SENSITIVE_GQL_OP_NAMES`](#PX_SENSITIVE_GQL_OP_NAMES) for more information. See [`px_extract_graphql_keywords`](#px_extract_graphql_keywords) for an alternative using a custom function.

For case-insensitive matching, the regex should end with the `i` flag. For example, `/(\w*[Ll]ogin\w*)|(\w*[Ss]ignup\w*)/i`.

---

### Header data enrichment

These configurations let you add headers to incoming requests with additional data.

**`PX_DE_HEADER_NAME`** `string` — default: ""

Adds a header to the incoming request with the configured header name and the JSON-stringified data enrichment object as the value. If empty or if data enrichment has not been enabled for your policy, no header will be set. To view available data and enable this feature, see [Data classification enrichment](/applications/data-classification-enrichment).

---

### HUMAN Challenge & hard block customization

These configurations let you customize the [HUMAN Challenge block page](/applications/create-a-human-challenge) as well as the hard block page, which appears when a request is blocked without a Challenge. They cannot be set separately. The pages use different markup, so Challenge Editor JavaScript and Challenge-specific CSS do not restyle the hard block page. [`PX_CUSTOM_LOGO`](#PX_CUSTOM_LOGO) appears on both.

> **Note**
>
> Hard block pages load `b.js` from NetStorage using the same `/pxns/*` path as `c.js`. [Update to the latest version](/applications/general/deploy-tool#update-an-enforcer-version) to upload it into your directory. Without it, hard-blocked visitors can receive a blank Access Denied page.

The Enforcer requires HUMAN Challenge and hard block responses to stay within 2048 characters. `PX_CSS_REF`, `PX_JS_REF`, and `PX_CUSTOM_LOGO` are inserted into that HTML. Keep the three URLs to 150 characters combined so Challenge responses, especially on mobile, stay within the limit. If the generated page is larger than 2048 characters, the Enforcer does not block the request.

**`PX_CSS_REF`** `string`

A way to include a custom CSS file to the block page.

Provide the URL of the custom CSS file.

---

**`PX_JS_REF`** `string`

A way to include custom JavaScript to the block page. This script will run after the default JavaScript scripts.

Provide the URL of the custom JavaScript file.

The default Challenge (`c.js`) and hard block (`b.js`) scripts load asynchronously from NetStorage, so this script may run before the default page content exists.

---

**`PX_CUSTOM_LOGO`** `string` — default: ""

Adds a custom logo to the [HUMAN Challenge](/applications/create-a-human-challenge) block page via URL.

---

### Monitored routes

These configurations let you specify routes that should be monitored by the Enforcer, which means their requests will never be blocked, even when the Enforcer is in [`active_blocking`](#PX_MODULE_MODE) mode. This means that these routes will go through the full Enforcer workflow and generate risk and async activities, but all block activities will only be simulated blocks on these routes.

Primitive string values are treated as path prefixes. For example, `/login` also matches `/login/callback`.

See [Monitored routes](#monitored-routes-custom-functions) for custom function options.

**`PX_MONITORED_ROUTES`** `string` — default: empty

A regular expression (`RegExp`) of endpoints to be monitored rather than blocked by the Enforcer, even when the Enforcer is in [`active_blocking`](#PX_MODULE_MODE) mode.  For case-insensitive matching, the regex should end with the `i` flag. For example, `/^(./category/?.)|(./product/?.)$/i`.

---

### PXHD cookie

**`PX_SECURED_PXHD_ENABLED`** `boolean` — default: false

The PX Hashed Data (PXHD or `_pxhd`) cookie links the first risk request with the browser activities as detected by the **Sensor** for better user tracking. It can also add more information that's shared between the HUMAN Collector, Enforcer, and Sensor. This configuration determines whether the [`Secure` cookie attribute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies#block_access_to_your_cookies) is added when setting the PXHD cookie.

See [Use of cookies & web storage](/applications/use-of-cookies-web-storage) for more information.

* `true`: Adds the `Secure` attribute to the PXHD cookie
* `false`: Does not add the `Secure` attribute to the PXHD cookie

---

### Remote Configuration

Remote Configuration lets you update your Enforcer's configuration from the HUMAN portal rather than interacting with the Enforcer package directly.

> **Note**
>
> Remote Configuration requires access to [Akamai EdgeKV](https://techdocs.akamai.com/edgekv/docs/welcome-to-edgekv) and adding the [EdgeKV helper library](https://techdocs.akamai.com/edgekv/docs/download-the-helper-library-1) to your Akamai EdgeWorker.

**`PX_LOGGER_AUTH_TOKEN`** `string` — required, default: empty

An alternative to the [basic logger](#PX_LOGGER_SEVERITY) configuration. This sends Enforcer logs to HUMAN's logging service if a specific header is present on the request. This is particularly useful for expedited debugging, diagnosis, and resolution of any integration or Enforcer-related issues.

[Contact HUMAN](/applications/human-customer-support) to receive your token.

**Security Settings:** Hidden

---

**`PX_RC_AUTH_TOKEN`** `string` — required, default: empty

The token used to authenticate the Enforcer with the HUMAN Remote Configuration service.

[Contact HUMAN](/applications/human-customer-support) to receive your token.
**Security Settings:** Hidden

---

**`PX_RC_ID`** `string` — required, default: empty

The ID associated with the Remote Configuration.

[Contact HUMAN](/applications/human-customer-support) to receive your ID.

---

**`PX_RC_MAX_FETCH_ATTEMPTS`** `integer` — default: 5

The maximum number of time to attempt to fetch the Remote Configuration. If the Enforcer fails to fetch the Remote Configuration after the specified maximum, it will use the last known configuration.

---

**`PX_RC_RETRY_INTERVAL`** `integer` — default: 1000

The interval time in milliseconds to wait between attempts to fetch the Remote Configuration.

---

### Sensitive headers removal

**`PX_SENSITIVE_HEADERS`** `string` — default: cookie,cookies

Specifies certain headers that should not be forwarded to any other destination, including the HUMAN **Detector**. While HUMAN's detection system will continue to use these headers to determine whether to block or not, the specified headers won't be forwarded from the Enforcer, won't appear in Enforcer activities, and won't be sent to any other IP if the Enforcer acts as a proxy.  Should be configured as a comma-separated list of header names.

---

### Sensitive routes

These configurations let you specify certain routes that need particularly stringent protection from attacks, such as endpoints that execute payments or handle personal information. Sensitive routes will always trigger a **Risk API** call even if the request contains a valid, unexpired, low-score cookie.

Primitive string values are treated as path prefixes. For example, `/login` also matches `/login/callback`.

> **Note**
>
> Requests with high-score cookies won't send a Risk API call.

See [Sensitive routes](#sensitive-routes-custom-functions) for custom function options.

**`PX_SENSITIVE_ROUTES`** `string` — default: empty

A regular expression (`RegExp`) of prefixes for all routes that should be considered sensitive.

For case-insensitive matching, the regex should end with the `i` flag. For example, `/^(/login/.*)|(/sign/)$/i`.

---

### URL-decode reserved characters

**`PX_DEC_URL_RESERVED_CHARS`** `boolean` — default: false

When `true`, the Enforcer will decode [reserved characters](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2) such as `%3F` and `%2F` in the request URL path prior to processing. In other words, the Enforcer will treat the URIs `/login%3F.ico` and `/login?.ico` as equivalent. By default, the Enforcer doesn't decode reserved characters and treats these URLs separately.

* `true`: Decode reserved characters in the request URL.
* `false`: Do not decode reserved characters in the request URL.

---

### Users identifiers

These configurations let you extract user identifiers from a JWT carried on the request either in a cookie or a header. They're closely related to the [Accounts](/applications/about-the-accounts-overview-dashboard) and [Account Takeover or Fake Account](/applications/about-the-recent-attacks-dashboard) features in Sightline Cyberfraud Defense.

The Enforcer reads the JWT from the configured cookie first, then from the configured header if cookie extraction does not succeed. Field names support dot notation for nested JWT claim (for example, `product.id`).

**`PX_JWT_COOKIE_NAME`** `string` — default: empty

The name of the cookie that contains the JWT token that HUMAN should extract user identifiers from. For example, `auth`.

---

**`PX_JWT_COOKIE_USERID_NAME`** `string` — default: empty

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted and reported. For example, `nameID`.

---

**`PX_JWT_COOKIE_ADDL_FIELDS`** `string` — default: empty

The field names in the JWT object, extracted from the JWT cookie, that should be extracted and reported in addition to the user ID. The field names should be configured as a comma-separated list. For example, `exp,iss`.

---

**`PX_JWT_HEADER_NAME`** `string` — default: empty

The name of the header that contains the JWT token that HUMAN should extract user identifiers from. For example, `x-jwt-authorization`.

---

**`PX_JWT_HEADER_USERID_NAME`** `string` — default: empty

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted and reported. For example, `sub`.

---

**`PX_JWT_HEADER_ADDL_FIELDS`** `string` — default: empty

The field names in the JWT object, extracted from the JWT header, that should be extracted and reported in addition to the user ID. The field names should be configured as a comma-separated list. For example, `exp,iss`.

---

## Custom functions

Some supported features can't be expressed as Akamai Property Manager variables. Instead, you can define custom functions in the `HumanSecurityFunctionsConfiguration` object directly within the Akamai EdgeWorker code. This should be done in `example/src/customFunctions.ts` or the equivalent source file used for bundling.

> **Warning**
>
> Do not add custom functions post-build to the compiled Worker output.

These functions may be invoked during the `onClientRequest`, `onClientResponse`, or `responseProvider` events. Since the request and response objects vary in structure between events, we strongly recommend performing runtime checks for the existence of properties and methods before accessing them directly.

Refer to Akamai's documentation for [request methods](https://techdocs.akamai.com/edgeworkers/docs/request-object#methods) and [response methods](https://techdocs.akamai.com/edgeworkers/docs/response-object#methods) for available events.

### Additional activity handler

**`px_additional_activity_handler`** `function` — default: null

A custom function passed to the Enforcer that runs after sending `page_requested` or `block` activity to the Collector and before forwarding the request to the next step in the pipeline. A common use case is to set the score as a variable or header. Then the application can read the score and do what is defined within the application’s logic.

> **Warning**
>
> The request body can only be read once! If you plan on reading the request body in this function, we recommend you use the `HumanSecurityUtils.getRequestBody()` function to read the request body safely.

**Parameters:**

* `config: HumanSecurityConfiguration`
* `context: IContext`
* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** `void` or a Promise resolving to `void`

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_additional_activity_handler: (
        config: HumanSecurityConfiguration,
        context: IContext,
        request: EW.IngressClientRequest | EW.ResponseProviderRequest
    ): void => {
        if ('setHeader' in request) {
            request.setHeader('x-px-score', `${context.score}`);
            request.setHeader('x-px-rtt', `${context.riskApiData.riskRtt}`);
        }
    },
    // ...
}
```

---

### CORS support \[#cors-support-custom-functions]

See [CORS support](#cors-support) for Property Manager options.

**`px_cors_create_custom_block_response_headers`** `function` — default: null

If the default CORS response headers are not sufficient, you can use this configuration to customize the headers that should be added to all block responses resulting from CORS requests. If this function is defined, the default headers will **not** be added. Only those headers specified in the returned object will be added to the block response.

**Parameters:**

* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** An object of the type `Record<string, string[]>` or a Promise resolving to this type

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_cors_create_custom_block_response_headers: (
        request: EW.IngressClientRequest | EW.ResponseProviderRequest,
    ): Record<string, string[]> => {
        return {
            'Access-Control-Allow-Origin': [request.getHeader('origin')?.[0] ?? '*'],
            'Access-Control-Allow-Credentials': ['false'],
            'Access-Control-Allow-Methods': ['GET', 'POST', 'PUT'],
            'X-Custom-Header': ['1']
        };
    },
    // ...
}
```

---

### Credentials Intelligence \[#credentials-intelligence-custom-functions]

See [Credentials Intelligence](#credentials-intelligence) for Property Manager options.

**`extract_credentials_callback`** `function`

**Required** if [`sent_through`](#sent_through) is set to `"custom"`. A custom credential extraction callback that returns the raw credentials from the request. It receives the HTTP request as a parameter and should return a Credentials object:

**`Credentials object example`**

```json Credentials object example
type Credentials = {
    user?: string;  // the raw username
    pass?: string;  // the raw password
};
```

**Parameters:**

* `request:` [EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** A Credentials object or a Promise resolving to a Credentials object. If neither the username or the password can be extracted from the request, the function should return `null`.

> **Warning**
>
> The request body can only be read once! If you plan on reading the request body in this function, we recommend you use the `HumanSecurityUtils.getRequestBody()` function to read the request body safely.

**`Example`**

```ts Example
{
    // ...
    sent_through: 'custom',
    extract_credentials_callback: async (request: EW.ResponseProviderRequest): Promise<{ user?: string; pass?: string; }> => {
        const body: string | undefined = await HumanSecurityUtils.getRequestBody(request);
        
        // custom logic to extract credentials from the request body
        
        if (!username || !password) {
            return null;
        }
        return { user: username, pass: password };
    },
    // ...
}
```

---

**`login_successful_callback`** `function`

**Required** if [`login_successful_reporting_method`](#login_successful_reporting_method) is set to `"custom"`. A custom callback that accepts the HTTP response and returns a boolean or Promise resolving to a boolean that indicates whether the login attempt was successful.

**Parameters:**

* `response:` `{ status: number; headers: Record<string, string[]>; body: any }`

**Returns:** A boolean or a Promise resolving to a boolean.

> **Warning**
>
> The response body can only be read once! If you plan on reading the response body in this function, we recommend you use the `HumanSecurityUtils.getResponseBody()` function to read the response body safely.

**`Example`**

```ts Example
{
    // ...
    login_successful_reporting_method: 'custom',
    login_successful_callback: async (response: { status: number; headers: Record<string, string[]>; body: any }): Promise<boolean> => {
        return response.status === 200 
                && response.headers['set-cookie']?.some((val) => val.includes('session_token='))
                && await HumanSecurityUtils.getResponseBody(response).includes('Welcome!');
    },
    // ...
}
```

---

### Custom parameters

These configurations are related to [custom parameters](/applications/set-custom-parameters).

**`px_enrich_custom_parameters`** `function` — default: null

> **Note**
>
> Custom parameters added with this function must be defined **before** the Worker is bundled.

Enriches activities sent from the Enforcer to HUMAN with additional custom parameters. This data can include user information, session IDs, or other data that HUMAN should have access to. These custom parameters are defined by a configurable function that must return an object that contains these custom parameters. There is a limit of 10 custom parameters.

> **Warning**
>
> The request body can only be read once! If you plan on reading the request body in this function, we recommend you use the `HumanSecurityUtils.getRequestBody()` function to read the request body safely.

**Parameters:**

* `config: HumanSecurityConfiguration`
* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** `Promise<CustomParameters>`

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_enrich_custom_parameters: async (
        config: HumanSecurityConfiguration,
        request: EW.IngressClientRequest | EW.ResponseProviderRequest,
    ): CustomParameters | Promise<CustomParameters> => {
        let body = null;
        if ('body' in request && request.method === 'POST') {
            try {
                body = JSON.parse(await HumanSecurityUtils.getRequestBody(request))
            } catch {
                // fail silently
            }
        }
        return {
            custom_param1: 'hardcoded value',
            custom_param2: request.getHeader('header-name'),
            custom_param3: body?.['body_property']
        };
    },
    // ...
}
```

---

### Enforced routes \[#enforced-routes-custom-functions]

See [Enforced routes](#enforced-routes) for Property Manager options.

**`px_custom_is_enforced_request`** `function` — default: null

> **Warning**
>
> This configuration is meant for cases that require more complex logic. We recommended you use [`PX_ENFORCED_ROUTES`](#PX_ENFORCED_ROUTES) for most cases.

A custom function that lets you define which requests should be enforced based on custom logic. It accepts the incoming request as an argument and returns a boolean indicating whether the request should be enforced.

**Parameters:**

* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** A boolean or a Promise resolving to a boolean.

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_custom_is_enforced_request: (request: EW.IngressClientRequest | EW.ResponseProviderRequest): boolean | Promise<boolean> => {
        return request.method === 'POST' && request.path.startsWith('/enforced_route');
    },
    // ...
}
```

---

### Filters \[#filters-custom-functions]

See [Filters](#filters) for Property Manager options.

**`px_custom_is_filtered_request`** `function` — default: null

> **Warning**
>
> This configuration is meant for cases that require more complex logic. We recommended you use the other default filters available for most cases.

A custom function that lets you define which requests should be filtered based on custom logic. It accepts the incoming request as an argument and returns a boolean indicating whether the request should be filtered.

**Parameters:**

* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** A boolean or a Promise resolving to a boolean.

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_custom_is_filtered_request: (request: EW.IngressClientRequest | EW.ResponseProviderRequest): boolean | Promise<boolean> => {
        return request.method === 'GET' && request.path.startsWith('/static/');
    },
    // ...
}
```

---

### GraphQL support \[#graphql-support-custom-functions]

See [GraphQL support](#graphql-support) for Property Manager options.

**`px_extract_graphql_keywords`** `function` — default: null

A custom function that identifies key terms from GraphQL operation queries. An alternative to the [`PX_GRAPHQL_KEYWORDS`](#PX_GRAPHQL_KEYWORDS) configuration.

This function accepts the GraphQL query string and must return an array of strings representing all keywords found in the query. These keywords are used to determine the purpose of the operation (such as login, checkout, search) and can also be used to specify which GraphQL operations should be considered sensitive. See [`PX_SENSITIVE_GQL_OP_NAMES`](#PX_SENSITIVE_GQL_OP_NAMES) for more information.

If this function is defined and returns an array (even an empty array), then the returned array will be used as the GraphQL keywords. If this function is defined and returns null, then the query will continue to be evaluated using [`PX_GRAPHQL_KEYWORDS`](#PX_GRAPHQL_KEYWORDS).

**Parameters:**

* `graphqlQuery: string`

Returns `string[]` or a Promise resolving to `string[]`.

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_extract_graphql_keywords: (graphqlQuery: string): string[] | Promise<string[]> => {
        if (/userId\d+/.test(graphqlQuery)) {
            // report no keywords for this query
            return [];
        } else if (/perform(Login|Signin)/.test(graphqlQuery)) {
            // always report 'login' as the only keyword for this query
            return ['login'];
        } else {
            // process query according to px_graphql_keywords configuration
            return null;
        }
    },
    // ...
}
```

---

### Monitored routes \[#monitored-routes-custom-functions]

See [Monitored routes](#monitored-routes) for Property Manager options.

**`px_custom_is_monitored_request`** `function` — default: null

> **Warning**
>
> This configuration is meant for cases that require more complex logic. We recommended you use [`PX_MONITORED_ROUTES`](#PX_MONITORED_ROUTES) for most cases.

A custom function that lets you define which endpoints should be monitored based on custom logic. It accepts the incoming request as an argument and returns a boolean indicating whether the request should be monitored.

**Parameters:**

* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** A boolean or a Promise resolving to a boolean.

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_custom_is_monitored_request: (request: EW.IngressClientRequest | EW.ResponseProviderRequest): boolean | Promise<boolean> => {
        return request.method === 'GET' && request.path.startsWith('/monitored');
    },
    // ...
}
```

---

### Response custom parameters

These configurations enrich async activities with values derived from the origin response.

**`px_enrich_response_custom_parameters`** `function` — default: null

A function that receives the configuration and the response from the origin and returns up to ten fields: `custom_param11` through `custom_param20`. These are merged into `page_requested`, `additional_s2s`, and simulated block activities. There is a limit of ten response custom parameters.

> **Warning**
>
> The response body can only be read once! If you plan on reading the response body in this function, we recommend you use the `HumanSecurityUtils.getResponseBody()` function to read the response body safely.

**Parameters:**

* `config: HumanSecurityConfiguration`
* `response:` `{ status: number; headers: Record<string, string[]>; body: any }`

**Returns:** An object with `custom_param11`–`custom_param20` keys, or a Promise resolving to that object.

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_enrich_response_custom_parameters: async (
        config: HumanSecurityConfiguration,
        response: { status: number; headers: Record<string, string[]>; body: any },
        request?: EW.ResponseProviderRequest | EW.IngressClientRequest,
    ): Promise<Record<string, string>> => {
        const bodyText = await HumanSecurityUtils.getResponseBody(response);
        return {
            custom_param11: response.headers['x-request-id']?.[0] ?? '',
            custom_param12: String(response.status),
            custom_param13: request?.getHeader('user-agent')?.[0] ?? '',
            custom_param14: bodyText?.includes('success') ? 'true' : 'false',
            // ... up to custom_param20
        };
    },
    // ...
}
```

---

### Sensitive routes \[#sensitive-routes-custom-functions]

See [Sensitive routes](#sensitive-routes) for Property Manager options.

**`px_custom_is_sensitive_request`** `function` — default: null

> **Warning**
>
> This configuration is meant for cases that require more complex logic. We recommended you use [`PX_SENSITIVE_ROUTES`](#PX_SENSITIVE_ROUTES) for most cases.

A custom function that lets you define which requests should be considered sensitive based on custom logic. It accepts the incoming request as an argument and returns a boolean indicating whether the request should be considered sensitive.

**Parameters:**

* `request:` [EW.IngressClientRequest | EW.ResponseProviderRequest](https://techdocs.akamai.com/edgeworkers/docs/request-object)

**Returns:** A boolean or a Promise resolving to a boolean.

**`Example`**

```ts Example
const config: HumanSecurityFunctionsConfiguration = {
    // ...
    px_custom_is_sensitive_request: (request: EW.IngressClientRequest | EW.ResponseProviderRequest): boolean | Promise<boolean> => {
        return request.method === 'POST' || request.method === 'PUT';
    },
    // ...
}
```

---