The flow at a glance
User logs in through Auth0
The user authenticates through the provider (
JavascriptProvider on web, ReactNativeProvider on mobile) via a popup or redirect. Auth0 issues an RS256-signed JWT identifying the user through its sub claim.App requests a signature with a `fatxn` claim
To sign a NEAR transaction, the app calls
requestTransactionSignature({ transaction }) (or requestDelegateActionSignature({ delegateAction })). The provider re-authenticates against Auth0 with the encoded transaction bound into the JWT as the custom fatxn claim. The result is a fresh JWT whose signature covers the exact payload to be signed.`FastAuth.sign` is called on-chain
The signer calls
sign(guard_id, verify_payload, sign_payload, algorithm) on the NEAR Auth contract (fast-auth.near / fast-auth.testnet). Here verify_payload is the Auth0 JWT, sign_payload is the transaction hash to be signed, and algorithm is one of secp256k1, ecdsa, or eddsa.`guard_id` prefix routes to the JWT Guard Router
FastAuth inspects the guard_id. When the prefix is jwt, it delegates verification to the JwtGuardRouter (jwt.fast-auth.near / jwt.fast-auth.testnet), which looks up the concrete guard by name.`Auth0Guard` verifies the JWT with RS256
The router forwards the request to the
Auth0Guard (auth0.jwt.fast-auth.near / auth0.jwt.fast-auth.testnet). The guard verifies the RS256 signature using owner-managed RSA public keys, then validates the claims: the issuer (iss), the audience (aud must contain the guard account), token validity (exp / nbf), and — critically — that the fatxn claim equals the sign_payload. This last check binds the JWT to exactly the transaction being signed, so a token can never be replayed against a different payload.MPC signs at `{guard_id}#{sub}`
On successful verification, the guard returns the user’s
sub, and FastAuth constructs the derivation path {guard_id}#{sub} (for example jwt#auth0#google-oauth2|123456789). It SHA-256 hashes the sign_payload and forwards the request to the MPC network (v1.signer / v1.signer-prod.testnet), which collaboratively produces a signature from distributed key shares — no single party ever holds the full key. Derivation is deterministic, so the same identity always controls the same NEAR account.Relayer submits the transaction
The signature is returned to the caller. Your app can broadcast the signed transaction directly, or hand it to a relayer to submit it — optionally gasless via a delegate action, so users transact without holding NEAR.
If verification or MPC computation fails, the deposit attached to cover gas and network fees is refunded to the original caller.
Contract interaction diagram
The diagram below traces a request through the on-chain contracts. TheFastAuth entry point routes to the JwtGuardRouter when the guard_id prefix is jwt, the router delegates to the matching guard, and — for Auth0 — verification succeeds without touching the Attestation contract, since Auth0 keys are owner-managed rather than attestation-based.
Attestation contract instead — covered under Protocol → Advanced.
Why guard_id routing matters
The guard_id is more than a lookup key — it’s the first segment of the MPC derivation path, and its prefix decides how verification happens.
- Prefix
jwttellsFastAuthto delegate to theJwtGuardRouter, which maintains a registry mapping each guard name to a guard contract account (add_guard,get_guard,remove_guard). For Auth0, the router resolves to theAuth0Guard. - The full
guard_idbecomes the leading component of the derivation path{guard_id}#{sub}. Because the guard is baked into the path, identities are isolated between providers: a Google user under Auth0 and a user under a different guard can never derive the same NEAR key, even if their subjects collide.
FastAuth entry point and the MPC signing step stay unchanged.
What each layer guarantees
| Layer | Responsibility | Guarantee |
|---|---|---|
FastAuth | Entry point; routes by guard_id, coordinates MPC signing | The signature is only requested after a guard reports success |
JwtGuardRouter | Resolves the jwt-prefixed guard by name | Requests reach the correct provider’s guard |
Auth0Guard | RS256 verification + iss / aud / exp / fatxn checks | The JWT is authentic, unexpired, addressed to this guard, and bound to the exact payload |
| MPC network | Distributed signing at {guard_id}#{sub} | A valid signature is produced without any party holding the full key |
Next steps
JWTs
The RS256 token, its claims, and the
fatxn payload binding.Auth0
How the default provider issues tokens and which claims the guard checks.
MPC signing
Per-user key derivation, signature algorithms, and distributed signing.
Contracts overview
The entry point, router, guards, and supporting infrastructure.