Privy is a powerful library that enables you to provision powerful non-custodial embedded wallets in order to create delightful user experiences. Privy protects your users’ accounts and wallets via secure account verification, session management, and key sharding cryptography. See the architecture security documentation for more information.Before deploying Privy in production, there are several important security configurations to consider. Beyond this, security is a comprehensive topic that touches every part of your stack.
Because your application client provides the context in which users access their accounts, it is an essential environment to keep secure. Follow client-side security best practices, including limiting what is able to inject Javascript into your site. You should make sure only the code you intend runs in your app.
Using domains not configured in your allowed domains list will cause your integration to fail.
This is an important security measure that protects your users.
To enable HttpOnly cookies for enhanced security, you can verify your domain ownership through a simple setup process in the Privy dashboard. Learn more
If you have integrated user authentication with Privy wallet infrastructure, we recommend the following authentication settings. Authentication security starts with choosing appropriate methods for your application. Consider your users’ needs and security requirements when configuring these settings. Read more about our authentication architecture.
For high-value applications, we recommend that you:
Disable SMS-based authentication to prevent SIM-swapping attacks
Enable strong MFA options like authenticator apps or passkeys
Configure appropriate session duration. The default is 30 days. You can do this using app clients
These security settings can be configured in your Privy dashboard. The defaults are chosen to
balance security and user experience, but you may want to adjust them based on your specific
needs.
For wallets that users interact with directly through your application, we recommend enabling increasingly strict security settings as account value increases.
Set an owner on the wallet to add an additional layer of security for transaction signing. This means your transaction requests must be authorized with two factors: 1) your Privy app secret and 2) a signature from an authorization key, which is a cryptographic key that only your service has access to.
Once this is set up, implement key management controls:
Use a hardware-backed KMS (key management system) such as AWS KMS to secure authorization keys. Hardware-backed KMS systems disallow any export of keys.
We recommend rotating authorization keys regularly, by updating the owner on wallets to a new key on a regular basis (every 90-180 days).
You can further segregate wallets by setting different keys as the owner on different wallets. This means a given authorization key may only transact on one or a subset of wallets.
You can require additional authorization for transactions, by requiring a quorum of authorization keys to approve a transaction. For example, you may set a 2-of-2 key quorum as the owner of a wallet: one key held in a KMS, and one key held by your service.
We strongly recommend backing up authorization keys for redundancy. Privy does not have access to authorization keys and cannot recover your authorization key if you lose it.
Recommended Security Practice: A powerful security control your application can implement is to separate the keys used for transaction signing from the keys used for policy management. This ensures that even if your backend is compromised and transaction signing keys are exposed, the attacker cannot modify or remove the policies that constrain the wallet’s behavior.To implement this separation:
Create two different signing keys: one for managing wallets and policies and one for transaction signing
The management key should be used rarely and only be accessed in a very restricted environment
The transaction signing key will be used frequently and will accessed by your core application
When creating a wallet or policy, set the management key as the owner, which will make its signature required for any updates
On your wallet, set your transaction signing key and the policy it is subject to as an additional_signer
This creates a robust security boundary where:
Transaction signing keys can only operate within policy constraints
Policy management keys are rarely used and can be stored with higher security
A compromise of transaction signing infrastructure cannot escalate to policy modification
The keys above can be quorums (e.g., 2-of-3 keys), providing additional security through
multi-party authorization requirements.