suideveloper
All questions
Accounts and wallets

What is zkLogin?

November 3, 2026

zkLogin is a Sui signature scheme (flag 0x05) that lets someone own a Sui address and sign with it using an OAuth/OpenID login, such as Google, Apple, Facebook or Twitch, instead of a seed phrase. The login provider's signed JWT, plus a zero-knowledge proof, authorize a short-lived ephemeral key, and that key signs the transactions. The proof shows that the JWT is valid and matches the address without putting the user's identity on chain. zkLogin is part of the protocol, so it doesn't depend on any particular wallet.

How it works

  1. Ephemeral key. The app generates a temporary keypair and picks a maxEpoch after which the key expires.
  2. Nonce. The ephemeral public key, maxEpoch and some randomness are hashed (Poseidon over BN254) into a nonce, which goes into the OAuth request. The provider's signed JWT then contains that nonce, which binds the login to this session key.
  3. Salt. Each user has a secret user_salt. It keeps the link between the OAuth identity and the Sui address private.
  4. Address. The address is derived from iss (the provider), aud (your app's OAuth client ID), sub (the user's ID with that provider) and the salt. It doesn't depend on any public key, so it stays the same across sessions.
  5. Proof. A proving service produces a Groth16 proof that the JWT is signed by the provider, contains the nonce, and matches the address seed.
  6. Signing. Each transaction is signed with the ephemeral key. The zkLogin signature bundles that signature with the proof and maxEpoch, and validators check it against the provider's current public keys (JWKs), which are kept on chain.

Losing a JWT alone doesn't put funds at risk, because an attacker would also need the ephemeral private key. A compromised OAuth account also isn't enough on its own, because the attacker would still need the salt.

In code

@mysten/sui/zklogin has the building blocks:

TypeScript
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519'
import { generateNonce, generateRandomness, jwtToAddress } from '@mysten/sui/zklogin'

const ephemeral = new Ed25519Keypair()
const maxEpoch = currentEpoch + 2 // current epoch from your client
const randomness = generateRandomness()
const nonce = generateNonce(ephemeral.getPublicKey(), maxEpoch, randomness)

// ...send the user to the OAuth provider with `nonce`, receive `jwt`...

const address = jwtToAddress(jwt, userSalt, false) // false = current (non-legacy) derivation

Next you call a prover with the JWT, the extended ephemeral public key, maxEpoch, the randomness and the salt. You then combine the proof with the ephemeral signature using getZkLoginSignature, or use ZkLoginSigner, which handles that step. The zkLogin integration guide covers the full flow. If you'd rather not run salts and provers yourself, Mysten's Enoki service manages them.

Supported providers

According to the Sui docs, Facebook, Google, Twitch, Apple, AWS (per tenant), Karrier One and Credenza3 work on mainnet. Slack, Kakao and Microsoft are devnet-only. Others are under review, so check the docs for the current list.

Things to plan for

  • The salt is critical. If the salt is lost, the address is unreachable. Store it reliably, or use a salt service.
  • Addresses are per app and per provider. The same Google account gives a different address for a different aud (client ID) or a different provider. If you change OAuth client IDs, your users end up with new addresses.
  • Sessions expire. After maxEpoch the user has to log in again. The protocol caps how far ahead maxEpoch can be (protocol config zklogin_max_epoch_upper_bound_delta, set to 30 epochs). Epochs last about a day; see What is an epoch on Sui?.
  • Recovery. If the user loses the OAuth account, they lose the address. For valuable accounts, put the zkLogin signer in a 1-of-2 multisig with a second provider or a passkey.
  • Mainnet prover access. Mysten's hosted prover is open on devnet and testnet. On mainnet it requires registering through the Enoki portal. You can also self-host the prover with Docker.

Compare zkLogin with passkeys and the other signature schemes.

Sources

More on accounts and wallets