May 05, 2025
How Privy Secures and Recovers Private Keys
Privy offers a seamless cross-device wallet experience. Whether you’re creating a new wallet or logging in from a new device, the process is smooth and requires no user-facing key management. Unlike most Web3 wallets, users never see or store private keys, eliminating a major source of asset loss.
I understand that in the world of Web3, each individual is ultimately responsible for their own assets, that’s the core principle of decentralization.
But after all this time, asset loss is still far too common.
Why hasn’t the ecosystem built foundational infrastructure to help protect our assets?
So naturally, I’m very curious about the technology behind Privy. It’s clear that they’ve nailed the user experience, but what about security? Let’s take a closer look.
TL;DR
-
When Privy creates an embedded wallet, it generates wallet entropy, which is then split into three parts: Device share, Auth share, and Recovery share, using Shamir’s Secret Sharing (SSS).
Any two shares can be used to reconstruct the wallet entropy and then derive the private key, all within the isolated Privy iframe.
-
If one of the shares is lost, the wallet entropy can still be reconstructed using the remaining two. From there, a new set of three shares can be generated.
Each of these new shares is then encrypted and stored, while the previous shares are marked as obsolete.
-
The embedded wallet provider is injected into the Privy iframe and isolated from the dApp. Communication between the two occurs via iframe messaging, ensuring that all wallet operations are performed securely within the sandboxed iframe environment.
Key sharding
This is the core of Privy’s wallet infrastructure.
Private keys are split into encrypted shares using a reliable, battle-tested, and fast cryptographic algorithm called Shamir’s secret sharing (SSS). No share in isolation provides any information or access to the wallet.
When a user logs into a dApp with Privy for the first time using a social login(a typical Web2 user scenario), and the Privy configuration includes the following:
1embeddedWallets: {
2 ethereum: {
3 // or "all-users"
4 createOnLogin: "users-without-wallets", // default "off"
5 },
6},
Privy automatically generates an embedded wallet within Privy iframe. During this process, wallet entropy is created and split using Shamir’s Secret Sharing (SSS) into three shares: the Device share, the Auth share, and the Recovery share.
The wallet data is written to the user.linkedAccounts
list, and any third-party account used for login is also recorded in this list.
-
Device Share
This share is encrypted and stored in the
localStorage
within the Privy iframe. -
Auth share
This share is encrypted within the Privy iframe and then sent to the Privy backend for storage. When needed, the Privy backend locates the corresponding Auth share based on the user’s identity and returns the encrypted share to the iframe, where it is decrypted and used.
-
Recovery share
The storage location of this share depends on the configuration set in the Privy dashboard. By default, Privy uses
-
Default (Automatic Recovery):
A key encryption key (KEK) is generated using a cryptographically secure random number generator (CSPRNG). The Recovery share is encrypted with the KEK, then the encrypted share is sent to and stored by the Privy backend. The KEK itself remains in the iframe.
-
Password Backup Enabled:
On first login, the user is prompted to set a password. A KEK is derived from this password using a key derivation function. The Recovery share is then encrypted with the KEK and sent to the Privy backend for storage. To access the Recovery share later, the user must re-enter their password to decrypt it.
-
Cloud Backup Enabled:
The encrypted Recovery share is stored in the user’s chosen cloud platform instead of the Privy backend. To recover the share, the user must log into their cloud account to retrieve the encrypted share, which is then decrypted locally in the iframe.
-
When a share needs to be decrypted in the Privy iframe, a temporary KEK (Key Encryption Key) is generated. After decryption, the KEK is immediately destroyed.
The embedded wallet provider doesn’t inject window.ethereum
like MetaMask does. Instead, it’s isolated within the Privy iframe and interacts with the dApp through the useWallets()
hook exposed by @privy-io/react-auth
. Since the private key and all wallet operations are confined to the isolated iframe, this design provides a strong layer of security.
The diagram below illustrates this process:
Key Recovery
There are two main types of key recovery: recovering the private key for signing, or restoring the Device share on a new device.
For private key
This process occurs when a logged-in user needs to perform sensitive operations, such as signing a transaction or exporting their private key.
When the user initiates a signing request, the Privy iframe retrieves the encrypted Device share and encrypted Auth share, then decrypts them.
These two shares are used to reconstruct the wallet entropy, which is then used to derive the private key for signing.
After the operation is completed, the private key is immediately discarded, and the Auth share is re-encrypted and sent back to the Privy backend for secure storage.
For Device share
This process occurs when a returning user logs into the dApp on a new device.
Since the new device doesn’t have the Device share, the user first logs in using a Web2 method. After authentication, an authorization code is sent to the Privy backend. Privy then uses this code to request an access token from the Web2 platform. This token allows Privy to verify the user’s identity and retrieve their associated DID (Decentralized Identifier).
Next, Privy generates a Privy Access Token using the user’s DID, along with fields such as the Privy App ID, session ID, and session expiration time. This token is sent to the dApp and serves as the user’s login credential.
By default, this token is stored in localStorage
under the key privy:token
. If HttpOnly cookies are enabled, the token is stored in a privy-token
cookie instead, which is automatically included in HTTP requests and cannot be accessed via JavaScript, enhancing security against XSS attacks.

In addition, based on the user’s DID, the Privy backend locates the corresponding User object and retrieves the necessary Auth share and Recovery share (assuming cloud storage isn’t being used).
The Privy iframe fetches the required shares from the backend, decrypts them, and reconstructs the wallet entropy. Then,this entropy is split into three new shares, each encrypted and securely stored within the Privy iframe and backend.
In Shamir’s Secret Sharing (SSS), each time the wallet entropy is reconstructed, new shares are generated using fresh random coefficients in the polynomial. This ensures that the new shares are entirely independent of the previous ones, even though the wallet entropy remains the same.
This approach enhances security by preventing any correlation between old and new shares, thereby maintaining forward secrecy.
The diagram below provides a simplified overview of this process
Wrapping Up
This is a solid starting point for understanding the inner workings of Privy’s wallet infrastructure.
We now have a clearer picture of how the embedded wallet interacts with a dApp, how Privy helps users securely store private keys, and how it enables seamless access and transactions across different devices.
To trust and make the most of Privy, it’s crucial to understand exactly what it does and how it works.
This article didn’t dive deeply into user authentication, as Privy supports a wide variety of login methods. What matters here is that no matter how a user logs in, they’re always associated with a unique ID. That ID links to the user object, the Auth share, and even the Recovery share, ensuring consistent identity mapping.