{"id":22096007,"url":"https://github.com/perimeterx/perimeterx-kong-plugin","last_synced_at":"2025-07-17T22:33:49.707Z","repository":{"id":53715597,"uuid":"101315154","full_name":"PerimeterX/perimeterx-kong-plugin","owner":"PerimeterX","description":"PerimeterX Kong plugin","archived":false,"fork":false,"pushed_at":"2025-07-10T18:44:39.000Z","size":124,"stargazers_count":7,"open_issues_count":0,"forks_count":5,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-07-11T00:53:15.916Z","etag":null,"topics":["enforcer","perimeterx"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PerimeterX.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-08-24T16:20:02.000Z","updated_at":"2025-07-10T18:41:58.000Z","dependencies_parsed_at":"2023-11-07T04:07:52.475Z","dependency_job_id":"6e315050-89f7-496c-b37d-c6b861593404","html_url":"https://github.com/PerimeterX/perimeterx-kong-plugin","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/PerimeterX/perimeterx-kong-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerimeterX%2Fperimeterx-kong-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerimeterX%2Fperimeterx-kong-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerimeterX%2Fperimeterx-kong-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerimeterX%2Fperimeterx-kong-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PerimeterX","download_url":"https://codeload.github.com/PerimeterX/perimeterx-kong-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerimeterX%2Fperimeterx-kong-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265672342,"owners_count":23808844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["enforcer","perimeterx"],"created_at":"2024-12-01T04:09:21.860Z","updated_at":"2025-07-17T22:33:49.697Z","avatar_url":"https://github.com/PerimeterX.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"![image](https://storage.googleapis.com/perimeterx-logos/primary_logo_red_cropped.png)\n\n# [PerimeterX](http://www.perimeterx.com) Kong Plugin\n\n## Table of Contents\n\n- [Getting Started](#gettingstarted)\n  - [Dependencies](#dependencies)\n  - [Requirements](#requirements)\n  - [Installation](#installation)\n  - [Installing on Amazon Linux](#awsinstall)\n  - [Basic Usage Example](#basic-usage)\n  - [Demonstration Docker](#docker)\n- [Upgrading](*upgrade)\n- [Configuration](#configuration)\n\n  - [First-Party Configuration](#first_party_config)\n    - [First-Party Mode](#first-party)\n    - [PerimeterX First-Party JS Snippet](#perimeterx_first_party_js_snippet)\n  - [Blocking Score](#blocking-score)\n  - [Monitoring mode](#monitoring-mode)\n  - [Enabled Routes](#enabled-routes)\n  - [Sensitive Routes](#sensitive-routes)\n  - [Extracting Real IP Address](#real-ip)\n  - [Filter Sensitive Headers](#sensitive-headers)\n  - [API Timeout](#api-timeout)\n  - [Send Page Activities](#send-page-activities)\n  - [Debug Mode](#debug-mode)\n  - [Custom Block Page](#customblockpage)\n  - [API Protection Mode](#api-protection)\n  - [Multiple App Support](#multipleapps)\n  - [Additional Activity Handler](#add-activity-handler)\n  - [Enrich Custom Parameters](#custom-parameters)\n  - [Whitelisting](#whitelisting)\n  - [Custom Cookie Header](#custom-cookie-header)\n\n- [Advanced Blocking Response](#advancedBlockingResponse)\n- [Additional Information](#additional-information)\n- [Contributing](#contributing)\n\n## \u003ca name=\"gettingstarted\"\u003e\u003c/a\u003e Getting Started\n\n## \u003ca name=\"dependencies\"\u003e\u003c/a\u003e Dependencies\n\n- [Kong](https://getkong.org/) (2.x and 3.x Kong versions are supported)\n- [LuaJIT](http://luajit.org/)\n- [Lua CJSON](http://www.kyne.com.au/~mark/software/lua-cjson.php)\n- [Lua Resty HTTP](https://github.com/pintsized/lua-resty-http)\n- [Lua Resty Nettle](https://github.com/bungle/lua-resty-nettle)\n- [lustache](https://github.com/Olivine-Labs/lustache)\n- [GNU Nettle \u003e= v3.2](https://www.lysator.liu.se/~nisse/nettle/)\n\nTo install package dependencies on Ubuntu run:\n\n`sudo apt-get update \u0026\u0026 sudo apt-get install lua-cjson nettle-dev luarocks luajit libluajit-5.1-dev ca-certificates make`\n\nAll Lua dependecies are automatically fulfilled with Luarocks.\n\n## \u003ca name=\"installation\"\u003e\u003c/a\u003e Installation\n\nInstallation can be done using [luarocks](https://luarocks.org/).\n\n```sh\nluarocks install kong-plugin-perimeterx\n```\n\nManual installation can accomplished by downloading the sources for this repository and running `sudo make install`.\n\n\u003ca name=\"awsinstall\"\u003e\u003c/a\u003e Additional steps for installing on Amazon Linux\n\nMake sure to change the path shown below in the \"Lua CA Certificates\" section as Amazon Linux stores the CA required in a different location than shown.\n\nIf running Amazon Linux this is the trusted certificate path please use:\n\n```\nlua_ssl_trusted_certificate \"/etc/pki/tls/certs/ca-bundle.crt\";\n```\n\n## \u003ca name=\"requirements\"\u003e\u003c/a\u003e NGINX Configuration File Requirements\n\n### Resolver\n\nAdd the directive `resolver A.B.C.D;` in the HTTP section of your configuration. This is required so NGINX can resolve the PerimeterX API DNS name. `A.B.C.D` is the IP address of your DNS resolver.\n\n### Lua CA Certificates\n\nTo support TLS to PerimeterX servers, you must point Lua to the trusted certificate location (actual location may differ between Linux distributions).\n\n```\nlua_ssl_trusted_certificate \"/etc/ssl/certs/ca-certificates.crt\";\nlua_ssl_verify_depth 3;\n```\n\nIn CentOS/RHEL systems, the CA bundle location may be located at `/etc/pki/tls/certs/ca-bundle.crt`.\n\n### \u003ca name=\"basic-usage\"\u003e\u003c/a\u003e Basic Usage Example\n\nEnsure that you followed the NGINX Configuration Requirements section before proceeding.\n\nLoad the plugin by adding `perimeterx` to the `plugins` section in your Kong configuration (on each Kong node).\n\n`kong.yaml` \"plugins\" section example:\n\n```\n...\nplugins:\n    - name: perimeterx\n      config:\n          px_appId: --REPLACE--\n          auth_token: --REPLACE--\n          cookie_secret: --REPLACE--\n          px_debug: true\n          block_enabled: true\n```\n\nNote: you can also set this property via its environment variable equivalent: `KONG_CUSTOM_PLUGINS`.\n\nTo apply PerimeterX enforcement, add the perimeterx plugin to your API(s):\n\n```bash\ncurl -i -X POST \\\n      --url http://localhost:8001/apis/\u003capi-name\u003e/plugins/ \\\n      --data 'name=perimeterx' \\\n      --data 'config.px_appId=PX_APP_ID' \\\n      --data 'config.auth_token=AUTH_TOKEN' \\\n      --data 'config.cookie_secret=COOKIE_KEY'\n```\n\nYou can find your app ID, authentication token, and cookie key under your account's admin section in [PerimeterX Portal](https://console.perimeterx.com)\n\n### \u003ca name=docker\u003e\u003c/a\u003e Demonstration Docker\n\nTo run the demonstration Docker image:\n\n1. Copy `kong/config/kong.yml` to `kong/config/kong.dev.yml` and adjust it with your PerimeterX app id, cookie secret and auth token.\n\n2. From the root folder execute `./scripts/run-kong.sh  3.9.1`.\n\n3. Navigate to \u003chttp://127.0.0.1:8000\u003e.\n\n4. You can find the PerimeterX module output in your terminal.\n\n## \u003ca name=\"upgrade\"\u003e\u003c/a\u003e Upgrading\n\nTo upgrade to the latest Enforcer version run the following command in luarocks:\n\n`luarocks install perimeterx-kong-plugin`\n\nYour Enforcer version is now upgraded to the latest enforcer version.\n\nFor more information, contact [PerimeterX Support](support@perimeterx.com).\n\n### \u003ca name=\"configuration\"\u003e\u003c/a\u003e Configuration Options\n\n#### Configuring Required Parameters\n\nConfiguration options are set via Kong's admin API, as config parameter.\n\n#### Required parameters\n\n- px_appId\n- cookie_secret\n- auth_token\n\n#### \u003ca name=\"first_party_config\"\u003e\u003c/a\u003e First-Party Configuration\n\n##### \u003ca name=\"first-party\"\u003e\u003c/a\u003e First-Party Mode\n\nFirst-Party Mode enables the module to send/receive data to/from the sensor, acting as a reverse-proxy for client requests and sensor activities.\n\nFirst-Party Mode may require additional changes on the [JS Sensor Snippet](#perimeterx_first_party_js_snippet). For more information, refer to the PerimeterX Portal.\n\n```bash\n--data 'config.first_party_enabled=true'\n```\n\nThe following routes must be enabled for First-Party Mode for the PerimeterX Kong plugin:\n\n- `/\u003cPX_APP_ID without PX prefix\u003e/xhr/*`\n- `/\u003cPX_APP_ID without PX prefix\u003e/init.js`\n- `/\u003cPX_APP_ID without PX prefix\u003e/captcha/*`\n\n- If the PerimeterX Kong module is enabled on `location /`, the routes are already open and no action is necessary.\n\n\u003e NOTE: The PerimeterX Kong Plugin Configuration Requirements must be completed before proceeding to the next stage of installation.\n\n##### \u003ca name=\"perimeterx_first_party_js_snippet\"\u003e\u003c/a\u003e First-Party JS Snippet\n\nEnsure the PerimeterX Kong Plugin is configured before deploying the PerimeterX First-Party JS Snippet across your site. (Detailed instructions for deploying the PerimeterX First-Party JS Snippet can be found \u003ca href=\"https://docs.perimeterx.com/pxconsole/docs/managing-applications#section-snippet\" onclick=\"window.open(this.href); return false;\"\u003ehere\u003c/a\u003e.)\n\nTo deploy the PerimeterX First-Party JS Snippet:\n\n##### 1. Generate the First-Party Snippet\n\n- Go to \u003ca href=\"https://console.perimeterx.com/#/app/applicationsmgmt\" onclick=\"window.open(this.href); return false;\"\u003e**Applications**\u003c/a\u003e \u003e\u003e **Snippet**.\n- Select **First-Party**.\n- Select **Use Default Routes**.\n- Click **Copy Snippet** to generate the JS Snippet.\n\n##### 2. Deploy the First-Party Snippet\n\n- Copy the JS Snippet and deploy using a tag manager, or by embedding it globally into your web template for which websites you want PerimeterX to run.\n\n#### \u003ca name=\"blocking-score\"\u003e\u003c/a\u003e Changing the Minimum Score for Blocking\n\n**Default blocking value:** 100\n\n```bash\n--data 'config.blocking_score=60'\n```\n\n#### \u003ca name=\"monitoring-mode\"\u003e\u003c/a\u003e Blocking Mode\n\n**Default:** false\n\n```bash\n--data 'config.block_enabled=true'\n```\n\nThe PerimeterX plugin is enabled in monitor only mode by default.\n\nSetting the block*enabled flag to \\_true* will activate the module to enforce the blocking score. The PerimeterX module will block users crossing the block score threshold that you define. If a user crosses the minimum block score then the user will receive the block page.\n\n#### \u003ca name=\"enabled-routes\"\u003e\u003c/a\u003e Enabled Routes\n\nThe enabled routes variable allows you to implicitly define a set of routes which the plugin will be active on. Supplying an empty list will set all application routes as active.\n\n**Default: Empty list (all routes)**\n\n```bash\n--data 'config.enabled_routes=/blockhere'\n```\n\n#### \u003ca name=\"sensitive-routes\"\u003e\u003c/a\u003e Sensitive Routes\n\nLists of route prefixes and suffixes. The PerimeterX module will always match the request URI with these lists, and if a match is found will create a server-to-server call, even if the cookie is valid and its score is low.\n\n**Default: Empty list**\n\n```bash\n--data 'config.sensitive_routes_prefix=/login,/user/profile'\n--data 'config.sensitive_routes_suffix=/download'\n```\n\n#### \u003ca name=\"sensitive-headers\"\u003e\u003c/a\u003e Filter sensitive headers\n\nA list of sensitive headers can be configured to prevent specific headers from being sent to PerimeterX servers (lower case header names). Filtering cookie headers for privacy is set by default, and can be overridden on the `pxConfig` variable.\n\n**Default: cookie, cookies**\n\n```bash\n--data 'config.sensitive_headers=cookie,cookies,secret-header'\n```\n\n#### \u003ca name=\"api-timeout\"\u003e\u003c/a\u003eAPI Timeout Milliseconds\n\n\u003e Note: Controls the timeouts for PerimeterX requests. The API is called when a Risk Cookie does not exist, or is expired or invalid.\n\nAPI Timeout in milliseconds (float) to wait for the PerimeterX server API response.\n\n**Default:** 1000\n\n```bash\n--data 'config.s2s_timeout=250'\n```\n\n#### \u003ca name=\"debug-mode\"\u003e\u003c/a\u003e Debug Mode\n\nEnables debug logging mode.\n\n**Default:** false\n\n```bash\n--data 'config.px_debug=true'\n```\n\n#### \u003ca name=\"real-ip\"\u003e\u003c/a\u003e Extracting the real IP address from a request\n\n\u003e Note: It is important that the real connection IP is properly extracted when your NGINX server sits behind a load balancer or CDN. The PerimeterX module requires the user's real IP address.\n\nFor the PerimeterX NGINX module to see the real user's IP address, you need to set `ip_headers`, a list of headers to extract the real IP from, ordered by priority.\n\n**Default with no predefined header: `ngx.var.remote_addr`**\n\nExample:\n\n```bash\n--data 'config.ip_headers=X-TRUE-IP,X-Forwarded-For'\n```\n\n#### \u003ca name=\"customblockpage\"\u003e\u003c/a\u003e Custom Block Page\n\nCustomizing block page can be done by 2 methods:\n\n##### Modifying default block pages\n\nPerimeterX default block page can be modified by injecting custom css, javascript and logo to page\n\n**default values:** nil\n\nExample:\n\n```bash\n--data 'config.custom_logo= http://www.example.com/logo.png'\n--data 'config.css_ref=http://www.example.com/style.css'\n--data 'config.js_ref=http://www.example.com/script.js'\n```\n\n##### Redirect to a custom block page url\n\nUsers can customize the blocking page to meet their branding and message requirements by specifying the URL to a blocking page HTML file. The page can also implement reCaptcha. See [NGINX plugin docs](https://github.com/PerimeterX/perimeterx-nginx-plugin/tree/master/examples) for examples of a customized Captcha page.\n\n**default:** nil\n\n```bash\n--data 'config.custom_block_url=http://www.example.com/block.html'\n```\n\n\u003e Note: This URI **MUST** be whitelisted under `config.whitelist.uri_full` to avoid infinite redirects to the block page.\n\n#### \u003ca name=\"api-protection\"\u003e\u003c/a\u003e API Protection Mode\n\nFor the case where kong is used for API calls and not serving HTML pages, users can set the plugin into API protection mode.\n\nIn this mode, when the system decides to block a request, instead of rendering an HTML block/captcha page, it will return a JSON object\nthat contains a URL for optional redirect on the user's client side.\n\nThe end user can be redirected this way to a custom captcha page, and after solving the captcha challenge, will be redirected back to the page they came from or to a default location.\n\n##### Note\n\nWhen setting the configuration of `api_protection_mode` to `true`, users must also set `api_protection_block_url` which is the address of the custom block page,\nand api_protection_default_redirect_url which is the default location for redirect after solving captcha.\n\nExample:\n\n```bash\n--data 'config.api_protection_mode=true'\n--data 'config.api_protection_block_url=http://www.example.com/block.html'\n--data 'config.api_protection_default_redirect_url=http://www.example.com/home.html'\n```\n\nResponse may look like:\n\n```json\n{\n    \"reason\": \"blocked\",\n    \"redirect_to\": \"http://www.example.com/block.html?url=aHR0cDovL2xvY2FsaG9zdDo4MDAwLz9nZmQ9ZmdkZmc=\u0026uuid=11a12b80-b40c-11e7-8050-eb8403f523e5\u0026vid=ef77a690-9bc8-11e7-9c31-970ffdcc0e6d\"\n}\n```\n\n#### \u003ca name=\"redirect_on_custom_url\"\u003e\u003c/a\u003e Redirect on Custom URL\n\nThe `_M.redirect_on_custom_url` flag provides 2 options for redirecting users to a block page.\n\n**default:** false\n\n```bash\n--data 'config.redirect_on_custom_url=false'\n```\n\nBy default, when a user crosses the blocking threshold and blocking is enabled, the user will be redirected to the block page defined by the `_M.custom_block_url` variable, responding with a 307 (Temporary Redirect) HTTP Response Code.\n\nSetting the flag to flase will *consume* the page and serve it under the current URL, responding with a 403 (Unauthorized) HTTP Response Code.\n\n\u003e *Setting the flag to **false** does not require the block page to include any of the coming examples, as they are injected into the blocking page via the PerimeterX Nginx Enforcer.*\n\nSetting the flag to **true** (enabling redirects) will result with the following URL upon blocking:\n\n```\nhttp://www.example.com/block.html?url=L3NvbWVwYWdlP2ZvbyUzRGJhcg==\u0026uuid=e8e6efb0-8a59-11e6-815c-3bdad80c1d39\u0026vid=08320300-6516-11e6-9308-b9c827550d47\n```\n\n\u003e Note: the **url** variable is comprised of URL Encoded query parameters (of the originating request) and then both the original path and variables are Base64 Encoded (to avoid collisions with block page query params).\n\n###### Custom blockpage requirements\n\nWhen captcha is enabled, and `_M.redirect_on_custom_url` is set to **true**, the block page **must** include the following:\n\n- The `\u003cbody\u003e` section **must** include:\n\n````html\n\u003cdiv id=\"px-captcha\"\u003e\u003c/div\u003e\n\u003cscript\u003e\n    window._pxAppId = '\u003cAPP_ID\u003e';\n    window._pxJsClientSrc = 'https://client.perimeterx.net/\u003cAPP_ID\u003e/main.min.js';\n    window._pxHostUrl = 'https://collector-\u003cAPP_ID\u003e.perimeterx.net';\n\u003c/script\u003e\n\u003cscript src=\"https://captcha.px-cdn.net/\u003cAPP_ID\u003e/captcha.js?a=c\u0026m=0\"\u003e\u003c/script\u003e\n\n#### Configuration example: ```bash --data 'config.custom_block_url=/block.html' --data 'config.redirect_on_custom_url=true'\n````\n\n#### Block page implementation full example\n\n```html\n\u003chtml\u003e\n    \u003chead\u003e \u003c/head\u003e\n    \u003cbody\u003e\n        \u003ch1\u003eYou are Blocked\u003c/h1\u003e\n        \u003cp\u003eTry and solve the captcha\u003c/p\u003e\n        \u003cdiv id=\"px-captcha\"\u003e\u003c/div\u003e\n        \u003cscript\u003e\n            window._pxAppId = '\u003cAPP_ID\u003e';\n            window._pxJsClientSrc = 'https://client.perimeterx.net/\u003cAPP_ID\u003e/main.min.js';\n            window._pxHostUrl = 'https://collector-\u003cAPP_ID\u003e.perimeterx.net';\n        \u003c/script\u003e\n        \u003cscript src=\"https://captcha.px-cdn.net/\u003cAPP_ID\u003e/captcha.js?a=c\u0026m=0\"\u003e\u003c/script\u003e\n    \u003c/body\u003e\n    \u003chtml\u003e\u003c/html\u003e\n\u003c/html\u003e\n```\n\n#### \u003ca name=\"multipleapps\"\u003e\u003c/a\u003e Multiple App Support\n\nThe PerimeterX Enforcer allows for multiple configurations for different apps.\n\nIf your PerimeterX account contains several Applications (as defined via the portal), follow these steps to create different configurations for each Application.\n\nSince Kong supports multiple APIs, you can also use the same PerimeterX Application with different configuration for different APIs, but for best results in our detection,\nit is best to use different Applications and policies for different APIs.\n\n#### \u003ca name=\"add-activity-handler\"\u003e\u003c/a\u003e Additional Activity Handler\n\nAdding an additional activity handler is done by setting `additional_activity_handler` property with an user defined function. The 'additional_activity_handler' function will be executed before sending the data to the PerimeterX portal.\nBecause of technical limitations of the Kong platform, you can't set this function using the admin API. Instead, you need to edit the PerimeterX plugin's `handler.lua`\nfile, and add the function directly to the configuration.\n\nDefault: nil\n\n```lua\nfunction additional_activity_handler(event_type, ctx, details)\n local cjson = require \"cjson\"\n if (event_type == 'block') then\n  ngx.log(ngx.ERR, \"PerimeterX: [\" .. event_type .. \"] blocked with score: \" .. ctx.block_score .. \". Details: \" .. cjson.encode(details))\n else\n  ngx.log(ngx.ERR, \"PerimeterX: [\" .. event_type .. \"]. Details: \" .. cjson.encode(details))\n end\nend\n\nfunction PXHandler:init_worker(config)\n    ...\n    config.additional_activity_handler = additional_activity_handler\nend\n```\n\n### \u003ca name=\"custom-parameters\"\u003e Enrich Custom Parameters\n\nAdding an Enrich Custom Parameters function is done by setting `enrich_custom_params` property with an user defined function. With the `enrich_custom_params` function you can add up to 10 custom parameters to be sent back to PerimeterX servers. When set, the function is called before setting the payload on every request to PerimeterX servers. The parameters should be passed according to the correct order (1-10).\nYou must return the `px_custom_params` object at the end of the function.\nBecause of technical limitations of the Kong platform, you can't set this function using the admin API. Instead, you need to edit the PerimeterX plugin's `handler.lua`\n\nDefault: nil\n\n```lua\nfunction enrich_custom_parameters(px_custom_params)\n    -- here we have an access to `ngx` object.\n    -- e.g.: ngx.req.get_headers()[\"x-user-id\"]\n    px_custom_params[\"custom_param1\"] = \"user_id\"\n    return px_custom_params\nend\n\nfunction PXHandler:init_worker(config)\n    ...\n    config.enrich_custom_parameters = enrich_custom_parameters\nend\n\n```\n\n#### \u003ca name=\"\"\u003e\u003c/a\u003e Additional Activity Handler\n\nAdding an additional activity handler is done by setting 'additional_activity_handler' configuration directive with a user defined function. The 'additional_activity_handler' function will be executed before sending the data to the PerimeterX portal.\nBecause of technical limitations of the Kong platform, you can't set this function using the admin API. Instead, you need to edit the PerimeterX plugin's `handler.lua`\nfile, and add the function directly to the configuration.\n\nDefault: not set.\n\n```lua\nfunction additional_activity_handler(event_type, ctx, details)\n local cjson = require \"cjson\"\n if (event_type == 'block') then\n  ngx.log(ngx.ERR, \"PerimeterX: [\" .. event_type .. \"] blocked with score: \" .. ctx.block_score .. \". Details: \" .. cjson.encode(details))\n else\n  ngx.log(ngx.ERR, \"PerimeterX: [\" .. event_type .. \"]. Details: \" .. cjson.encode(details))\n end\nend\n\nfunction PXHandler:init_worker(config)\n    ...\n    --add function to pxconfig here\n    config.additional_activity_handler = additional_activity_handler\nend\n```\n\n#### \u003ca name=\"custom-cookie-header\"\u003e\u003c/a\u003e Custom Cookie Header\n\nWhen set, this property specifies a header name which will be used to extract the PerimeterX cookie from, instead of the Cookie header.\n\n\u003e NOTE: Using a custom cookie header requires client side integration to be done as well. Please refer to the relevant [docs](https://docs.perimeterx.com/pxconsole/docs/advanced-client-integration#section-custom-cookie-header) for details.\n\n**Default:** nil\n\nExample:\n\n```bash\n--data 'config.config.custom_cookie_header=x-px-cookies'\n```\n\n## \u003ca name=\"whitelisting\"\u003e\u003c/a\u003e Whitelisting\n\nWhitelisting (bypassing enforcement) is configured under in the `whitelist` table.\n\nThere are several different types of filters that can be configured.\n\n```\nwhitelist_uri_full = { _M.custom_block_url },\nwhitelist_uri_prefixes = {},\nwhitelist_uri_suffixes = {'.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'},\nwhitelist_ip_addresses = {},\nwhitelist_ua_full = {},\nwhitelist_ua_sub = {},\nwhitelist_hosts = {}\n```\n\n- **whitelist_uri_full** : for value `{'/api_server_full'}` - will filter requests to `/api_server_full?data=1` but not to `/api_server?data=1`\n- **whitelist_uri_prefixes** : for value `{'/api_server'}` - will filter requests to `/api_server_full?data=1` but not to `/full_api_server?data=1`\n- **whitelist_uri_suffixes** : for value `{'.css'}` - will filter requests to `/style.css` but not to `/style.js`\n- **whitelist_ip_addresses** : for value `{'192.168.99.1'}` - will filter requests coming from any of the listed ips.\n- **whitelist_ua_full** : for value `{'Mozilla/5.0 (compatible; pingbot/2.0; http://www.pingdom.com/)'}` - will filter all requests matching this exact UA.\n- **whitelist_ua_sub** : for value `{'GoogleCloudMonitoring'}` - will filter requests containing the provided string in their UA.\n- **whitelist_hosts** : for value `{'www.example.com'}` - will filter requests coming from the provided host.\n\n## \u003ca name=\"advancedBlockingResponse\"\u003e\u003c/a\u003e Advanced Blocking Response\n\nIn special cases, (such as XHR post requests) a full Captcha page render might not be an option. In such cases, using the Advanced Blocking Response returns a JSON object continaing all the information needed to render your own Captcha challenge implementation, be it a popup modal, a section on the page, etc. The Advanced Blocking Response occurs when a request contains the *Accept* header with the value of `application/json`. A sample JSON response appears as follows:\n\n```javascript\n{\n    \"appId\": String,\n    \"jsClientSrc\": String,\n    \"firstPartyEnabled\": Boolean,\n    \"vid\": String,\n    \"uuid\": String,\n    \"hostUrl\": String,\n    \"blockScript\": String\n}\n```\n\nOnce you have the JSON response object, you can pass it to your implementation (with query strings or any other solution) and render the Captcha challenge.\n\nIn addition, you can add the `_pxOnCaptchaSuccess` callback function on the window object of your Captcha page to react according to the Captcha status. For example when using a modal, you can use this callback to close the modal once the Captcha is successfullt solved. \u003cbr/\u003e An example of using the `_pxOnCaptchaSuccess` callback is as follows:\n\n```javascript\nwindow._pxOnCaptchaSuccess = function (isValid) {\n    if (isValid) {\n        alert('yay');\n    } else {\n        alert('nay');\n    }\n};\n```\n\nFor details on how to create a custom Captcha page, refer to the [documentation](https://docs.perimeterx.com/pxconsole/docs/customize-challenge-page)\n\n## \u003ca name=\"additional-information\"\u003e\u003c/a\u003e Additional Information\n\n### URI Delimiters\n\nPerimeterX processes URI paths with general- and sub-delimiters according to RFC 3986. General delimiters (e.g., `?`, `#`) are used to separate parts of the URI. Sub-delimiters (e.g., `$`, `\u0026`) are not used to split the URI as they are considered valid characters in the URI path.\n\n## \u003ca name=\"contributing\"\u003e\u003c/a\u003e Contributing\n\nThe following steps are welcome when contributing to our project.\n\n### Fork/Clone\n\n[Create a fork](https://guides.github.com/activities/forking/) of the repository, and clone it locally.\nCreate a branch on your fork, preferably using a descriptive branch name.\n\n### Pull Request\n\nAfter you have completed the process, create a pull request. Please provide a complete and thorough description explaining the changes. Remember, this code has to be read by our maintainers, so keep it simple, smart and accurate.\n\n### Thanks\n\nAfter all, you are helping us by contributing to this project, and we want to thank you for it.\nWe highly appreciate your time invested in contributing to our project, and are glad to have people like you - kind helpers.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperimeterx%2Fperimeterx-kong-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperimeterx%2Fperimeterx-kong-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperimeterx%2Fperimeterx-kong-plugin/lists"}