Skip to main content
Firebase Authentication is your source of truth. UserKit needs to know which of your users is on the page, and it will not take the page’s word for it — your server signs the claim.
The identity secret never enters the bundle. Never prefix it with NEXT_PUBLIC_, never render it into HTML, never send it to the browser to save a round trip. Whoever holds it can mint a verified session for any of your users.
The contract is the one on the federated identity page and nothing here changes it:

What Firebase supplies

One value: uid. Firebase is the provider that does not arrive as a cookie your server can read — the browser holds an ID token and sends it, and a token is a string anybody can compose. verifyIdToken is what turns it into a fact.
lib/firebase.ts
user.uid is also sitting in the browser, and it is deliberately not what gets sent. An id the page supplies is an id the page chose — signing it would let any visitor be anyone.

The server half

app/api/userkit-boot/route.ts
An ID token that will not verify answers 401, exactly as an absent one does. The difference is a detail about your verification that the browser has no use for.

The client half

getState().verified is true only when the HMAC checked out. Signed in to Firebase with verified: false means either the secret belongs to the other environment or the message signed was not exactly the external_id.

Session cookies work too

createSessionCookie is the other shape, and it makes this endpoint look like the Supabase one: read the cookie, verify it with verifySessionCookie, sign the uid. Nothing above the provider line changes.

Configuration

What does not travel

A Firebase ID token carries an email and an email_verified claim. They are statements about Firebase’s records, and they do not become identities in UserKit: an email sent through /v1/boot is stored as an attribute, does not resolve to an existing contact and does not become an identity edge. The HMAC proves the external_id and only the external_id. To prove an address, send a magic link or an email code — the two flows that arrive in it.

The full example

A runnable Next app with these files, an .env.example and the pieces this page leaves out.