Setup guide V1 - 9 of 12

Secure your identify() call

Add a server-side HMAC signature so DropFix can verify that user identity data has not been tampered with.

HMAC verification

How it works

Without a signature, a user can open their browser DevTools and call identify() with any plan or MRR they want. DropFix would accept it.

With HMAC, your server signs the user ID with a secret key before sending it to the browser. DropFix recomputes the same signature server-side and rejects the call if the values do not match. The secret key never leaves your server.

Without HMAC

Any user can fake their own plan or MRR

With HMAC

Plan and MRR are cryptographically verified

Without HMAC

Identity data is trusted on the honour system

With HMAC

DropFix rejects tampered identify() calls

Without HMAC

Signals and digests may be based on wrong data

With HMAC

All churn signals use verified data only

Step 1 — Generate the signature on your server

On your backend, after login succeeds, generate an HMAC-SHA256 signature of the user ID using your DropFix secret key. Include a Unix timestamp so the signature expires after 5 minutes.

Node.js / Next.js
import { createHmac } from 'crypto'

const signed_at = Math.floor(Date.now() / 1000)
const dropfix_hash = createHmac('sha256', process.env.DROPFIX_SECRET_KEY)
  .update(user.id)
  .digest('hex')

// Return both to the frontend
return { user: { ...user, dropfix_hash, dropfix_signed_at: signed_at } }
Python
import hmac, hashlib, os, time

signed_at = int(time.time())
dropfix_hash = hmac.new(
  os.environ['DROPFIX_SECRET_KEY'].encode(),
  user.id.encode(),
  hashlib.sha256
).hexdigest()

# Return both to the frontend
return { 'dropfix_hash': dropfix_hash, 'dropfix_signed_at': signed_at }
Ruby
signed_at = Time.now.to_i
dropfix_hash = OpenSSL::HMAC.hexdigest(
  'SHA256',
  ENV['DROPFIX_SECRET_KEY'],
  user.id.to_s
)

# Return both to the frontend
render json: { dropfix_hash: dropfix_hash, dropfix_signed_at: signed_at }

Where to find your secret key

Go to DropFix -> Settings -> Security -> Secret Key. Store it in your server environment as DROPFIX_SECRET_KEY. Never put it in client-side code or commit it to version control.

Step 2 — Pass the signature in identify()

Return dropfix_hash and dropfix_signed_at from your login API and pass them to identify().

Frontend identify call
DropFix.identify(user.id, {
  name: user.name,
  email: user.email,
  plan: user.plan,
  mrr: user.mrr,
  signup_date: user.createdAt,
  signature: user.dropfix_hash,   // or hash: user.dropfix_hash
  signedAt: user.dropfix_signed_at,
})

Signature expires after 5 minutes

The signedAt timestamp lets DropFix reject signatures older than 5 minutes. Generate a fresh signature on every login — do not cache it between sessions.

What happens when verification fails

Situation

No signature sent

DropFix response

Request accepted — user stored as unverified

Situation

Wrong signature

DropFix response

401 returned — nothing stored

Situation

Signature older than 5 minutes

DropFix response

401 returned — nothing stored

Situation

Valid signature

DropFix response

200 returned — plan and MRR trusted and stored

Enable strict mode in Settings -> Security to reject all identify() calls that do not include a valid signature.