Why is the zkLogin self-custody?

Why is the zkLogin self-custody? I think if OAuth Providers impersonate a user, they can also get user’s salt by using a jwt which they generate and they can transact.


zkLogin is a protocol that expects a valid fresh JWT and a salt (ie a secret 128bit value).

The standard itself does not specify how the salt is provisioned, ie some wallet providers might decide to store the salt in user’s wallet memory or secure-storage during account creation and provision it only if the user loses it. Some devs might allow registering a recovery method (ie a phone 2FA, some PIN authenticator etc), which protects against malicious openID providers.

Note that many non-zkLogin solutions only rely in web2 openID login to access your key (or a share of the key); and hence they are obviously directly prone to this curious oAuth provider scenario, and zkLogin’s design decision to incorporate an extra second factor (the salt) was exactly for this purpose + allowing multiple unlinkable addresses (with different salt) for the same user (another benefit of zkLogin is simulation or BIP32).

Some additional Sui features that make the use of zkLogin safer is a) addresses do not expose the wallet used nor the userID (in the openID provider), nor the salt. We also specifically hided the JWT signature as well, to protect user addresses from being tracked by oAuth providers, as they cannot match addresses to userID. b) zkLogin can be used in native multi-sig, and hence one can use zkLogin as multi-factor along with another auth method (ie mnemonic, soon passkeys etc). You can try this in devnet already, Sui supports up to 10 factors in a k out of n structure.