---
title: Prepare the server
description: In this step, you set up your server to perform device profiling.
component: sdks
version: latest
page_id: sdks:sdks:use-cases/device-profile/setup
canonical_url: https://docs.pingidentity.com/sdks/latest/sdks/use-cases/device-profile/setup.html
llms_txt: https://docs.pingidentity.com/sdks/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
section_ids:
  device-profiling-journey: Configure a journey to perform device profiling
  customize-device-matching: Customize device profile matching
  download_and_modify_a_sample_device_match_script: Download and modify a sample device match script
  requirements: Requirements
  customize_the_script: Customize the script
  configure_the_matching: Configure the matching
  build_the_script: Build the script
---

# Prepare the server

In this step, you set up your server to perform device profiling.

## Configure a journey to perform device profiling

To profile devices you must configure an authentication journey in your server.

The following table covers the authentication nodes and callbacks available for profiling devices in your authentication journeys.

| Node                                                                                                              | Callback                                                                                                                                    | Description                                                           |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| [Device Profile Collector node](https://docs.pingidentity.com/auth-node-ref/latest/device-profile-collector.html) | [DeviceProfileCallback](https://docs.pingidentity.com/pingoneaic/latest/am-authentication/callbacks-interactive.html#DeviceProfileCallback) | Gather location data and other metadata from the client device.       |
| [Device Match node](https://docs.pingidentity.com/auth-node-ref/latest/device-match.html)                         | Non-interactive                                                                                                                             | Compare collected device data with that stored in the user's profile. |
| [Device Profile Save node](https://docs.pingidentity.com/auth-node-ref/latest/device-profile-save.html)           | Non-interactive                                                                                                                             | Persist collected device data to a user's profile.                    |

In your server, log in as an administrator and create a new authentication journey similar to the following example:

![An example device profiling journey](../../../_images/device-profile-example-journey.png)Figure 1. An example device profiling journey

* You must identify the user to be able to retrieve any stored device profiles they already have.

  In this example, we ask for their username and password, and verify the credentials against the data store.

* The [Device Profile Collector node](https://docs.pingidentity.com/auth-node-ref/latest/device-profile-collector.html) 1 instructs the SDK to collect and return metadata from the client device.

* The [Device Match node](https://docs.pingidentity.com/auth-node-ref/latest/device-match.html) 2 compares the collected metadata against any stored in the user's profile.

  |   |                                                                                                                                                                                                                                                                     |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | You can write scripts to customize how the node compares captured and stored metadata.For a complete sample script, as well as instructions for its use and a development toolkit, refer to <https://github.com/ForgeRock/forgerock-device-match-script> on GitHub. |

* The example journey continues after comparing metadata, depending on the outcome:

  * `True`

    The client device matches a device they have saved previously, and authentication succeeds without further interaction.

  * `False` or `Unknown Device`

    The client device does not match, or they have not saved a device profile, so authentication requires additional steps, such as MFA verification.

* After successful MFA verification, the [Device Profile Save node](https://docs.pingidentity.com/auth-node-ref/latest/device-profile-save.html) 3 offers to save the metadata to the user's profile, marking the client device as trusted for future journeys.

## Customize device profile matching

The default [Device Match node](https://docs.pingidentity.com/auth-node-ref/latest/device-match.html) logic matches devices based on the number of differences in the captured attribute values. You can modify the threshold for difference by using the Acceptable Variance field in the node configuration.

The node also supports a custom matching script, where you can customize or write your own logic for matching device profiles. The script type must be Decision node script for authentication trees in self-managed AM servers or Journey Decision Node in Advanced Identity Cloud deployments.

Learn more about creating scripts:

* [Script with JavaScript in Advanced Identity Cloud](https://docs.pingidentity.com/pingoneaic/latest/am-scripting/preface.html)

* [Scripting in AM](https://docs.pingidentity.com/pingam/8/scripting-guide/preface.html)

### Download and modify a sample device match script

ForgeRock provides a sample repository that builds a device profile matching script you can download and customize for use in your environment.

The code is available on GitHub: <https://github.com/ForgeRock/forgerock-device-match-script>

#### Requirements

You require the following prerequisites to build this project:

* Node v13.10 or higher

* NPM v6 or higher

#### Customize the script

Without any modifications, the sample script performs matching on both metadata and location data.

You can modify `src/index.js` to prevent either of the matching types from running:

* Perform both metadata and location matching

  ```javascript
  // Metadata and location matching
  const [ metadataMatch, locationMatch ] = deviceMatcher();
  const isMetadataMatching = metadataMatch(client.metadata, stored.metadata);
  const isLocationMatching = locationMatch(client.location, stored.location);
  ```

* Perform only metadata matching

  ```javascript
  const [ metadataMatch ] = deviceMatcher();
  const isMetadataMatching = metadataMatch(client.metadata, stored.metadata);
  ```

* Perform only location matching

  ```javascript
  const [ _, locationMatch ] = deviceMatcher();
  const isLocationMatching = locationMatch(client.location, stored.location);
  ```

|   |                                                                                                                                                |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|   | To modify the *logic* the script uses, edit the following files:* Metadata matching: `src/metadata.js`

* Location matching: `src/location.js` |

#### Configure the matching

The logic for both metadata and location matching can be configured according to your requirements.

* Metadata matching

  The metadata matching script uses recursive iteration to compare the metadata obtained from the client with the stored metadata. It is written with small to moderately large sized JavaScript objects in mind, and not optimized for very large or very deep structures.

  When the recursion reaches a primitive value in the JSON, such as a string, number, or boolean, it does a comparison of the associated values. If there's a mismatch, it increments a counter.

  You can modify this behavior as follows:

  1. Configure the `maxUnmatchedAttrs` parameter to specify the maximum allowed number of allowed mismatches.

  2. Alter the "weight" of specific attributes in the JSON, by using the `attrWeights` parameter.

     The weightings assigned work alongside the configured maximum number of mismatches. For example, if `maxUnmatchedAttrs` is set to 2, this could be exceeded by having three attributes with the *default* weight of 1 that do not match (n=1+1+1), or you could have a single property with a weight of 3 that does not match (n=3).

     Configuring the weighting means you can assign lower importance to certain profile properties, like display width or height, which might vary if the user changes displays from the prior authentication.

     If you're less concerned with the display properties because they can easily change, and more concerned with things that will remain unchanged, like the device's memory, you can assign greater weight to them as appropriate.

  **Example**:

  ```javascript
  const config = {
    attrWeights: {
      // Custom weights for metadata attributes (object keys)
      deviceMemory: 3 // type `number`
      // ... as many attributes as you want
      // all attributes default to 1
    },
    maxUnmatchedAttrs: 2, // type `number`; default to 0 (exact match)
  };
  const [ metadataMatch ] = deviceMatcher(config);
  const isMetadataMatching = metadataMatch(client.metadata, stored.metadata);
  ```

* Location matching

  The location matching script does not internally compare geolocation coordinates. It uses an [external library called "geolib"](https://www.npmjs.com/package/geolib), which is well-built and very powerful.

  The script uses the `getDistance()` function from the library, and wraps it with a comparison of the distance between two points to that of the maximum allowed radius.

  Specify the maximum radius by using the `allowedRadius` parameter. All measurements are in meters. **Example**:

  ```javascript
  const config = {
    allowedRadius: 250, // type `number`; defaults to 100 (meters)
  };
  const [ _, locationMatch ] = deviceMatcher(config);
  const isLocationMatching = locationMatch(client.location, stored.location);
  ```

#### Build the script

To build the sample device match script, follow these steps:

1. Download the device match script project from the GitHub repository:

   `git clone https://github.com/ForgeRock/forgerock-device-match-script.git`

2. In a terminal window, navigate to the root of the device match script project:

   `cd forgerock-device-match-script`

3. Run `npm` to download and install the required packages and modules:

   `npm install`

4. Build the device match script with `npm`:

   `npm run build:widget`

5. Copy and paste the contents of the `dist/script.js` file into your ForgeRock server.

   The script type must be Decision node script for authentication trees in self-managed AM servers or Journey Decision Node in Advanced Identity Cloud deployments.

6. In your [Device Match node](https://docs.pingidentity.com/auth-node-ref/latest/device-match.html) configuration, select Use Custom Matching Script, and in the Custom Matching Script field, select the script you created in the previous step.

7. Click Save.

For information on testing the script as well as some frequently asked questions, refer to the [README.md](https://github.com/ForgeRock/forgerock-device-match-script/blob/master/README.md) in the repo.
