Overview
Policies define transaction signing rules that enable fine-grained control over which transactions can be signed by evaluating conditions against transaction data. When Policy Evaluation is enabled for your application, policies are applied during transaction signing:
Enable Policy Evaluation
Before using policies, you need to enable Policy Evaluation for your application in the Magic Dashboard.
Navigate to your app settings in the Magic Dashboard
Go to the Settings page
Find the Policy Evaluation card
Toggle Enable Policy Evaluation to turn on the feature
Set the Recency Window (in minutes) to specify how long a user’s MFA validation remains valid for policy checks. This determines the time window for which step-up policies won’t require re-authentication if the user was recently validated.
Click Save to apply your changes
The recency window allows you to control how frequently users need to complete MFA verification for step-up policies. For example, if you set a recency window of 15 minutes, users who completed MFA within the last 15 minutes won’t be prompted again for step-up policy checks.
Global scope : Always enforced and blocks transactions immediately if conditions fail
Step-Up scope : Requires additional MFA verification when conditions are met
Step-Up scope limitation : Step-Up policies require Embedded Wallet integration, as MFA verification is tied to the Embedded Wallet system. For users who are not Embedded Wallet users (i.e., Express API users without Embedded Wallet integration), only Global scope policies can be used. Step-Up policies will not work for non-Embedded Wallet users.
Policy Object
All policy endpoints return a policy object with the following structure:
Unique identifier for the policy.
Whether the policy is currently active. Defaults to true when created.
The blockchain this policy applies to (BTC, ETH, or SOL).
Array of rule objects defining transaction conditions and actions. Transaction signing method this rule applies to (e.g., eth_signTransaction, personal_sign, eth_signTypedData_v4).
Array of condition objects that are evaluated. Source of the field being evaluated (e.g., ethereum_transaction, typed_data, system).
Field name being evaluated (e.g., value, to, chain_id).
Comparison operator used. Valid values: eq (equals), neq (not equals), lt (less than), lte (less than or equal), gt (greater than), gte (greater than or equal), in (in list).
Value compared against. Can be a string, number, boolean, or object depending on the operator.
Optional ABI definition for contract call data parsing.
Action to take when conditions are met (e.g., require_mfa, block, DENY, ALLOW).
Policy scope. Valid values: GLOBAL (Global) or STEP_UP (Step-Up).
Optional policy description.
Create Policy
Create a new policy configuration for your application.
curl -X POST 'https://tee.express.magiclabs.com/v1/policy/' \
-H 'Content-Type: application/json' \
-H 'X-Magic-Secret-Key: your-magic-secret-key' \
-d '{
"name": "High Value Transaction Policy",
"chain": "ETH",
"rules": [
{
"name": "Require MFA for high value",
"method": "eth_signTransaction",
"conditions": [
{
"field_source": "ethereum_transaction",
"field": "value",
"operator": "gt",
"value": "1000000000000000000"
}
],
"action": "require_mfa"
}
],
"scope": "STEP_UP",
"description": "Requires MFA for transactions over 1 ETH"
}'
Response:
{
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"is_active" : true ,
"name" : "High Value Transaction Policy" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Require MFA for high value" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "value" ,
"operator" : "gt" ,
"value" : "1000000000000000000"
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Require MFA for transactions over 1 ETH"
}
Request Parameters
Policy name. Must be between 1 and 255 characters.
Blockchain for this policy. Valid values: BTC, ETH, SOL.
Array of rule objects that define transaction conditions. Must contain between 1 and 100 rules. Show Rule object properties
Rule name. Must be between 1 and 255 characters.
Transaction signing method this rule applies to (e.g., eth_signTransaction, personal_sign, eth_signTypedData_v4). Must be between 1 and 100 characters.
Array of condition objects that must be evaluated. Must contain between 1 and 50 conditions. Show Condition object properties
rules[].conditions[].field_source
Source of the field to evaluate (e.g., ethereum_transaction, typed_data, system). Must be between 1 and 100 characters.
rules[].conditions[].field
Field name to evaluate (e.g., value, to, chain_id). Must be between 1 and 100 characters.
rules[].conditions[].operator
Comparison operator. Valid values: eq (equals), neq (not equals), lt (less than), lte (less than or equal), gt (greater than), gte (greater than or equal), in (in list). Must be between 1 and 50 characters.
rules[].conditions[].value
Value to compare against. Can be a string, number, boolean, or object depending on the operator.
Optional ABI definition for parsing contract call data when evaluating transaction data fields.
Action to take when conditions are met (e.g., require_mfa, block). Must be between 1 and 50 characters.
Policy scope. Valid values: GLOBAL (always enforced, blocks transactions immediately) or STEP_UP (requires MFA verification when conditions are met).
Optional description of the policy. Maximum 1000 characters.
Response Fields
Returns a Policy object .
Get Policy
Retrieve a specific policy by its ID.
curl -X GET 'https://tee.express.magiclabs.com/v1/policy/{policy_id}' \
-H 'X-Magic-Secret-Key: your-magic-secret-key'
Response:
{
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"is_active" : true ,
"name" : "High Value Transaction Policy" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Require MFA for high value" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "value" ,
"operator" : "gt" ,
"value" : "1000000000000000000"
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Require MFA for transactions over 1 ETH"
}
Request Parameters
The unique identifier of the policy to retrieve.
Response Fields
Returns a Policy object .
Get Policies
Retrieve all policies for your application, optionally filtered by active status, chain, or scope.
curl -X GET 'https://tee.express.magiclabs.com/v1/policy?is_active=true&chain=ETH&scope=STEP_UP' \
-H 'X-Magic-Secret-Key: your-magic-secret-key'
Response:
[
{
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"is_active" : true ,
"name" : "High Value Transaction Policy" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Require MFA for high value" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "value" ,
"operator" : "gt" ,
"value" : "1000000000000000000"
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Require MFA for transactions over 1 ETH"
}
]
Query Parameters
Filter policies by active status. If not provided, returns all policies regardless of status.
Filter policies by blockchain. Valid values: BTC, ETH, SOL.
Filter policies by scope. Valid values: GLOBAL or STEP_UP.
Response Fields
Update Policy
Update an existing policy configuration. All fields are optional - only provided fields will be updated.
curl -X PATCH 'https://tee.express.magiclabs.com/v1/policy/{policy_id}' \
-H 'Content-Type: application/json' \
-H 'X-Magic-Secret-Key: your-magic-secret-key' \
-d '{
"is_active": false,
"name": "Updated Policy Name",
"description": "Updated description"
}'
Response:
{
"id" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" ,
"is_active" : false ,
"name" : "Updated Policy Name" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Require MFA for high value" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "value" ,
"operator" : "gt" ,
"value" : "1000000000000000000"
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Updated description"
}
Request Parameters
The unique identifier of the policy to update.
Whether the policy should be active. Set to false to temporarily disable a policy without deleting it.
Updated policy name. Must be between 1 and 255 characters if provided.
Updated array of rule objects. Must contain between 1 and 100 rules if provided.
Updated policy scope. Valid values: GLOBAL or STEP_UP.
Updated policy description. Maximum 1000 characters.
You can update individual fields without affecting others. For example, you can update just the is_active status to enable or disable a policy, or update only the description field.
Response Fields
Returns a Policy object with the updated fields. Note that chain cannot be updated and will remain unchanged.
Delete Policy
Remove a policy configuration from your application.
curl -X DELETE 'https://tee.express.magiclabs.com/v1/policy/{policy_id}' \
-H 'X-Magic-Secret-Key: your-magic-secret-key'
Response:
No content ( 204 status code)
Request Parameters
The unique identifier of the policy to delete.
Deleting a policy will immediately stop it from being evaluated for transaction signing. Ensure you understand the security implications before deleting policies that enforce important transaction rules.
Common Use Cases
Typed Data Signing Policies
Policies can also be applied to EIP-712 typed data signing (eth_signTypedData_v4, eth_signTypedData_v3, etc.). When creating policies for typed data, use the typed_data field source and access domain and message fields using the typed_data_domain_{fieldName} and typed_data_message_{fieldName} pattern.
Block Specific Contract Addresses
Block typed data signatures for specific verifying contracts:
{
"name" : "Block High-Risk Contracts" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Block specific contract address" ,
"method" : "eth_signTypedData_v4" ,
"conditions" : [
{
"field_source" : "typed_data" ,
"field" : "typed_data_domain_verifyingContract" ,
"operator" : "eq" ,
"value" : "0x1234567890123456789012345678901234567890"
}
],
"action" : "DENY"
}
],
"scope" : "GLOBAL" ,
"description" : "Block signatures for specific contract addresses"
}
This policy will block all typed data signatures where the verifyingContract in the EIP-712 domain matches the specified contract address.
Require MFA for Specific Domain Names
Require step-up authentication for typed data from specific applications:
{
"name" : "High Risk Domain MFA" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Require MFA for high-risk applications" ,
"method" : "eth_signTypedData_v4" ,
"conditions" : [
{
"field_source" : "typed_data" ,
"field" : "typed_data_domain_name" ,
"operator" : "eq" ,
"value" : "High Risk Exchange"
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Require MFA for typed data signatures from specific applications"
}
Block High Value Orders
Block typed data orders that exceed certain value thresholds by checking message fields:
{
"name" : "Block High Value Orders" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Block orders over 10M" ,
"method" : "eth_signTypedData_v4" ,
"conditions" : [
{
"field_source" : "typed_data" ,
"field" : "typed_data_message_makerAmount" ,
"operator" : "gt" ,
"value" : "10000000"
}
],
"action" : "DENY"
}
],
"scope" : "GLOBAL" ,
"description" : "Block typed data orders with makerAmount over 10,000,000"
}
This policy evaluates the makerAmount field from the typed data message and blocks any orders exceeding the threshold.
High Value Transaction Policy
Require MFA for transactions over a certain value threshold:
{
"name" : "High Value Transaction Policy" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Require MFA for high value" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "value" ,
"operator" : "gt" ,
"value" : "1000000000000000000"
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Require MFA for transactions over 1 ETH"
}
Contract Interaction Policy
Block transactions to specific contract addresses:
{
"name" : "Blocklisted Contracts" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "Block known malicious contracts" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "to" ,
"operator" : "eq" ,
"value" : "0x1234567890123456789012345678901234567890"
}
],
"action" : "DENY"
}
],
"scope" : "GLOBAL" ,
"description" : "Block transactions to known malicious contract addresses"
}
Multi-Condition Policy
Combine multiple conditions for complex rule evaluation:
{
"name" : "Complex Transaction Policy" ,
"chain" : "ETH" ,
"rules" : [
{
"name" : "High value after timestamp" ,
"method" : "eth_signTransaction" ,
"conditions" : [
{
"field_source" : "ethereum_transaction" ,
"field" : "value" ,
"operator" : "gt" ,
"value" : "500000000000000000"
},
{
"field_source" : "system" ,
"field" : "current_unix_timestamp" ,
"operator" : "gt" ,
"value" : 1640995200
}
],
"action" : "require_mfa"
}
],
"scope" : "STEP_UP" ,
"description" : "Require MFA for high-value transactions after a specific timestamp"
}