Skip to content

Server wallet architecture

To enable secure wallets, Privy uses Shamir's secret sharing (SSS) within secure enclaves. The combination of these primitives ensure that private keys can only ever be reassembled within a secure enclave and that only permissioned actions can take place.

The combination of these primitives make the system resilient to any single party breach, and enforce flexible policies to govern what wallet actions can be taken and by whom.

Secure enclaves

Secure enclaves, also known as trusted execution environments (TEEs), are highly restricted, isolated compute environments that allow for secure code execution and cryptographic verification (attestation) of the code being executed. In particular, Privy uses AWS Nitro Enclaves.

Privy uses enclaves to support private key reconstitution for the following hardware guarantees:

  • Enclaves have no persistent storage, no interactive access, and no network connectivity, and so provide a secure, isolated compute environment for sensitive data. Private keys for wallets are only accessible within the enclave, and will only be used to produce signatures compliant with the policies attached to the wallet.
  • Attestations are cryptographic verifications of the computation run on a enclave. They are signed hashes of code on a enclave that can be verified with the corresponding public key. They prove that only the intended code can be executed, guaranteeing that wallet policies are enforced for any actions that run in the enclave.

Authorization keys

Your app can optionally register an authorization key with the enclave to require the enclave to verify a signature from your server before executing any requests. This is strongly recommended as an additional layer of security to ensure that the enclave only executes requests originating from your servers.

Privy uses P-256 (also known as secp256r1) asymmetric keys for authorization keys. When you register a key:

  • The private key is generated on your device, and is only ever known to your app. Neither Privy nor the enclave ever sees the P-256 private key, and cannot sign payloads with it.
  • The public key is registered with the enclave, and is used to verify signatures produced by your servers.

If an authorization key is registered for your app, the enclave will require that your servers sign the request payload for any wallet action (e.g. signing a message) with the authorization private key for your app. The enclave will verify the signature against the corresponding authorization public key registered for your app before executing any wallet actions.

Shamir's secret sharing

Privy's cryptosystem architecture is built on Shamir's secret sharing (SSS), a reliable and cryptographically battle-tested method for splitting a secret across a number of different parties.

INFO

Privy's shamir-secret-sharing cryptography library is open-source, heavily audited, and used to secure millions of user accounts. It is the canonical Typescript library for Shamir's secret sharing.

When creating a new wallet, Privy splits the generated private key into a set of Shamir shares:

  1. a enclave share, which is encrypted with the enclave's public key, and can only be decrypted within the TEE.
  2. an app share, which is encrypted by Privy at rest, and is sent to the enclave whenever an action is requested from the wallet.

This is a 2-of-2 share set, which means that both shares are required in order to generate signatures. Neither the app share nor the enclave share in isolation provide any information or access to the wallet.

TIP

Only the enclave can decrypt its own share and combine it with the app share to reconstitute the wallet and execute actions. Neither Privy nor your app's backend can reconstitute the wallet without the enclave in the loop.

Wallet API share set

Policies

Apps can assign specific policies to restrict actions that can be taken by a given wallet, such as generating signatures or sending transactions. This is important for features such as payment subscriptions, stop and limit orders, or scheduled transactions.

Actions can be configured with specific policies, such as:

  • Allowlisted recipients
  • Allowlisted smart contracts and methods
  • Transaction maximums

End-to-end flow

At a high-level, the end-to-end flow for executing a request with a wallet is as follows:

  1. Your app makes a POST request to Privy's /api/v1/wallets/rpc endpoint with the wallet address, chain_type, and RPC request encoding the action requested from the wallet (e.g. a certain signature).
    • If an authorization key is registered for your app, you must sign the body of the request with your app's authorization private key and include the signature in the request's headers.
  2. Privy's backend authenticates the request with your Privy app secret. If the request is valid, the request is forwarded to the enclave.
  3. The enclave decrypts the encrypted enclave share and combines it with the app share to reconstitute the wallet's private key.
    • If an authorization key is registered for your app, the enclave will verify the authorization signature from your request against your app's authorization public key before executing any wallet actions.
  4. The enclave then verifies that the scope of the action requested falls within the policies enforced by the wallet, and if so, signs the action. This signature is returned in Privy's response to your app's original POST request to allow your app to use the signature as needed (e.g. broadcasting a signed transaction).