Permissions let you define guardrails on your REST API wallets. Set up a policy through the Para dashboard that specifies what transactions are allowed, and Para enforces it on every signing request. If a transaction violates the policy, the request is denied before anything is signed.
Permissions are opt-in. If you don’t create a policy, all signing requests are allowed (existing behavior). Once a policy is active, it becomes deny-by-default — transactions must match an ALLOW rule.
Key Concepts
- One active policy per API key. Each policy contains one or more scopes, and each scope contains permission rules.
- Deny-by-default. When a policy exists, any transaction that doesn’t match an ALLOW rule is denied.
- DENY always wins. If a transaction matches both an ALLOW and a DENY rule, it’s denied.
- EVM only. Permissions currently evaluate EVM transactions. Solana and Cosmos are not yet supported.
How Enforcement Works
When you call any signing endpoint (sign-raw, sign-message, sign-typed-data, sign-transaction, transfer), Para checks whether a policy exists for your API key. If one does, the transaction is evaluated against every scope and permission in the policy.
If the transaction is denied, you get a 403 response with details about which rule blocked it:
{
"code": "POLICY_DENIED",
"message": "Transaction denied by policy",
"deniedBy": {
"scopeName": "Token Transfers",
"permissionType": "TRANSFER",
"condition": {
"resource": "TO_ADDRESS",
"comparator": "CONTAINED_IN",
"reference": ["0xabc...", "0xdef..."]
}
}
}
The deniedBy field tells you exactly which scope, permission type, and condition caused the denial, making it straightforward to debug.
Permission Types
Each permission targets a specific kind of signing operation:
| Type | Applies To |
|---|
SIGN_MESSAGE | sign-message, sign-typed-data, and sign-raw endpoints |
TRANSFER | transfer endpoint (native token sends) |
CALL_CONTRACT | sign-transaction when calling a contract function |
DEPLOY_CONTRACT | sign-transaction when deploying a contract |
Condition Reference
Conditions narrow when a permission applies. Every condition has a resource (what to check), a comparator (how to check), and a reference (expected value).
Resources
| Resource | Description | Used With |
|---|
VALUE | Transaction value in wei | TRANSFER, CALL_CONTRACT |
TO_ADDRESS | Destination address | TRANSFER, CALL_CONTRACT |
MESSAGE | The message being signed | SIGN_MESSAGE |
ARGUMENTS | Contract function arguments (e.g., ARGUMENTS[0]) | CALL_CONTRACT |
Comparators
| Comparator | Description | Reference Type |
|---|
EQUALS | Exact match | Single value |
NOT_EQUALS | Must not match | Single value |
GREATER_THAN | Numeric greater than | Number string (wei) |
LESS_THAN | Numeric less than | Number string (wei) |
CONTAINED_IN | Must be one of the listed values | Array of values |
NOT_CONTAINED_IN | Must not be any of the listed values | Array of values |
Limitations
- EVM only. Solana and Cosmos transactions are not evaluated against policies.
- No time-based spending limits. You can set validity windows on policies, but not cumulative spending caps.