Skip to main content

Overview

Template variables let a policy condition compare against a value that Privy resolves per request. The policy does not fix that value when it is written. A condition holds a placeholder such as {{wallet.address}}, and Privy substitutes the value each time it evaluates the condition. Together, template variables let one set of rules adapt to each request, instead of a separate rule per case. This approach offers several benefits:
  • Reusability: Encode a rule once and reuse the same policy wherever it applies
  • Maintainability: Keep rules stable as the set of resources a policy governs changes
  • Scalability: Cover any number of cases with one rule instead of one rule per case
  • Safety: Privy resolves the value from the request context, so a caller cannot supply its own

Concepts

A template variable is a placeholder, written as {{namespace.field}}, that a condition value holds in place of a literal. Before evaluating the condition, the policy engine replaces it with a secure value from the request context. The value a rule compares against can therefore differ from one request to the next. Privy supports one template variable today:
  • {{wallet.address}} resolves to the address of the wallet signing the request. Privy resolves it per request, so one policy can hold a rule about each wallet’s own address.

Where it can be used

{{wallet.address}} can be used anywhere a condition compares an address, and inside the content of a message. These operators accept it: The in_condition_set operator does not accept a template variable, because its value names a condition set rather than an address.
Aggregation conditions do not accept a template variable yet. See stateful policies for what aggregations support.

Examples

Restrict an ERC-20 transfer recipient to the signing wallet

The recipient argument must decode to the signing wallet’s own address, which keeps funds from leaving the wallet that holds them.

Allow the signing wallet alongside fixed addresses

The in operator accepts template variables and literal addresses in the same array. This rule allows a transaction to the signing wallet or to a treasury address.

Restrict a transfer action recipient to the signing wallet

The transfer wallet action evaluates against the request body, so the same constraint applies to destination.address.

Only sign typed data that names the signing wallet

A condition can compare an address leaf of an EIP-712 message against the signing wallet. This rule stops a wallet from signing an order on another account’s behalf.
An ethereum_typed_data_message condition only evaluates when the types map in the policy matches the types map in the signing request exactly. See Restrict parameters of a typed data message for the full requirement.

Only sign login messages that name the signing wallet

The message field source compares free-form text, so a template variable can sit inside a longer value. This rule allows a Sign-In with Ethereum message only when it names the signing wallet.
String comparisons are case-sensitive. For Ethereum wallets, {{wallet.address}} resolves to the EIP-55 checksummed address that the wallets API returns, so a message holding a lowercase address will not match. Address fields compare EVM addresses without regard to case, so they are unaffected.

Only debit the signing wallet on Solana

A Solana transaction can carry instructions that move funds from other signers. A condition on Transfer.from limits a transaction to debiting the signing wallet.

Next steps

Create a policy

Create and attach a policy with the Node SDK or the REST API.

Conditional policies per signer

Apply different permissions to different signers on the same wallet.