Polyester checks the caller, the account policy, and the destination before accepting withdrawals or transfers.
The goal is to make session theft insufficient for moving funds to a new destination.
Low-risk actions use fewer prompts. New destinations require stronger verification.
How the model works
Withdrawals and transfers use layered authorization. Each flow requires the checks that match its destination and account policy.
Layer | What it proves | Typical use |
|---|---|---|
Session or API key | The request is tied to an authenticated user or registered API key. | Private account activity |
Account and subaccount policy | The caller is allowed to act on the selected account. | Subaccount access, role checks, API key scope |
Fresh MFA step-up | The user recently confirmed this high-risk action. | Withdrawals, security changes, whitelist changes |
Wallet-signed intent | The bound wallet authorized the exact movement details. | New destinations, high-risk value movement |
Destination whitelist | The destination was already trusted through a protected flow. | Repeat transfers and withdrawals |
These layers are intentionally independent. If one credential is compromised, another control can still block the action.
Required checks by destination
Not every transfer carries the same risk. The required checks depend mostly on whether the destination is already trusted.
Destination or action | Typical requirement | Why |
|---|---|---|
Own subaccount | Session/API key + policy, with MFA when required | Value stays inside the same account boundary |
Whitelisted internal destination | Session/API key + policy + MFA when required | Destination was previously trusted |
Whitelisted external address | Session/API key + policy + MFA when required | External destination was previously trusted |
New internal destination | Wallet-signed intent + MFA/risk checks | Value can leave the user's own account boundary |
New external address | Wallet-signed intent + MFA/risk checks | Value can leave Polyester to a new destination |
On-chain account-control action | Wallet signature required | The wallet or smart account is the authority |
Adding, removing, or relaxing whitelist requirements is itself a high-risk action. Transfers can use a lower-friction path only if whitelist updates require strong verification.
Interactive users vs API users
Interactive users authenticate with a normal account session.
High-risk flows may require:
fresh MFA step-up
wallet-signed intent
destination whitelist checks
account and subaccount policy checks
This protects against session theft by requiring an additional check before value can move to an untrusted destination.
API users authenticate with registered Ed25519 API keys.
Money-moving API flows still require:
API-key signature verification
API key policy checks
account and subaccount policy checks
destination whitelist checks
replay and risk controls
API-key signatures prove that the API key authorized the request. They do not bypass destination or policy checks.
See Ed25519 API Keys for API-key signing details.
Wallet-signed intents
For high-risk transfers, Polyester can require the user to sign a structured intent with their wallet.
The signed intent describes the action, not just the login session:
Field | Purpose |
|---|---|
Action type | Distinguishes withdrawals, transfers, and other value movement |
Source account | Binds the movement to the selected account or subaccount |
Destination | Binds the exact destination account or address |
Asset and amount | Binds what value is moving |
Nonce and expiry | Limits replay and stale signatures |
Domain | Prevents signatures from being reused in the wrong environment or contract context |
Polyester verifies that the signature matches the wallet bound to the account and that the signed fields match the requested action.
A signature proves who authorized a message. It does not replace the message. Polyester verifies the canonical intent and the signature together.
MFA and fresh step-up
MFA can be enabled for interactive account security. For sensitive actions, Polyester may require a fresh step-up, meaning the user completes MFA again for that specific action.
Fresh step-up is stronger than relying on a previous login because it proves the user recently confirmed a high-risk operation.
Examples of actions that may require fresh step-up:
external withdrawals
transfers to non-owned or newly trusted destinations
creating or changing destination whitelists
relaxing security settings
changing API key permissions for money-moving actions
See Multi-Factor Authentication for more detail.
Destination whitelists
Destination whitelists reduce prompts for repeat transfers without trusting every new destination by default.
When a destination is whitelisted, Polyester can treat that destination as trusted during transfer authorization.
Whitelisted destinations may include:
external withdrawal addresses
internal transfer destinations
account-owned subaccounts
A destination becomes lower friction only after it is whitelisted through a protected flow.
See Guard Signer for how Polyester protects whitelist changes.
Withdrawals vs internal transfers
Withdrawals and internal transfers use the same security controls, but not always at the same level.
Transfers between subaccounts owned by the same root account are lower risk.
They usually require session or API-key authentication, policy checks, and MFA when required.
Transfers to another user's internal account are higher risk.
Treat them more like withdrawals because value leaves the user's own account boundary.
External withdrawals are highest risk when the destination is new.
Wallet-signed intent, policy checks, whitelist checks, and fresh MFA can all apply depending on the account configuration and destination trust state.
Practical summary
Rules of thumb:
low-risk actions can rely on normal authentication and policy
same-owner transfers can be lower friction
whitelisted destinations can reduce repeated signing prompts
new or untrusted destinations require stronger verification
on-chain account-control actions require wallet signatures
Common flows use fewer prompts. Actions that move value outside a trusted boundary require stronger verification.