AWS CloudFront Proxy Integration v2

Fingerprint CloudFront Proxy Integration is responsible for proxying identification and agent-download requests between your website and Fingerprint through your AWS infrastructure. Your website does not strictly need to be behind CloudFront or run on AWS to use this proxy integration, although that is optimal for ease of setup and maximum accuracy benefits.

👍

Migrating from v1

If you are using CloudFront proxy integration v1 and want to upgrade to v2 without downtime or client-side changes, you can follow Migrating CloudFront proxy integration from v1 to v2.

📘

Improvements over v1

  • More robust and secure auto-update mechanism: The v1 update mechanism, relying on CodePipeline and S3 triggers, was broken by AWS changes. The v2 update mechanism is based on Fingerprint sending authenticated HTTP requests to the integration's Management Lambda function. You manually provide the Management function URL and token to the Fingerprint dashboard. Fingerprint stores the token in encrypted form.
  • Lower footprint and improved performance: By removing internal dependencies, the shipped Lambda function code has been reduced by 97% to 740 lines.
  • Updated Node runtime:The v1 Lambda functions run on Node 16, which AWS is deprecating. The v2 Lambda functions run on Node 20.

🚧

Limitations

The AWS CloudFront Proxy Integration is accessible and exclusively supported for customers on the Enterprise Plan. Other customers are encouraged to use Custom subdomain setup or Cloudflare Proxy Integration.

🚧

Update expectations

The underlying data contract in the identification logic can change to keep up with browser and device releases. Using the AWS CloudFront Proxy Integration might require occasional manual updates on your side. Ignoring these updates will lead to lower accuracy or service disruption.

The integration consists of several components:

  • Your website, which may be running on AWS CloudFront but doesn't have to.
  • An AWS CloudFront distribution
    • If your website is already running on CloudFront, you can use the same distribution for the proxy integration. This is the recommended setup to maximize the accuracy benefits of the integration. See Step 3.2 for more details.
    • If your website is not running on CloudFront, you can create a new CloudFront distribution just for the proxy integration (see Step 3.2).
  • AWS Lambda@Edge Function that handles proxying requests to Fingerprint resources. We will refer to it as "Lambda function" going forward. It is available on a specific path on your site. The rest of your site is not affected.
  • Management Lambda function that is responsible for updating the integration. We will refer to it as "Management function" going forward.
  • Additional cache behavior that enables using a Lambda function for proxying requests.
  • AWS Secrets that store settings for Lambda and Management functions.
  • A CloudFormation template and stack responsible for deploying the AWS resources listed above.

The Lambda proxy function code and the entire CloudFormation stack are 100% open-source and available on GitHub. Once the Fingerprint JavaScript agent is configured on your site correctly, the Lambda function is responsible for delivering the latest fingerprinting client-side logic as well as proxying identification requests and responses between your site and Fingerprint APIs.

The benefits of using the CloudFront Integration

  • Ad blockers will not block the Fingerprint JS agent from loading. Connecting to an external URL is stopped by most ad blockers but connecting to the same site URL is allowed.
  • Significant increase in accuracy in browsers with strict privacy features such as Safari or Firefox.
  • Cookies are now recognized as “first-party.” This means they can live in the browser even when third-party cookies are blocked and extend the lifetime of visitor information.
  • Insight and control over the identification requests that can be combined with other AWS features like CloudWatch.
  • With the CloudFront Integration, you can manage an unlimited number of subdomains and paths. You can package and provide Fingerprint services to all your customers at any scale while benefiting from all the 1st-party integration improvements.
  • Cookie security: CloudFront integration drops all cookies sent from the origin website. The Lambda function code is open-source so this behavior can be transparently verified and audited.
  • Easy to meet compliance and auditing requirements.

Prerequisites

  • An AWS account.
  • Optionally: An existing CloudFront distribution that serves your web application.
    • If your application does not run on CloudFront, this guide will help you create a new CloudFront distribution that is deployed on the same eTLD + 1 domain as your website, or any of its subdomains - see Step 3.2.

Integration setup overview

The integration setup consists of several manual and automatic steps. Each step is discussed in detail below.

  1. Issue a proxy secret in the Fingerprint Dashboard.
  2. Create path variables used by the AWS configuration and JavaScript agent configuration on your website.
  3. Install the CloudFormation application containing all the necessary resources for the integration.
  4. Configure the CloudFront distribution with the integration's Lambda function and cache behavior.
  5. Configure the Fingerprint JavaScript agent on your website or client application.
  6. Enable automatic updates of your integration in the Fingerprint Dashboard.

Step 1: Issue a proxy secret

Your integration needs a proxy secret to authenticate requests from your Lambda function to Fingerprint servers.

  1. Go to the Fingerprint Dashboard and select your application in the top left.
  2. Navigate to App settings > API Keys.
  3. Click Create proxy key.
  4. Name it something like CloudFront integration.
  5. Click Create API key.
  6. Save the secret value somewhere. You will use it in the Step 3.2 as the FPJS_PRE_SHARED_SECRET variable.

Step 2: Create path variables

You need to set the path variables you will use throughout your AWS configuration (Step 3.2) and the JS agent configuration on your website (Step 5). These values are arbitrary. Just decide what your values are and write them down somewhere.

In this guide, we will use readable values corresponding to the variable names to make it easier to follow:

FPJS_BEHAVIOR_PATH="FPJS_BEHAVIOR_PATH"
FPJS_AGENT_DOWNLOAD_PATH="FPJS_AGENT_DOWNLOAD_PATH"
FPJS_GET_RESULT_PATH="FPJS_GET_RESULT_PATH"

However, your values used in production should look more like random strings:

FPJS_BEHAVIOR_PATH="ore54guier"
FPJS_AGENT_DOWNLOAD_PATH="vbcnkxb654"
FPJS_GET_RESULT_PATH="5yt489hgfj"

That is because some adblockers might automatically block requests from any URL containing fingerprint-related terms like "fingerprint", "fpjs", "track", etc. Random strings are the safest. So whenever you see a value like FPJS_BEHAVIOR_PATH in this guide, you should use your random value instead.

Step 3: Install the CloudFormation application

The Lambda proxy function and associated resources are provided as a CloudFormation template.

Step 3.1: Create CloudFormation stack

  1. Go to the CloudFormation installation wizard to open the deployment dialog.
  2. Select the us-east-1 region in your AWS console before deploying the application. Due to AWS limitations, the Lambda proxy function, and therefore the entire CloudFormation stack, must be deployed to the us-east-1 region.
  3. Keep predefined settings:
    1. Prepare template is Choose an existing template.
    2. Specify template is Amazon S3 URL.
    3. Amazon S3 URL is https://fingerprint-pro-cloudfront-integration.s3.amazonaws.com/v2/template.yml
  4. Click Next.

Step 3.2: Specify stack details

Provide a stack name and fill in the required template parameters.

  • Set FpjsAgentDownloadPath to the FPJS_AGENT_DOWNLOAD_PATH value defined in Step 2.
  • Set FpjsGetResultPath to the FPJS_GET_RESULT_PATH value defined in Step 2.
  • Set FpjsPreSharedSecret to the FPJS_PRE_SHARED_SECRET value you created in Step 1.

In this step, you need to choose between using an existing CloudFront distribution or creating a new one.

A) Use an existing CloudFront distribution (recommended)

If your website is already running on CloudFront, you can use the same distribution and domain for the proxy integration.

This is the recommended setup. Your website and the proxy function will be same-site, served from the same IP address or IP address range. Having the same or similar IP improves cookie lifetimes in Safari — they will be stored in the browser for up to one year instead of 7 days.

  • Set DistributionId to the identifier of your existing CloudFront distribution.

B) Create a new CloudFront distribution

If your website is not running on CloudFront, you can create a new CloudFront distribution and website subdomain just for the proxy integration.

This setup limits Safari cookie lifetime to 7 days. Because your website and the Lambda proxy function will likely have different IP ranges, Safari will apply the same cookie lifetime cap as for third-party CNAME cloaking. This is still an improvement over third-party cookies getting blocked entirely by Safari. But we recommend serving your website and the proxy integration using the same CloudFront distribution if possible (option A above).

  • Leave DistributionId empty. The template will create and configure a new CloudFront distribution for you.
  • If you want to attach an alternate domain name and custom SSL certificate to the new CloudFront distribution, fill in these parameters:
    • Set ACMCertificateARN to the ARN identifier of your SSL certificate in the AWS Certificate Manager.
    • Set DomainNames to a list of plus-separated domain names, for example: domain1.com or domain1.com+domain2.com. These will be attached to the created CloudFront distribution.
      The deployment will fail if any of the domain names is not covered by the certificate or if it is already used as an alternate name for another CloudFront distribution.

Once you have made your choice, click Next.

Note: This application creates the custom IAM roles that allow us to modify CloudFront distribution to keep the Lambda@Edge function up to date. You can review these policies in the CloudFormation template.

Step 3.3: Configure stack options

Fingerprint Pro integration has no specific stack options to configure at this step. You can change them depending on your internal requirements.

Click Next.

Step 3.4: Review and create

  1. Review the Parameters section.
  2. In the Capabilities and transforms section:
    1. Check I acknowledge that AWS CloudFormation might create IAM resources.
    2. Check I acknowledge that AWS CloudFormation might create IAM resources with customized names.
    3. Check I acknowledge that AWS CloudFormation might require the following capability: CAPABILITY_AUTO_EXPAND
  3. Click Submit.

After deployment, you will be redirected to the CloudFormation Stacks page where you can see a list of resources created by the application.

3010

CloudFormation stack resources.

  • The Status indicates the current state of deployment. It starts from REVIEW_IN_PROGRESS to CREATE_IN_PROGRESS, and finally CREATE_COMPLETE.
  • If you see a different status (CREATE_FAILED, ROLLBACK_IN_PROGRESS, ROLLBACK_COMPLETE, etc), please contact our support team.

Once the application is fully deployed (stack has the status CREATE_COMPLETE), you can switch to the Outputs tab, and find the names of created entities.

  • The Export name of LambdaFunctionName is a unique name of the created Lambda proxy function.
  • The Export name of FingerprintProMgmtLambda is a unique name of the created Management function responsible for delivering updates to the main Lambda proxy function.
  • The Value of CloudFrontDistributionId is an internal ID of the CloudFront distribution created by the CloudFormation template or your existing CloudFront distribution that you specified in Step 3.2.A.
  • The Export name of FingerprintIntegrationSettingsSecret is the name of the AWS Secret for the Lambda proxy function. You can save this value somewhere. You might need it in Step 4.1.
  • The Export name of CachePolicyName is a unique name of the CloudFront cache policy, which will be applied in a cache behavior for Fingerprint requests. You can save this value somewhere. You might need it in Step 4.2.
  • The Value of MgmtLambdaFunctionUrl is a public URL of the management Lambda function. You can save this value somewhere. You will need it later to enable automatic updates for your integration in Step 6.

🚧

Do not disrupt the Management function

The Management Lambda function (FingerprintProMgmtLambda) deployed alongside the main proxy function is responsible for updating the integration. It makes sure visitor identification on your website keeps up with new browser releases and fingerprinting evasion techniques. An outdated integration can lead to lower accuracy or break visitor identification completely. Don't disable or delete the management function.

Step 4: Configure the CloudFront distribution

  • If you are using an existing CloudFront distribution already serving your website (you have specified DistributionId in Step 3.2.A), start from Step 4.1 to configure your distribution for the proxy integration.
  • If you decided to create a new CloudFront distribution (you have left DistributionId empty in Step 3.2.B), the CloudFormation template has deployed a new CloudFront distribution already pre-configured to serve the proxy integration.
    1. Attach an alternate domain name and CNAME if you haven't specified it in Step 3.2.B.
    2. Continue to Step 5.

Step 4.1: Create a new origin

  1. Go to your CloudFront distribution, switch to the Origins tab, and click Create origin.
  2. Fill in the required fields:
    1. Set Origin domain to fpcdn.io.
    2. Set Protocol to HTTPS only.
    3. Set Minimum origin SSL protocol to TLSv1.2.
    4. Set Name to fpcdn.io.
    5. Add a custom header:
      • Set Header name to FPJS_SECRET_NAME
      • Set Value to the Export name of FingerprintIntegrationSettingsSecret created in Step 3.4.
    6. Finally, click Create origin.

Step 4.2: Create a cache behavior

In this step, you will create a cache behavior to proxy requests to the Fingerprint API.

  1. Go to your CloudFront distribution.
  2. Switch to the Behaviors tab and click Create behavior.
  3. Fill in the required fields:
    1. Set Path pattern to a value that matches all routes under FPJS_BEHAVIOR_PATH. For example, if FPJS_BEHAVIOR_PATH=random-path fill in random-path/*.
    2. Set Origin and origin groups to fpcdn.io.
    3. Set the Viewer protocol policy to Redirect HTTP to HTTPS.
    4. Set the Allowed HTTP methods to GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE.
    5. Set Cache key and origin requests to Cache policy and origin request policy (recommended).
    6. Set Cache policy to a Custom policy named FingerprintProCDNCachePolicy-{id}. You can find the name of your cache policy in CloudFormation > Stacks > _ > _Outputs as the Export name of CachePolicyName.
    7. Set Origin request policy to AllViewer.
    8. Click Create behavior.

🚧

Do not change the provided Cache Policy

It is intentionally configured with the minimum TTL of 0. Misconfiguring the policy could disrupt visitor identification and increase false positives (assigning the same visitor ID to different browsers).

Step 4.3: Attach the Lambda function to the cache behavior

  1. Go to CloudFormation > Stacks and open your newly created stack (named Fingerprint-Pro-Cloudfront-Integration-v2 by default).
  2. Switch to the Resources tab, find the resource with the Logical ID of FingerprintProCloudFrontLambda and click the link in the corresponding Physical ID column.

CloudFormation Lambda function

  1. Scroll down and switch to the Configuration tab.
  2. On the left, click Triggers, then click Add trigger.
  3. Select CloudFront as the source and click Deploy to Lambda@Edge.
1644

Add a trigger for the Lambda function.

  1. Select Configure new CloudFront trigger.
    1. Select your distribution.
    2. Select the cache behavior you created in the previous step.
    3. Set CloudFront event to Origin Request.
    4. Check Include body.
    5. Check Confirm deploy to Lambda@Edge.
    6. Click Deploy.

It may take several minutes to add the trigger to the CloudFront distribution. To monitor the progress, go to your CloudFront distribution, switch to the General tab, and check the Last modified time.

Step 5: Configure the Fingerprint JavaScript agent on your client

Use the path variables created in Step 2 to construct the agent-download and result-endpoint URLs.

If your website and the proxy integration are behind the same CloudFront distribution (you chose Step 3.2.A), the JavaScript Agent configuration will use randomized paths inside your domain, for example:

import * as FingerprintJS from '@fingerprintjs/fingerprintjs-pro'

// Initialize the agent at application startup.
const fpPromise = FingerprintJS.load({
  apiKey: 'PUBLIC_API_KEY',
  scriptUrlPattern: [
    'https://yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_AGENT_DOWNLOAD_PATH?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>',
    FingerprintJS.defaultScriptUrlPattern, // Fallback to default CDN in case of error
  ],
  endpoint: [
    'https://yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_GET_RESULT_PATH?region=us',
    FingerprintJS.defaultEndpoint // Fallback to default endpoint in case of error
  ],
});
const url = 'https://yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_AGENT_DOWNLOAD_PATH?apiKey=<PUBLIC_API_KEY>';
const fpPromise = import(url)
  .then(FingerprintJS => FingerprintJS.load({
    endpoint: [
      'https://yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_GET_RESULT_PATH?region=us',
      FingerprintJS.defaultEndpoint // Fallback to default endpoint in case of error
    ]
  }));

If you set up a separate CloudFront distribution on your subdomain according to Step 3.2.B, the JavaScript Agent configuration will use that subdomain to interact with Fingerprint, for example:

import * as FingerprintJS from '@fingerprintjs/fingerprintjs-pro'

// Initialize the agent at application startup.
const fpPromise = FingerprintJS.load({
  apiKey: 'PUBLIC_API_KEY',
  scriptUrlPattern: [
    'https://metrics.yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_AGENT_DOWNLOAD_PATH?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>',
    FingerprintJS.defaultScriptUrlPattern, // Fallback to default CDN in case of error
  ],
  endpoint: [
    'https://metrics.yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_GET_RESULT_PATH?region=us',
    FingerprintJS.defaultEndpoint // Fallback to default endpoint in case of error
  ],
});
const url = 'https://metrics.yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_AGENT_DOWNLOAD_PATH?apiKey=<PUBLIC_API_KEY>';
const fpPromise = import(url)
  .then(FingerprintJS => FingerprintJS.load({
    endpoint: [
      'https://metrics.yourwebsite.com/FPJS_BEHAVIOR_PATH/FPJS_GET_RESULT_PATH?region=us',
      FingerprintJS.defaultEndpoint // Fallback to default endpoint in case of error
    ]
  }));

📘

Parameter URL nuances

  • Note that the import url for the CDN installation method and scriptUrlPattern used by the NPM package are similar but different and cannot be used interchangeably.
  • Pay attention to differences in query parameters:
    • Pass region to the endpoint parameters in the following format: ?region=eu. The value needs to reflect the region of you application.
    • Leave the scriptUrlParam parameter as displayed here: ?apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>. The apiKey version and loaderVersion parameters will be replaced by the values in the NPM package automatically. Do not alter them manually.

If everything is configured correctly, you should receive data through your CloudFront distribution successfully.

Step 6: Enable automatic updates in the Fingerprint Dashboard

Keeping the integration up to date is crucial for maintaining maximum identification accuracy. To enable automatic updates, provide the following Management function settings from AWS to the Fingerprint dashboard:

  • The public URL of the Management function.
  • An authentication token for the Management function.

When a new version of the proxy integration is available, Fingerprint will trigger an update by sending a request to the Management function URL, authenticated with the provided token. The token has only the permissions necessary for this purpose. You can verify the granted permissions in the Management function's Execution role (Stack > Resources > FpMgmtLambdaFunctionExecutionRole).

🚧

Note: Only users with the Owner or Admin role assigned can enable automatic updates for the integration in the Dashboard.

Step 6.1: Find the Management function details in AWS

  1. Go to CloudFormation > Stacks and open your newly created stack (named Fingerprint-Pro-Cloudfront-Integration-v2 by default).

  2. Switch to the Outputs tab. The Value of MgmtLambdaFunctionUrl is a public URL of your Management Lambda function. Save it somewhere.

  3. Switch to the Resources tab. Click the Physical ID of the MgmtSettingsSecret.

  4. Inside the secret page, click Retrieve secret value and copy the token value. This is the authentication token for the Management Lambda function. Save it somewhere.

Step 6.2: Provide the Management function details to the Fingerprint Dashboard

  1. Go to Dashboard > App Settings > Integrations > AWS CloudFront
  2. Click Enable updates.
  3. Fill in the values of CloudFront Management Lambda URL and Authentication Token that you retrieved in Step 6.1.
  4. Click Save Changes.

The integration page will show Status: Updates enabled and Fingerprint will automatically keep your integration up to date.

Monitoring and managing the integration

Go to Dashboard > App Settings > Integrations > AWS CloudFront to see the status of your integration. Here you can monitor:

  • If automatic updates are enabled.
  • If the integration is up to date.
  • How many identification requests are coming through the integration (and how many are not).
  • The error rate of proxied identification requests (caused by missing or incorrect proxy secret).

The information on the status page is cached so allow a few minutes for the latest data points to be reflected.

You can also disable automatic updates (not recommended) or update the provided Management function details.

Troubleshooting

If you run into problems, please provide our support team with the following information:

  1. Open the integration CloudFormation stack.
  2. Go to the Events tab, and copy the contents of the Status reason column for any failed statuses.

Cost calculation for AWS

You can use AWS Calculator to estimate your expenses.

Lambda@Edge service

  • The number of requests is roughly equal to visitor identification events multiplied by three.
    There are up to 3 requests for each visitor identification.
    • The first request downloads the agent script. This request is typically cached by the browser.
    • The second request calls the identification endpoint. Caching the identification request is up to you, but most of our frontend libraries have a caching mechanism built-in.
    • Potentially a third helper request may be used to improve accuracy. This request is typically cached by the browser.
  • The duration of each request depends on your CloudFront availability settings. The typical duration of the agent download request is 200ms, for identification requests it is 500ms.
  • The amount of memory allocated is 128MB.
  • The Lambda function has CloudWatch logs enabled.

Secrets Manager

  • The number of secrets is 2.
  • The number of API calls is approximately 12 calls per hour per each used AWS region.

Additional costs for the CloudFront distribution

  • Data transfer from CloudFront distribution to clients:
    • The agent’s size is about 36kB.
    • The identification request result is up to 1kB per request.
  • Data transfer from clients to the CloudFront distribution:
    • The payload size for the identification requests is approximately 5-10kB.