Back

Defense in depth: transaction policies

Setting up a simple policy restricting your wallet to only be able to take a known set of actions can save you even in the event of a complete infrastructure takeover.

Colfax Selby

|

Mar 14, 2025

Looking at recent hacks, they are usually the result of a compromised wallet taking an action it doesn’t normally perform. In most cases, especially with wallets that hold a large amount of value, wallets transact in the same patterns - with a finite list of addresses or contracts, same set of assets, calling the same functions, or transferring a regular fixed amount. Or if that’s not the case, it is possible to rearchitect a system that way.

Your wallet has many layers of security to protect you – you need to enter a password to interact, you’re (generally) shown what the transaction does (or better yet, what the result of it is), and even in some cases your wallet lives on its own hardware device.

But whether you’ve gotten phished or your infrastructure gets compromised directly, hacks still happen. A safeguard you can use as a last line of defense is policies.

Cryptographically verifiable policies

With Privy server wallets, you can set up simple or complex policies that restrict what your wallet can do. These policies are enforced against any incoming transaction request, and if the request does not adhere to the policy, even if the request comes from your servers, it will not go through. This is inherently baked into the implementation of server wallets and there is no way to bypass it, details on that below.

Some common examples of policies are:

  • Max transaction value

  • Allowlist transactions to a certain set of addresses / contracts

  • Restrict parameter values when calling a smart contract

  • Prevent the use of delegatecall

  • Stack multiple together

How this fits into server wallets architecture

Privy’s architecture ensures that a wallet’s private key can only be reconstituted on behalf of the holders of the wallet’s authorization keys. Policies are an additional layer of defense, enforced before your private key is reassembled inside the secure execution environment. You can read more about our server wallet architecture here.

Low level flexibility to fit your needs

When talking about policies, it’s important to understand how they can be updated. Policies have owners. Owners are made up of a quorum of keys – an individual key, a subset of a group, or a whole set of keys are required to sign off on updates, depending on the configuration.

Transactions are also approved by a quorum - either a single key, or multiple, are required to send a transaction request.

With these tools, you can architect a wallet system that fits your needs, whether you’re just getting started or run a large, multi-national corporation.

A simple architecture fit for an early-stage idea

You’re working on a social, verified-image sharing app

  • You have a signing key that manages your policies. You set them up once, and keep this key offline since it’s not needed on a regular basis.

  • You have a different signing key that’s responsible for signing off on each transaction. This key sits in an environment variable.

A complex architecture fit for a large organization

You run a global exchange that handles $10B of annual volume across 50 currencies.

  • Your core transaction policies are managed by compliance team

    • Policy changes require a 5 of 7 quorum of signatures for updates

  • The OFAC denylist policy is managed by a separate sanctions team

  • Your wallets are provisioned and policies assigned to them on a restricted machine, and this happens very rarely

  • You have a small fleet of “omnibus” treasury wallets that hold a majority of your funds

    • Any transaction coming out of these wallets requires 3 signatures out of a preset group of 5 treasury managers at your company

    • These wallets can only send funds to a list of 10 “hot” wallets your company manages

    • Each outgoing transaction has a limit of $500k

  • Hot wallets

    • These are your day-to-day operations wallets

    • They each only require one signature to transact from a key that lives in an environment variable on your server

    • They can send to any address with a transaction limit of $10k

    • However, a set of 3 administrators can sign together to send up to $500k in a transaction

In either case, if your core infrastructure is compromised, the attacker can only send transactions from your wallets that adhere to the policies you’ve set up – they can only send funds to your allowlisted addresses, send transactions of a maximum value, or call smart contracts with the constrained parameters you’ve specified.

Configuration matters & where we’re going

Policies must be easy and intuitive to set up. You are only as secure as your policy configuration and the safety of the keys that control them.

We’re working hard to make the safest way, the easiest way. Currently, we offer the ability to restrict the parameters on smart contract calls, and we’re building a higher level abstraction like 'usdc_transfer_limit' and things like transaction simulation, so you can enforce against the outcome of a transaction rather than the inputs. We’re also working on restricting total transaction volume, rather than individual transaction limits, so you can set up even more constraints.

You can get started with transaction policies here! We’re always excited to hear about what you’re building, and especially your experience with Privy, so join our developer slack and let us know what you think – your feedback will drive our roadmap.

Share this post


RELATED POSTS