Guide for integrating Turnkey authentication into your backend, covering session JWT creation, validation, and enforcing user access controls.
Start the Signup Process
Generate Passkey and Temporary API Key
stampLogin()
request later in the flow, which would trigger a second prompt right after creating the passkey. Using the API key instead allows us to create the session in the background with just a single tap.Create a Turnkey Sub-organization
Create a Session
TurnkeyClient
using the temporary API key and calls stampLogin()
. Turnkey returns a session JWT representing the authenticated user session.You're Now Authenticated
Start the Login Process
Use Passkey to Authenticate
TurnkeyClient
with a passkeyStamper
and calls stampLogin()
. This triggers a WebAuthn prompt, prompting the user to approve the login request using their passkey.Create a Session
You're Now Authenticated
Start the Login Process
Request and Verify OTP
Get or Create a Turnkey Sub-organization
Create a Session
otpLogin()
with the subOrgId, public key, and verification token. Turnkey returns a session JWT representing the authenticated user session, which the backend then returns to the frontend.You're Now Authenticated
Authorization
header. This allows your backend to identify the authenticated user and enforce any necessary access control based on the user_id
or organization_id
.
Note: These requests are sent to your own backend endpoints and may contain any application-specific payload, such as a form submission, a database mutation, or a business action. They are not necessarily related to Turnkey.
Here’s an example of how the frontend might send the JWT:
Verify the Signature
verifySessionJwtSignature
from @turnkey/crypto
to confirm that the JWT was signed by Turnkey and hasn’t been modified.Decode the Session JWT
user_id
, organization_id
, and exp
.Here’s an example helper you can define to decode and extract the session fields from the payload:Check the Expiration
Extract and Enforce Access Controls
userId
and organizationId
to enforce access control in your application.This step is application-specific and depends on how your backend maps users to organizations. For example, you might:userId
organizationId