Social logins provide a familiar and convenient way for users to access applications using their existing accounts from popular platforms like Google, Apple, or Facebook. Under the hood, this functionality is powered by OAuth - a robust authentication protocol that enables secure user verification through OpenID Connect (OIDC) tokens. This feature is available exclusively for sub-organization users.
Create API Key
Start the OAuth Login Flow
Initiate OAuth with Nonce
nonce
to sha256(publicKey)
based on the API public key. This binds the resulting OIDC token to the keypair.User Grants Permission
oidcToken
to the frontend.Send Credentials to Backend
oidcToken
and API public key to your backend.Get or Create a Turnkey Sub-organization
oidcToken
. If no sub-organization exists, it creates one using the identity in the token.Create a Session
oauth_login
with the oidcToken
, and API public key. Turnkey validates that the token’s nonce
matches sha256(publicKey)
and returns a session JWT. The backend sends this JWT to the frontend.You're Now Authenticated
x-stamp
header.issuer
(iss) – The OAuth provider that issued the token (e.g., https://accounts.google.com
)audience
(aud) – The OAuth app’s client IDsubject
(sub) – The unique identifier for the user in the OAuth provider’s systemaud
claim from the OIDC token is used as part of how sub-organizations are identified.
If a user logs in on one platform using the web client ID, and then later logs in on another platform using a different iOS client ID, the two tokens will have different aud
values. Because of this, Turnkey will not consider them the same identity.
To ensure users are recognized consistently across platforms, you must use the same OAuth client ID everywhere. In most cases, this means using your web client ID for web, iOS, and Android flows.
/.well-known/openid-configuration
for each domain. For Google for example, the issuer configuration is at accounts.google.com/.well-known/openid-configuration
. This JSON document contains, among other thing, a jwksUri
key. The value for this key is a URL hosting the list of currently-valid OIDC token signers.jwksUri
(e.g., for Google, the jwksUri
is googleapis.com/oauth2/v3/cert
). This is a list of public keys against which the secure enclave can verify tokens. Note: these public keys rotate periodically (every ~6hrs), hence it’s not possible to hardcode these public keys in our secure enclave code directly. We have to fetch them dynamically!iss
, aud
and sub
attributes against the registered OAuth providers on the Turnkey sub-organization. We also check exp
to make sure the OIDC token is not expired, and the nonce
attribute (see next section).
OAUTH_LOGIN
activity requires 2 parameters minimum:
oidcToken
: the base64 OIDC tokenpublicKey
: the client-side public key generated by the usernonce
claim is set to sha256(publicKey)
.
For example, if the public key is 0394e549c71fa99dd5cf752fba623090be314949b74e4cdf7ca72031dd638e281a
, our enclaves expect the OIDC token nonce to be 1663bba492a323085b13895634a3618792c4ec6896f3c34ef3c26396df22ef82
.
This restriction only applies during authentication (OAUTH
activity). Registration via CREATE_OAUTH_PROVIDER
and CREATE_SUB_ORGANIZATION
activities is not affected since these activities do not accept a publicKey
and do not return encrypted credentials as a result.
If your OAuth provider does not allow you to customize nonce
claims, Turnkey also accepts and validates tknonce
claims. This is an alternative claim that will be considered. Only one of (nonce
, tknonce
) needs to be set to sha256(publicKey)
; not both.
users:update
scope token can call this endpoint to arbitrarily link an identity.
For example, if a Google-authenticated user (OIDC token sub
claim: google-oauth2|118121659617646047510
) gets merged into a Twitter-authenticated user (OIDC token sub
claim: twitter|47169608
), the OIDC token obtained by logging in through Google post-merge will be twitter|47169608
. This can be surprising and lead to account takeover if an Auth0 admin is malicious. This is documented in Auth0’s own docs, here.
nonce
claims easily. To pass the hash of the end-user’s public key, use a custom tknonce
claim instead.