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
- Ephemeral key. The app generates a temporary keypair and picks a
maxEpochafter which the key expires. - Nonce. The ephemeral public key,
maxEpochand 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. - Salt. Each user has a secret
user_salt. It keeps the link between the OAuth identity and the Sui address private. - 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. - Proof. A proving service produces a Groth16 proof that the JWT is signed by the provider, contains the nonce, and matches the address seed.
- 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:
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) derivationNext 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
maxEpochthe user has to log in again. The protocol caps how far aheadmaxEpochcan be (protocol configzklogin_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
- zkLogin, Sui documentation
- zkLogin integration guide, Sui documentation
crates/sui-protocol-config/src/lib.rs, MystenLabs/sui