Identity verification

Identity verification adds an additional security layer to your Userflow.js snippet, by requiring a special signature, which only your back-end can compute via a secret key provided by Userflow. This prevents malicious third parties from posting data to Userflow on behalf of your users.

We strongly recommend that you configure and enforce identity verification to safe-guard your users’ information.

Security issues mitigated by identity verification

Without identity verification, a malicious third party could send/read data to/from Userflow on behalf of a user/company that they know the ID of, and:

  • Update their attributes in Userflow.
  • Track events on behalf of them.
  • Start/dismiss flows, checklists and launchers for them.
  • Respond to surveys on behalf of them.
  • Under some circumstances, read the user’s attributes: If any of your content contains user attributes (e.g. a “Hi {name}” message), the third party could start this flow, and then obtain the user’s name from the content displayed.

Some of these risks are mitigated if your user IDs are not publicly accessible and not easily-guessable. If the third party does not know a user’s ID, they can’t impersonate that user. The third party could still pollute your Userflow account by creating users with arbitrary IDs, so we still recommend enforcing identity verification in this case.

Enforcing identity verification

In short: Compute the signature on your server, include it in your Userflow.js snippet, and tell Userflow to reject unverified clients.

Step 1: Compute the signature on your server

The signature is generated by computing a SHA-256 HMAC of the user’s ID (the same ID you later give to userflow.identify()) signed with your Userflow environment’s Secret Key. Note that each Userflow environment has a separate Secret Key, so make sure you grab the right one. Find it under Settings → Identity verification in Userflow.

Important: The Userflow Secret Key is a secret! Do not store it in your code repository, include it in your front-end code or otherwise expose it to third parties.

Your programming language probably has an easy way to compute HMAC. Here’s what it looks like in Node.js:

import crypto from 'crypto'

let signature = crypto
  .createHmac('sha256', 'USERFLOW_SECRET_KEY')
  .update(user.id)
  .digest('hex')

See more examples for other programming languages below.

If you’re using Companies, you also need to compute a signature for the companyId (the same ID you later give to userflow.group(companyId)).

Step 2: Pass the signature to Userflow.js

Include the signature (not the secret!) in your Userflow.js snippet (where you run userflow.identify()).

userflow.identify(
  // TODO: Replace with real user ID
  'USER_ID',
  {
    // TODO: Add your regular user attributes here
    name: 'NAME',
    email: 'EMAIL'
  },
  // Third argument is an options object
  {
    // TODO: Replace with computed user signature
    signature: 'SIGNATURE'
  }
)

If your app is a “Single-page application”, which gets the user’s ID and other info via an API call, you can include the computed signature in this API response, and add it to your snippet.

If you’re using Companies, you also need to include a signature (based on the companyId, not the user ID) in your userflow.group(companyId) call:

userflow.group(
  // TODO: Replace with real company ID
  'COMPANY_ID',
  {
    // TODO: Add your regular company attributes here
    name: 'NAME'
  },
  // Third argument is an options object
  {
    // TODO: Replace with computed group signature
    signature: 'SIGNATURE'
  }
)

Verify that your Userflow.js installation still works in your own app, and that the DevTools Console does not print any errors from Userflow. If you see any errors containing wording such as “Incorrect user identity verification signature”, it means that your signatures are incorrect.

Step 3: Enforce identity verification

In the Userflow UI under Settings → Identity verification, flip the Enforce identity verification switch to ON. Once done, any Userflow.js client not using correct identity verification will be rejected.

Recipes for computing signature in various programming languages

In all the cases below, replace USERFLOW_SECRET_KEY with your real Userflow environment’s Secret Key.

Node.js

import crypto from 'crypto'

let signature = crypto
  .createHmac('sha256', 'USERFLOW_SECRET_KEY')
  .update(user.id)
  .digest('hex')

PHP

hash_hmac(
  'sha256',
  $user->id,
  'USERFLOW_SECRET_KEY'
)

Ruby

OpenSSL::HMAC.hexdigest(
  'sha256',
  'USERFLOW_SECRET_KEY',
  user.id
)

Python

import hashlib
import hmac
import base64

"""
For Python 2.x use:
"""
message = bytes(user.id).encode('utf-8')
secret = bytes("USERFLOW_SECRET_KEY").encode('utf-8')

"""
For Python 3.x use:
"""
message = bytes(user.id, 'utf-8')
secret = bytes('USERFLOW_SECRET_KEY', 'utf-8')

signature = hmac.new(secret, message, digestmod=hashlib.sha256).hexdigest()

Elixir

:crypto.mac(:hmac, :sha256, "USERFLOW_SECRET_KEY", user.id)
  |> Base.encode16(case: :lower)

Got questions? We're here for you!

The best way to get help is to
We usually reply within 5 minutes
You can also send an email to support@userflow.com
We usually reply within a few hours