Collect Fingerprint logs

Supported in:

This document explains how to configure Fingerprint (formerly FingerprintJS) to push logs to Google Security Operations using webhooks.

Fingerprint is a device intelligence platform that provides visitor identification and fraud detection capabilities. It generates unique visitor identifiers and provides smart signals including bot detection, VPN detection, incognito mode detection, and other device intelligence insights. When a visitor is identified through the FingerprintJS JavaScript agent, webhooks can send the identification event data to Google Security Operations in real time.

Before you begin

Ensure that you have the following prerequisites:

  • A Google SecOps instance
  • FingerprintJS account with webhook support
  • Access to Google Cloud Console (for API key creation)
  • FingerprintJS JavaScript agent installed on your website or application

Create webhook feed in Google SecOps

Create the feed

  1. Go to SIEM Settings > Feeds.
  2. Click Add New Feed.
  3. On the next page, click Configure a single feed.
  4. In the Feed namefield, enter a name for the feed (for example, FingerprintJS Identification Events ).
  5. Select Webhookas the Source type.
  6. Select FingerprintJSas the Log type.
  7. Click Next.
  8. Specify values for the following input parameters:
    • Split delimiter(optional): Leave empty. Each webhook request contains a single identification event.
    • Asset namespace: The asset namespace .
    • Ingestion labels: The label to be applied to the events from this feed.
  9. Click Next.
  10. Review your new feed configuration in the Finalizescreen, and then click Submit.

Generate and save secret key

After creating the feed, you must generate a secret key for authentication:

  1. On the feed details page, click Generate Secret Key.
  2. A dialog displays the secret key.
  3. Copy and save the secret key securely.

Important: The secret key is displayed only once and cannot be retrieved later. If you lose it, you must generate a new secret key.

Get the feed endpoint URL

  1. Go to the Detailstab of the feed.
  2. In the Endpoint Informationsection, copy the Feed endpoint URL.
  3. The URL format is:

     https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate 
    

    or

     https://<REGION>-malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate 
    
  4. Save this URL for the next steps.

  5. Click Done.

Create Google Cloud API key

Chronicle requires an API key for authentication. Create a restricted API key in the Google Cloud Console.

Create the API key

  1. Go to the Google Cloud Console Credentials page .
  2. Select your project (the project associated with your Chronicle instance).
  3. Click Create credentials > API key.
  4. An API key is created and displayed in a dialog.
  5. Click Edit API keyto restrict the key.

Restrict the API key

  1. In the API keysettings page:
    • Name: Enter a descriptive name (for example, Chronicle FingerprintJS Webhook API Key ).
  2. Under API restrictions:
    1. Select Restrict key.
    2. In the Select APIsdropdown, search for and select Google SecOps API(or Chronicle API).
  3. Click Save.
  4. Copy the API key value from the API keyfield at the top of the page.
  5. Save the API key securely.

Configure FingerprintJS webhook

Construct the webhook URL

  • Combine the Chronicle endpoint URL and API key:

     < ENDPOINT_URL 
    > ? 
     key 
     = 
    < API_KEY 
    > 
    
    • Example:

       https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD... 
      

Create webhook in FingerprintJS Dashboard

  1. Sign in to the FingerprintJS Dashboard.
  2. Go to Dashboard > Webhooks.
  3. Click Add webhook.
  4. Provide the following configuration details:
    • URL: Paste the complete endpoint URL with API key from above.
    • Environment(optional): If you select an environment, your webhook will only report on events from a matching environment. Leave empty to receive events from all environments.
    • Basic authentication(optional): Expand Basic authenticationif you want to add additional authentication. For Chronicle integration, you can leave this empty as authentication is handled via the API key and secret key.
  5. Click Create Webhook.
  6. A success modal displays Webhooks created.
  7. Important: If you are using webhook signatures (Enterprise plan only), copy and save the encryption key shown in the success modal. The key is displayed only once.

Add Chronicle secret key to webhook

FingerprintJS does not support custom HTTP headers during webhook creation. You must add the Chronicle secret key as a query parameter in the webhook URL.

  • Update the webhook URL to include the secret key:

     < ENDPOINT_URL 
    > ? 
     key 
     = 
    < API_KEY>&secret 
     = 
    < SECRET_KEY 
    > 
    
    • Example:

       https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234... 
      

To update the webhook URL:

  1. In the FingerprintJS Dashboard, go to Dashboard > Webhooks.
  2. Find your webhook in the table and click the Editicon.
  3. Update the URLfield with the complete URL including both API key and secret key.
  4. Click Edit webhook.

Test the webhook

  1. In the FingerprintJS Dashboard, go to Dashboard > Webhooks.
  2. Find your webhook in the table.
  3. Click Send test event.
  4. Wait for confirmation that the test event was sent successfully.
  5. Verify the webhook shows a successful delivery status.

Authentication methods reference

Chronicle webhook feeds support multiple authentication methods. FingerprintJS webhooks use query parameters for authentication.

Query parameters method

FingerprintJS does not support custom HTTP headers during webhook creation, so credentials must be appended to the URL.

  • URL format:

     < ENDPOINT_URL 
    > ? 
     key 
     = 
    < API_KEY>&secret 
     = 
    < SECRET_KEY 
    > 
    
    • Example:

       https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate?key=AIzaSyD...&secret=abcd1234... 
      
  • Request format:

      POST <ENDPOINT_URL>?key=<API_KEY>&secret=<SECRET_KEY> HTTP/1.1 
     Content-Type: application/json 
     { 
     "visitorId": "3HNey93AkBW6CRbxV6xP", 
     "requestId": "1708102555327.NLOjmg", 
     "timestamp": 1582299576512 
     } 
     
    

UDM mapping table

Log Field UDM Mapping Logic
rawDeviceAttributes.architecture.value, rawDeviceAttributes.audio.value, rawDeviceAttributes.colorDepth.value, rawDeviceAttributes.colorGamut.value, rawDeviceAttributes.contrast.value, rawDeviceAttributes.cookiesEnabled.value, rawDeviceAttributes.deviceMemory.value, rawDeviceAttributes.fonts.value, rawDeviceAttributes.forcedColors.value, rawDeviceAttributes.hardwareConcurrency.value, rawDeviceAttributes.hdr.value, rawDeviceAttributes.indexedDB.value, rawDeviceAttributes.localStorage.value, rawDeviceAttributes.math.value, rawDeviceAttributes.monochrome.value, rawDeviceAttributes.openDatabase.value, rawDeviceAttributes.pdfViewerEnabled.value, rawDeviceAttributes.reducedMotion.value, rawDeviceAttributes.screenFrame.value, rawDeviceAttributes.screenResolution.value, rawDeviceAttributes.sessionStorage.value, rawDeviceAttributes.touchSupport.value.maxTouchPoints, rawDeviceAttributes.languages.value, rawDeviceAttributes.vendorFlavors.value, rawDeviceAttributes.fontPreferences.value.apple, rawDeviceAttributes.fontPreferences.value.default, rawDeviceAttributes.fontPreferences.value.min, rawDeviceAttributes.fontPreferences.value.mono, rawDeviceAttributes.fontPreferences.value.sans, rawDeviceAttributes.fontPreferences.value.serif, rawDeviceAttributes.fontPreferences.value.system
additional.fields Merged from labels created from source fields
has_principal, has_target, has_target_resource
metadata.event_type Set to "NETWORK_CONNECTION" if has_principal and has_target true, else "USER_RESOURCE_ACCESS" if has_target_resource true, else "STATUS_UPDATE" if has_principal true, else "GENERIC_EVENT"
source_type
metadata.product_event_type Value copied directly
requestId
metadata.product_log_id Value copied directly
browserDetails.userAgent
network.http.parsed_user_agent Parsed from browserDetails.userAgent
browserDetails.browserName
network.http.parsed_user_agent.browser Value copied directly
browserDetails.browserFullVersion
network.http.parsed_user_agent.browser_version Value copied directly
browserDetails.device
network.http.parsed_user_agent.device Value copied directly
network.http.parsed_user_agent.family Set to "USER_DEFINED"
browserDetails.os
network.http.parsed_user_agent.os Value copied directly
browserDetails.clientReferrer
network.http.referral_url Value copied directly
browserDetails.userAgent, userAgent
network.http.user_agent Value from userAgent if not empty, else browserDetails.userAgent
tag.session
network.session_id Value copied directly
rawDeviceAttributes.vendor.value
principal.administrative_domain Value copied directly
ip
principal.asset.ip Value copied directly
ip
principal.ip Value copied directly
ipInfo.v4.geolocation.city.name
principal.location.city Value copied directly
ipInfo.v4.geolocation.country.name
principal.location.country_or_region Value copied directly
ipInfo.v4.geolocation.latitude
principal.location.region_coordinates.latitude Converted to float
ipInfo.v4.geolocation.longitude
principal.location.region_coordinates.longitude Converted to float
browserDetails.osVersion, rawDeviceAttributes.platform.value
principal.platform_version Value from rawDeviceAttributes.platform.value if not empty, else browserDetails.osVersion
ipInfo.v4.asn.asn, ipInfo.v4.asn.network, ipInfo.v4.asn.name, ipInfo.v4.geolocation.accuracyRadius, ipInfo.v4.geolocation.continent.name, ipInfo.v4.geolocation.timezone, ipInfo.v4.geolocation.subdivisions.isoCode, ipInfo.v4.geolocation.subdivisions.name
principal.resource.attribute.labels Merged from labels created from source fields
bot.result, browserDetails.browserMajorVersion, confidence.score, confidence.revision, developerTools.result, highActivity.result, incognito, ipBlocklist.result, ipBlocklist.details.attackSource, ipBlocklist.details.emailSpam, visitorFound, visitorId, tag.request, privacySettings.result, proxy.result, suspectScore.result, tor.result, virtualMachine.result, tampering.anomalyScore, tampering.antiDetectBrowser, tampering.result, vpn.confidence, vpn.originCountry, vpn.originTimezone, vpn.result, vpn.methods.auxiliaryMobile, vpn.methods.osMismatch, vpn.methods.publicVPN, vpn.methods.timezoneMismatch, velocity.distinctCountry.intervals.1h, velocity.distinctCountry.intervals.24h, velocity.distinctCountry.intervals.5m, velocity.distinctIp.intervals.1h, velocity.distinctIp.intervals.24h, velocity.distinctIp.intervals.5m, velocity.events.intervals.1h, velocity.events.intervals.24h, velocity.events.intervals.5m, velocity.ipEvents.intervals.1h, velocity.ipEvents.intervals.24h, velocity.ipEvents.intervals.5m, rawDeviceAttributes.webGlBasics.value.renderer, rawDeviceAttributes.webGlBasics.value.rendererUnmasked, rawDeviceAttributes.webGlBasics.value.vendorUnmasked, rawDeviceAttributes.webGlBasics.value.shadingLanguageVersion, rawDeviceAttributes.webGlExtensions.value.contextAttributes, rawDeviceAttributes.webGlExtensions.value.extensions, rawDeviceAttributes.webGlExtensions.value.extensionParameters, rawDeviceAttributes.webGlExtensions.value.parameters, rawDeviceAttributes.webGlExtensions.value.shaderPrecisions, rawDeviceAttributes.mathML.value.bottom, rawDeviceAttributes.mathML.value.top, rawDeviceAttributes.mathML.value.left, rawDeviceAttributes.mathML.value.right, rawDeviceAttributes.mathML.value.width, rawDeviceAttributes.mathML.value.height, rawDeviceAttributes.mathML.value.font, rawDeviceAttributes.mathML.value.x, rawDeviceAttributes.mathML.value.y, rawDeviceAttributes.emoji.value.bottom, rawDeviceAttributes.emoji.value.top, rawDeviceAttributes.emoji.value.left, rawDeviceAttributes.emoji.value.right, rawDeviceAttributes.emoji.value.width, rawDeviceAttributes.emoji.value.height, rawDeviceAttributes.emoji.value.font, rawDeviceAttributes.emoji.value.x, rawDeviceAttributes.emoji.value.y, rawDeviceAttributes.canvas.value.Geometry, rawDeviceAttributes.canvas.value.Text, rawDeviceAttributes.canvas.value.Winding
security_result.detection_fields Merged from labels created from source fields
rawDeviceAttributes.webGlBasics.value.vendor
target.administrative_domain Value copied directly
ipInfo.v6.address
target.asset.ip Value copied directly
ipInfo.v6.address
target.ip Value copied directly
ipInfo.v6.geolocation.city.name
target.location.city Value copied directly
ipInfo.v6.geolocation.country.name
target.location.country_or_region Value copied directly
ipInfo.v6.geolocation.latitude
target.location.region_coordinates.latitude Converted to float
ipInfo.v6.geolocation.longitude
target.location.region_coordinates.longitude Converted to float
path
target.path Value copied directly
rawDeviceAttributes.webGlBasics.value.version
target.platform_version Value copied directly
ipInfo.v6.asn.asn, ipInfo.v6.asn.network, ipInfo.v6.asn.name, ipInfo.v6.geolocation.accuracyRadius, ipInfo.v6.geolocation.continent.name, ipInfo.v6.geolocation.timezone, ipInfo.v6.geolocation.subdivisions.isoCode, ipInfo.v6.geolocation.subdivisions.name
target.resource.attribute.labels Merged from labels created from source fields
url
target.url Value copied directly
metadata.product_name Set to "FINGERPRINT_JS"
metadata.vendor_name Set to "FINGERPRINT_JS"

Need more help? Get answers from Community members and Google SecOps professionals.

Create a Mobile Website
View Site in Mobile | Classic
Share by: