> 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.

# Configuration Options

Configuration options are a set of fields composing the `PxConfig` struct.The config should be instantiated by the client according to his needs. In case the config fields weren't set, they will be populated with default values.\
There are three ways to instantiate the config:

* Builder
* JSON file
* Directly

**Builder**:\
Init the NewPXConfigBuilder with appID, authToken and secret, then pipe the relevant builder setters with the build command at the end.

```none
pxConfig := *NewPXConfigBuilder("App ID", "Cookie Secret", "Auth Token").
        SetModuleMode("active_blocking").
        Build()
```

**JSON file**:\
Use perimeterx.GetPxConfigFromJson to generate PxConfig according to a json file.\
The function should receive the file name.

```none
pxConfig, err := perimeterx.GetPxConfigFromJson("enforcer_config.json")
```

**Directly**:\
In order to inherit the default config values we should use the BuildHUMANConfig function which maintains this logic.\
The BuildHUMANConfig expect an argument of `map[string]interface{}` where the string is the config field name and the interface is the value.

```none
pxConfig, err := perimeterx.BuildPXConfig(
      map[string]interface{}{
            px_app_id: "App ID", px_cookie_secret: "Cookie Secret", px_auth_token: "Auth Token"
      })
```

## Mandatory Parameters

All parameters are obtainable via the HUMAN Portal (Applications and Policies pages):

* AppID
* AuthToken
* CookieSecret

## Module Enabled

A boolean flag to enable/disable the HUMAN Enforcer.

**Default:** true

```none
SetModuleEnabled(false) // Builder

{"px_module_enabled": false} // JSON file

pxConfig["px_module_enabled"]= false //Direct
```

## Module Mode

Sets the working mode of the Enforcer.

Values:

`monitor` - Monitor Mode\
`active_blocking` - Blocking Mode

While `ModuleMode` is on ("monitor"), all requests will undergo the full inspection cycle yet will never be blocked. Setting the `ModuleMode` flag to "active blocking" will activate the module to enforce the blocking score. The HUMAN 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 captcha/block page.

```none
SetModuleMode("active_blocking") // Builder

{"px_module_mode": "active_blocking"} // JSON file

pxConfig["px_module_mode"] = "active_blocking" //Direct
```

## Blocking Score

Sets the minimum blocking score of a request.

Possible values:

* Any integer between 0 and 100.

**Default:** 100

```none
SetBlockingScore(70) // Builder

{"px_blocking_score": 70} // JSON file

pxConfig["px_blocking_score"] = 70 //Direct
```

## Sensitive Routes

List of route prefixes. The HUMAN module will always match the request URI with this list, and if a match is found, will create a server-to-server call, even if the cookie is valid and its score is low. Ensures that routes that are more sensitive to attacks will always undergo the full enforcement cycle.

**Default:** Empty

```none
SetSensitiveRoutes([]string{"/example", "/very/important"}) // Builder

{"px_sensitive_routes": []string{"/example", "/very/important"}} // JSON file

pxConfig["px_sensitive_routes"] = []string{"/example", "/very/important"} //Direct
```

## Sensitive Routes Regex

List of regular expressions. The HUMAN module will always match the request URI with this list, and if a match is found, will create a server-to-server call, even if the cookie is valid and its score is low. Ensures that routes that are more sensitive to attacks will always undergo the full enforcement cycle.

**Default:** Empty

```none
SetSensitiveRoutes([]string{"^/example.*", "^/very/important.*"}) // Builder

{"px_sensitive_routes": []string{"^/example.*", "^/very/important.*"}} // JSON file

pxConfig["px_sensitive_routes"] = []string{"^/example.*", "^/very/important.*"} //Direct
```

## Monitored Routes

List of route prefixes. The HUMAN module will always match the request URI with this list, and if a match is found, the request will be treated as if in monitor mode.

**Default:** Empty list

```none
SetMonitoredRoutes([]string{"/monitored-route"}) // Builder

{"px_monitored_routes": []string{"/monitored-route"}} // JSON file

pxConfig["px_monitored_routes"] = []string{"/monitored-route"} //Direct
```

## Monitored Routes Regex

List of regular expressions. The HUMAN module will always match the request URI with this list, and if a match is found, the request will be treated as if in monitor mode.

**Default:** Empty list

```none
SetMonitoredRoutesRegex([]string{"^/monitored-route.*"}) // Builder

{"px_monitored_routes_regex": []string{"^/monitored-route.*"}} // JSON file

pxConfig["px_monitored_routes_regex"] = []string{"^/monitored-route.*"} //Direct
```

## Enforced Routes

List of route prefixes. The HUMAN module will always match the request URI with this list, and if a match is found, the request will be treated as if in active_blocking mode.

**Default:** Empty list

```none
SetEnforcedRoutes([]string{"/enforced-route"}) // Builder

{"px_enforced_routes": []string{"/enforced-route"}} // JSON file

pxConfig["px_enforced_routes"] = []string{"/enforced-route"} //Direct
```

## Enforced Routes Regex

List of regular expressions. The HUMAN module will always match the request URI with this list, and if a match is found, the request will be treated as if in active_blocking mode.

**Default:** Empty list

```none
SetEnforcedRoutes([]string{"^/enforced-route.*"}) // Builder

{"px_enforced_routes": []string{"^/enforced-route.*"}} // JSON file

pxConfig["px_enforced_routes"] = []string{"^/enforced-route.*"} //Direct
```

## Filter By Route

An array of route prefixes that are always allowed and not validated by the HUMAN enforcer.\
Each string value of a path will be treated as a prefix.

**Default:** Empty

```none
SetWhitelistRoutes([]string{"/example", "/not/important"}) // Builder

{"px_filter_by_route": []string{"/example", "/not/important"}} // JSON file

pxConfig["px_filter_by_route"] = []string{"/example", "/not/important"} //Direct
```

## Filter By Route Regex

An array of regular expressions that are always allowed and not validated by the HUMAN enforcer. A regular expression can be defined directly as an expression, and will be treated as is.

**Default:** Empty

```none
SetWhitelistRoutesRegex([]string{"^/example.*", "^/not/important"}) // Builder

{"px_filter_by_route_regex": []string{"^/example$", "/not/important"}} // JSON file

pxConfig["px_filter_by_route_regex"] = []string{"^/example", "^/not/important"} //Direct
```

## Filter By HTTP Method

List of HTTP methods. The HUMAN module will always match the request method with this list, and if a match is found, will pass the request. The list is case-insensitive.

**Default:** Empty list

```none
SetFilterByHttpMethods([]string{"OPTIONS", "TRACE"}) // Builder

{"px_filter_by_http_method": []string{"OPTIONS", "TRACE"}} // JSON file

pxConfig["px_filter_by_http_method"] = []string{"OPTIONS", "TRACE"} //Direct
```

## Filter By User Agent

List of User Agents. The HUMAN module will always match the request user agent with this list, and if a match is found, will pass the request. The list is case-insensitive.

**Default:** Empty list

```none
SetFilterByUserAgents([]string{"test-agent", "FilteredAgent"}) // Builder

{"px_filter_by_user_agent": []string{"test-agent", "FilteredAgent"}} // JSON file

pxConfig["px_filter_by_user_agent"] = []string{"test-agent", "FilteredAgent"} //Direct
```

## Filter By IP

List of IPs or IP ranges. The HUMAN module will always match the extracted IP with this list, and if a match is found, will pass the request.

**Default:** Empty list

```none
SetFilterByIps([]string{"10.21.21.21", "21.0.0.0/8"}) // Builder

{"px_filter_by_ip": []string{"10.21.21.21", "21.0.0.0/8"}} // JSON file

pxConfig["px_filter_by_ip"] = []string{"10.21.21.21", "21.0.0.0/8"} //Direct
```

## Filter By Extension

A list of static file extensions to filter.

**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", ".map"]

```none
SetExtensionsToBeFiltered([]string{"css", "bmp", "tif"}) // Builder

{"px_filter_by_extension": []string{"css", "bmp", "tif"}} // JSON file

pxConfig["px_filter_by_extension"] = []string{"css", "bmp", "tif"} //Direct
```

## Sensitive Headers

A list of sensitive headers can be configured to prevent specific headers from being sent to HUMAN servers. Filtering cookie headers for privacy is set by default, and can be overridden on the pxConfig variable.

**Default:** \['cookie', 'cookies']

```none
SetSensitiveHeaders([]string{"a-secret-header", "other-secret-header"}) // Builder

{"px_sensitive_headers": []string{"a-secret-header", "other-secret-header"}} // JSON file

pxConfig["px_sensitive_headers"] = []string{"a-secret-header", "other-secret-header"} //Direct
```

## IP Headers

Extracting the real IP address from a request

The user's IP can be passed to the HUMAN module by passing a list of headers to extract the real IP from, ordered by priority.

> **Note**
>
> It is important that the real connection IP is properly extracted when your server is behind a load balancer or CDN. In order to properly perform processing and detection on server-to-server calls, the HUMAN module needs the real user's IP.

**Default:** Empty

```none
SetIPHeaders([]string{"X-Forwarded-For", "X-Real-Ip"}) // Builder

{"px_ip_headers": []string{"X-Forwarded-For", "X-Real-Ip"}} // JSON file

pxConfig["px_ip_headers"] = []string{"X-Forwarded-For", "X-Real-Ip"} //Direct
```

## First Party Enabled

First Party Mode enables the module to send/receive data to/from the sensor, acting as a "reverse-proxy" for client requests and sensor activities.

**Default:** true

```none
SetFirstPartyEnabled(false) // Builder

{"px_first_party_enabled": false} // JSON file

pxConfig["px_first_party_enabled"] = false //Direct
```

## Enrich Custom Parameters

Custom parameters allow you to add up to 10 custom parameters to be sent back to HUMAN servers. When set, the `EnrichCustomParams` function is called before setting the payload on every request to HUMAN servers.

**Default:** Empty

The configured custom parameters function must have a signature complying with the `CustomParamsHandler` type:

Go

```none
type CustomParamsHandler func(map[string]interface{}, *http.Request) map[string]interface{}
```

Example usage:

Go

```none
func(customParams map[string]interface{}, originalRequest *http.Request) map[string]interface{} {
    customParams["custom_param1"] = "string" // hard-coded string
    customParams["custom_param2"] = 12 // hard-coded int
    customParams["custom_param3"] = originalRequest.Method // value from the original request
    return customParams
}

SetEnrichCustomParams(enrichCustomParams) // Builder

// Not available for JSON file

pxConfig["px_enrich_custom_parameters"] = enrichCustomParams //Direct
```

## CSS Ref

Modifies a custom CSS by adding the CSSRef directive and providing a valid URL to the CSS.

**Default:** Empty

Go

```none
SetCSSRef("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css") // Builder

{"px_css_ref": "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"} // JSON file

pxConfig["px_css_ref"] = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" //Direct
```

## JS Ref

Adds a custom JS file by adding JSRef directive and providing the JS file that is loaded with the block page.

**Default:** Empty

Go

```none
SetJsRef("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js") // Builder

{"px_js_ref": "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"} // JSON file

pxConfig["px_js_ref"] = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" //Direct
```

## Custom Logo

The logo is displayed at the top of the the block page.

**Default:** Empty

Go

```none
SetCustomLogo("https://s.perimeterx.net/logo.png") // Builder

{"px_custom_logo": "https://s.perimeterx.net/logo.png"} // JSON file

pxConfig["px_custom_logo"] = "https://s.perimeterx.net/logo.png" //Direct
```

## API Timeout Milliseconds

API Timeout in milliseconds to wait for the HUMAN server API response. The API is called when a Risk Cookie does not exist, or is expired or invalid.

**Default:** 1000

Go

```none
SetActivitiesTimeout(250) // Builder

{"px_activities_timeout": 250} // JSON file

pxConfig["px_activities_timeout"] = 250 //Direct
```

## Logger

Sets the logger severity level mode.\
Values:

* `none` - HUMAN logger will not output any logs
* `error` - HUMAN logger will log errors only and fatal events (e.g., exceptions)
* `debug` - HUMAN logger will output detailed logs for debugging purposes

**Default:** `error`

Go

```none
SetLoggerSeverityLevel("debug") // Builder

{"px_logger_severity": "debug"} // JSON file

pxConfig["px_logger_severity"] = "debug" //Direct
```

## Custom Cookie Header

A case-insensitive header name that contains HUMAN cookies. If this header exists on the request, the cookies in the header value will be processed along with those found on the Cookie header. If any duplicate cookies are found, those in the custom cookie header will take precedence.

**Default:** x-px-cookies

```none
SetCustomCookieHeader("x-custom-cookies") // Builder

{"px_custom_cookie_header": "x-custom-cookies"} // JSON file

pxConfig["px_custom_cookie_header"] = "x-custom-cookies" //Direct
```

## Block Invalid Cookie

When set as `true`, the enforcer will not perform risk api calls when cookie decryption or validation fail. Instead, it will immediately serve a block page.

**Default:** false

Go

```none
SetBlockInvalidCookie(true) // Builder

{"px_block_invalid_cookie": true} // JSON file

pxConfig["px_block_invalid_cookie"] = true //Direct
```

## Custom Verification Handler

A custom verification handler is a function that can be called by the HUMANModule inside the default verification handler to enable additional functionality.

The verification handler must have a signature complying with the `VerificationHandler` type:

Go

```none
type VerificationHandler func(PxConfig, *PxContext, *http.Response, *http.Request)
```

Example usage:

Go

```none
func customVerificationHandler (config perimeterx.PxConfig, context *perimeterx.PxContext, w *http.Response, r *http.Request) {
    if context.Headers.Get("must-have-this-header") == "" {
        perimeterx.Block(context, w)
    }
}


SetCustomVerificationHandler(customVerificationHandler) // Builder

// Not available for JSON file

pxConfig["px_custom_verification_handler"] = customVerificationHandler //Direct
```

## Data Enrichment

PX data enrichment, the data enrichment cookie is attached to S2S calls as a way to transfer additional data between the Enforcer and HUMAN collector. The data it contains is set by the collector according to the setting in the portal and is available on the cookie as a JSON object. While this functionality is mostly controlled by the collector, you may want access to the PXDE values after activities have been sent, in the additional activity handler.\
The data enrichment payload can also be processed with `CustomVerificationHandler`.

Below is an example that includes the pre-condition checks to process the data enrichment payload and enrich the request headers.

## Advanced Blocking Response

In 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 containing 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:

```json
{
    "appId": String,
    "jsClientSrc": String,
    "firstPartyEnabled": Boolean,
    "vid": String,
    "uuid": String,
    "hostUrl": String,
    "blockScript": String
}
```

Once 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.

In 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 successfully solved.

An example of using the `_pxOnCaptchaSuccess` callback is as follows:

```javascript
window._pxOnCaptchaSuccess = function (isValid) {
    if (isValid) {
        alert('yay');
    } else {
        alert('nay');
    }
};
```

For details on how to create a custom Captcha page, refer to the [documentation](/applications/customize-challenge-page).

If you wish to disable this behavior when the Accept header has the value of application/json, set the following configuration:

Go

```none
SetAdvancedBlockingResponseEnabled(false) // Builder

{"px_advanced_blocking_response_enabled": false} // JSON file

pxConfig["px_advanced_blocking_response_enabled"] = false //Direct
```

## User Identifiers (JWT)

The User Identifiers are used by HUMAN to identify clients during and across sessions. The identifiers are:

* JWT - JSON Web Token is an encrypted token that holds a JSON object which contains metadata on the user request, including the app user ID. It can be stored in a cookie or header.
* CTS -  Cross Tab Session represented by a token that is stored on the `pxcts` cookie. (No configuration necessary.)

To extract the desired fields from the JWT (either as a request header or as a cookie), you must configure:

1. The name of the cookie or header where the JWT token can be found
2. The field name in the JWT payload representing the user ID
3. Any additional field values in the JWT payload that should be reported

**Default:** Empty

For cookie-based JWT tokens:

```none
// Builder
SetJwtCookieName("jwt_cookie")
SetJwtCookieUserIdFieldName("user_id")
SetJwtCookieAdditionalFieldNames([]string{"field1", "field2.subfield1"})

// JSON file
{
  "px_jwt_cookie_name": "jwt_cookie"
  "px_jwt_cookie_user_id_field_name": "user_id"
  "px_jwt_cookie_additional_field_names": ["field1", "field2.subfield1"]
}

// Direct
pxConfig["px_jwt_cookie_name"] = "jwt_cookie"
pxConfig["px_jwt_cookie_user_id_field_name"] = "user_id"
pxConfig["px_jwt_cookie_additional_field_names"] = []string{"field1", "field2.subfield1"}
```

For header-based JWT tokens:

```none
// Builder
SetJwtHeaderName("x-jwt-token-header")
SetJwtHeaderUserIdFieldName("user_id")
SetJwtHeaderAdditionalFieldNames([]string{"field1", "field2.subfield1"})

// JSON file
{
"px_jwt_header_name": "x-jwt-token-header"
"px_jwt_header_user_id_field_name": "user_id"
"px_jwt_header_additional_field_names": ["field1", "field2.subfield1"]
}

// Direct
pxConfig["px_jwt_header_name"] = "x-jwt-token-header"
pxConfig["px_jwt_header_user_id_field_name"] = "user_id"
pxConfig["px_jwt_header_additional_field_names"] = []string{"field1", "field2.subfield1"}
```

## CORS Support Enabled

Enables default CORS block headers on CORS requests. Also allows for the activation of other CORS features, such as adding custom block headers custom handling or filtering of preflight requests.

**Default:** false

```none
SetCorsSupportEnabled(true) // Builder

{"px_cors_support_enabled": true} // JSON file

pxConfig["px_cors_support_enabled"] = true //Direct
```

## CORS Preflight Request Filter Enabled

When enabled, filters preflight requests from the enforcement flow. (Note: If a custom preflight handler is set, it will be invoked.)

**Default:** false

```none
SetCorsFilterPreflightRequestsEnabled(true) // Builder

{"px_cors_preflight_request_filter_enabled": true} // JSON file

pxConfig["px_cors_preflight_request_filter_enabled"] = true //Direct
```

## CORS Custom Preflight Handler

A custom function that is triggered and can return a custom response for preflight requests. If `nil` is returned, no response will be returned and the enforcer flow will continue.

Note: The custom preflight handler will be invoked even if the CORS preflight filter configuration is enabled. If the filter is enabled and the handler returns `nil`, the request will be filtered.

**Default:** nil

```none
// Builder
SetCorsCustomPreflightHandler(func(request *http.Request) *http.Response {
    if shouldRespond {
        return &http.Response{} // custom response
    }
    return nil
})

//Direct
pxConfig["px_cors_custom_preflight_handler"] = func(request *http.Request) *http.Response {
    if shouldRespond {
        return &http.Response{} // custom response
    }
    return nil
}
```

## CORS Create Custom Block Headers

If CORS support is enabled, block responses will include the following two headers by default.

* Access-Control-Allow-Origin - req.Header.Get("Origin")
* Access-Control-Allow-Credentials - true

However, it is possible to customize the headers returned on block responses. This function returns headers that should be added to all block responses to CORS requests.

**Default:** nil

```none
// Builder
SetCorsCreateCustomCorsHeaders(func(request *http.Request, context *perimeterx.PxContext) http.Header {
    return http.Header{
		"X-Custom-Origin": []string{req.Header.Get("Origin")}
    }
})

// Direct
pxConfig["px_cors_create_custom_block_response_headers"] = func(request *http.Request, context *perimeterx.PxContext) http.Header {
    return http.Header{
        "X-Custom-Origin": []string{req.Header.Get("Origin")}
    }
}
```

## Credentials Intelligence

This feature extracts credentials (hashed username and password) from requests and sends them to HUMAN as additional info in the risk api call. The feature can be toggled on and off, and may be set for any number of unique paths. The settings are adjusted by modifying the `pxConfig`.\
If credentials are found to be compromised, the header `px-compromised-credentials` will be added to the origin request with the value `1`. You may configure the name of this header with the `px_compromised_credentials_header` configuration.

**Default Values**

* px_compromised_credentials_header: "px-compromised-credentials"
* px_login_credentials_extraction_enabled: false
* px_login_credentials_extraction: CILoginMap
* px_credentials_intelligence_version: "v2"
* px_send_raw_username_on_additional_s2s_activity: false
* px_additional_s2s_activity_header_enabled: false
* px_login_successful_reporting_method: "status"
* px_login_successful_body_regex: nil
* px_login_successful_header_name: "x-px-login-successful"
* px_login_successful_header_value: "1"
* px_login_successful_status: \[]int
* px_custom_credentials_extractor: nil

```json
{
  ...
 " px_compromised_credentials_header": "x-px-comp-creds",
 "px_login_credentials_extraction_enabled": true,
  "px_login_credentials_extraction": [
    {
      "pathType": "regex" or null // default: "exact"
      "path": "/login", // support regular expressions and exact path configuration
      "method": "post", // supports all http methods
      "sent_through": "body", // supported sentThroughs: body, header, query-param
      "pass_field": "password", // name (or array of names) of the password field in the request (can also be nested field using dots i.e details.password)
      "user_field": ["username", "email"] // name (or array of names) of the username field in the request (can also be nested field using dots i.e details.username)
    },
    ...
  ],
  ...
};
```

Builder example:

```none
credentialsExtractionDetails := []interface{}{map[string]interface{}{
        "pathType":   "direct",
        "path":       "/login",
        "method":     "post",
        "pass_field": "password",
        "user_field": []string{"username", "email"},
    }}

NewPXConfigBuilder("App ID", "Cookie Secret", "Auth Token").
        SetLoginCredentialsExtractionEnabled(true).
        SetLoginCredentialsExtractionDetails(credentialsExtractionDetails).
        Build()
```

> **Important Notice**
>
> Define regular expression "path": When using pathType "regex" the path attribute should contain regular expression as a string pattern without slashes and without flags (i.e, instead of /ab+c/i configure "ab+c"). Regular expressions are treated as case-insensitive by the enforcer by default.
>
> Configure `user_field` or `pass_field` as an array when the same login endpoint can have two or more different field names as input.

It is also possible to define a custom struct to extract the username and password. The struct should implement CredentialsExtractor interface and override the ExtractCredentials method. The method accepts the *http.Request as a parameter and return the* LoginCredentials. If extraction is unsuccessful, the function should return `nil`.

Go

```none
type MyCredentialsExtractor struct {
    username string
    password string
}

func (myCredentialsExtractor MyCredentialsExtractor) ExtractCredentials(request *http.Request) *perimeterx.LoginCredentials {
  //write extraction logic here
    return &perimeterx.LoginCredentials{Username: myCredentialsExtractor.username, Password: myCredentialsExtractor.password}
}

SetAdvancedBlockingResponseEnabled(MyCredentialsExtractor) // Builder

// Not available for JSON file

pxConfig["px_custom_credentials_extractor"] = MyCredentialsExtractor //Direct
```

### Additional S2S Activity

To enhance detection on login credentials extraction endpoints, the following additional information is sent to HUMAN via an `additional_s2s` activity:

* **Response Code** - The numerical HTTP status code of the response.
* **Login Success** - A boolean indicating whether the login completed successfully. See the options listed below for how to provide this data.
* **Raw Username** - The original username used for the login attempt. In order to report this information, make sure the configuration `px_send_raw_username_on_additional_s2s_activity` is set to `true`.

### Login Success Reporting

There are a number of different possible ways to report the success or failure of the login attempt. If left empty, the login successful status will always be reported as `false`.

**Default**: UnknownLoginResponseValidationMethod

Go

```none
SetLoginResponseValidationMethod("body") // Builder

{"px_login_successful_reporting_method": "body"} // JSON file

pxConfig["px_login_successful_reporting_method"] = "body" //Direct
```

**Status**\
Provide a status or array of statuses that represent a successful login. If a response's status code matches the provided value or one of the values in the provided array, the login successful status is set to `true`. Otherwise, it's set to `false`.

> **Note**
>
> To define a range of statuses, use the `custom` reporting method.

**Default Values**

px_login_successful_status: 200

Go

```none
SetLoginResponseValidationStatusCode([]int{200}) // Builder

{"px_login_successful_status": []int{200}} // JSON file

pxConfig["px_login_successful_status"] = []int{200} //Direct
```

**Header**

Provide a header name and value. If the header exists on the response and matches the provided value, the login successful status is set to `true`. If the header is not found on the response, or if the header value does not match the value in the configuration, the login successful status is set to `false`.

**Default Values**

px_login_successful_header_name: x-px-login-successful

px_login_successful_header_value: 1

Go

```none
SetHeaderNameToValidateLoginResponse("x-px-login-successful") // Builder

{"px_login_successful_header_name": "x-px-login-successful"} // JSON file

pxConfig["px_login_successful_header_name"] = "x-px-login-successful" //Direct


SetHeaderValueToValidateLoginResponse("1") // Builder

{"px_login_successful_header_value": "1"} // JSON file

pxConfig["px_login_successful_header_value"] = "1" //Direct
```

**Body**

Provide a string or regular expression with which to parse the response body. If a match is found, the login successful status is set for `true`. If no match is found, the login successful status is set to `false`.

**Default Values**

px_login_successful_body_regex: nil

Go

```none
SetRegexPatternToValidateLoginResponseBody("/login.*") // Builder

{"px_login_successful_body_regex": "/login.*"} // JSON file

pxConfig["px_login_successful_body_regex"] = "/login.*" //Direct
```

**Custom**

Provide a custom class that implements LoginResponseValidator and override isSuccessfulLogin which receives HttpServletResponseWrapper and returns a boolean.

**Default Values**

px_login_successful_custom_callback: null

Go

```none
type MyCustomLoginResponseValidator struct {}

func (clrv MyCustomLoginResponseValidator) IsSuccessfulLogin(response perimeterx.ResponseWriterWrapper) bool {
    // validation login
    return false
}

 SetCustomLoginResponseValidator(MyCustomLoginResponseValidator) // Builder

//Not available for JSON file

 pxConfig["px_custom_login_response_validation"] = MyCustomLoginResponseValidator //Direct
```

### Additional S2S Activity Headers

Rather than sending the `additional_s2s` activity automatically, it is instead possible to generate the base `additional_s2s` activity along with the URL endpoint, and pass them to the origin server as headers on the original HTTP request. When enabled, the module will add two new headers to the original request and send them to the origin:

* `px-additional-activity`, a stringified JSON activity that should be sent.
* `px-additional-activity-url`, the complete URL endpoint to which the JSON object should be sent.

> **Note**
>
> Enabling this feature will disable the automatic sending of the `additional_s2s` activity.

**Default Values**

px_additional_s2s_activity_header_enabled: false

Go

```none
SetAdditionalS2SActivityHeaderEnabled(true) // Builder

{"px_additional_s2s_activity_header_enabled": true} // JSON file

pxConfig["px_additional_s2s_activity_header_enabled"] = true //Direct
```

## Response Wrapper implementation

Credentials Intelligence require reading the login response. In order to enable reading multiple times the response a ResponseWrapper was created. The wrapper should be used inside an interceptor in the following manner.

This should be added before writing to the response.

Go

```none
responseWriter := perimeterx.NewResponseWriterWrapper(w)
```

Example for implementation inside interceptor:

Go

```none
func middleware() Adapter {
    return func(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            responseWriter := perimeterx.NewResponseWriterWrapper(w)
            response, context, err := perimeterx.Enforce(r, &ExampleRuntime{})

            fmt.Print(context.Score)

            if err != nil {
                fmt.Print(err)
            }

            if response.Body != nil {
                responseWriter.WriteHeader(response.StatusCode)
                responseWriter.Header().Set("Content-Type", response.Header.Get("Content-Type"))
                var body, _ = ioutil.ReadAll(response.Body)
                responseWriter.Write(body)
            } else {
                h.ServeHTTP(responseWriter, r)
            }
        })
    }
}
```

## Graphql

For those using GraphQL endpoints, it is possible to trigger server-to-server risk calls on particular operation types or names. Like the sensitive routes feature, a request that contains an operation of the configured type or name will trigger risk and client activity requests to HUMAN servers every time that operation is performed.

The risk and the client activity requests will contain a list of the one or more graphql operations, each including the name, type and if it's sensitive.

If an operation type (e.g., `query`, `mutation`, `subscription`) is configured in `px_sensitive_graphql_operation_types`, all GraphQL operations of that type will be treated as sensitive. If an operation name is configured in `px_sensitive_graphql_operation_names`, all GraphQL operations with that name will be treated as sensitive.

This feature only applies to request's route that match the regex route configured in `px_graphql_routes`.

**Default Values:**

px_graphql_enabled: true,

px_graphql_routes: regexp.Compile(".\*graphql.\*")

px_sensitive_graphql_operation_types: Empty

px_sensitive_graphql_operation_names: Empty

Go

```none
//Builder
*NewPXConfigBuilder("App ID", "Cookie Secret", "Auth Token").
SetGraphqlEnabled(true).
SetGraphqlRoutes([]string{"/graphql.*", "/gql.*"}).
SetSensitiveGraphqlOperationTypes([]string{"query","mutation"}).
SetSensitiveGraphqlOperationNames([]string{"LoginOperation", "AccountInfoQuery"}).
Build()

// JSON file
{
    ...
    px_sensitive_graphql_operation_types: ["query","mutation"],
    px_sensitive_graphql_operation_names: ["LoginOperation", "AccountInfoQuery"],
    px_graphql_enabled: true,
    px_graphql_routes: ["/graphql.*", "/gql.*"]
    ...
};

// Direct
pxConfig["px_graphql_enabled"] = true
pxConfig["px_graphql_routes"] = []string{"/graphql.*", "/gql.*"}
pxConfig["px_sensitive_graphql_operation_types"] = []string{"query","mutation"}
pxConfig["px_sensitive_graphql_operation_names"] = []string{"LoginOperation", "AccountInfoQuery"}.
```