Policies

Set programmable guardrails that automatically allow, block, or route sensitive actions through normal approval in your workspace. Policies evaluate every withdrawal and smart contract call against rules you define, so risky activity is stopped before it ever reaches the blockchain.

Overview

A policy is a set of rules that runs automatically whenever someone initiates a guarded action, such as requesting a withdrawal or calling a smart contract. Each rule describes a condition (for example, "withdrawal value over $10,000 to a non-whitelisted address") and an effect:

  • Deny: block the action outright
  • Allow: let the action skip the approval queue and proceed directly

Policies act as an always-on layer of defense that complements your signer approvals. Instead of relying on every approver to remember your treasury rules, you encode those rules once and let Fystack enforce them on every transaction.

Policy List

How Policies Are Evaluated

When a guarded action runs, Fystack checks it against every active policy that targets the relevant wallet and applies a custody-safe decision model:

  1. Deny always wins: if any rule matches with a Deny effect, the action is blocked, even if another rule would allow it.
  2. Allow bypasses approval: if a rule matches with an Allow effect and nothing denies, the action skips the approval queue and proceeds.
  3. No match: if no rule matches, the action continues through your normal approval flow.

Trigger Actions

Each rule applies to one trigger action, the type of operation it guards:

Trigger

Guards

Withdrawal

Evaluated when a withdrawal is requested. Rules can reference the amount, USD value, asset, destination address, whitelist status, address age, and recent wallet, workspace, and network activity.

Contract Call

Evaluated when a smart contract method is called. Rules can reference the network, contract address, method selector, method name, native value, gas limit, and decoded call arguments.

How to Create a Policy

Step 1: Open the Policies Page

In the left sidebar, open Policies, then click Create Policy.

Step 2: Name the Policy and Choose an Approval Group

Give the policy a clear Name that describes what it protects (for example, "Large withdrawal guard"). Then select the Approval Group that will review changes to this policy.

Every policy is tied to an approval group. This means a policy cannot be silently created or edited, any change must be reviewed and approved, the same way a withdrawal is.

Create Policy Form

Step 3: Target Specific Wallets (Optional)

By default, a policy applies to all wallets in the workspace. To scope it to a subset, select one or more wallets in the Wallets field. The policy's rules will only be evaluated for actions on those wallets.

Wallet Selector

Step 4: Add Rules

Add one or more rules to the policy. For each rule, choose the Trigger (Withdrawal or Contract Call), build the Condition, and pick the Effect (Allow or Deny).

The condition builder shows the fields available for the selected trigger, so you can construct expressions without memorizing field names. See Writing Rule Conditions below for examples.

Add Rule Form

Policies also programmable with JSON builder, which is useful for power users who want to copy/paste rules or use more complex logic than the UI supports.

Policy JSON Builder

Step 5: Submit for Approval

Click Create. Because every policy is approval-gated, the new policy is not active yet, it is submitted to its approval group as a Pending Approval request, along with all of its rules.

Policy Approval Request

Step 6: Approve the Policy

A member of the assigned approval group opens the pending request, reviews the proposed policy and its rules, and approves it. Only then does the policy become Active and start guarding transactions.

Approve Policy Modal

Writing Rule Conditions

A condition is an expression that evaluates to true or false. When it is true, the rule's effect applies. Combine fields with and, or, and not, and compare values with operators like >, >=, ==, and !=.

Condition Fields

The fields available in the builder depend on the rule's trigger. Use the labels below when deciding which field belongs in a rule.

Available on Every Trigger

Field

Use it for

User email

Rules that apply to a specific initiator.

User role

Rules based on workspace role: owner, admin, signer, proposer, viewer, or guest.

Hour

Time-of-day controls using UTC hour from 0 to 23.

Day of week

Business-hour, weekend, or weekday-only rules.

Withdrawal Fields

Field

Use it for

Amount

Asset-denominated limits, such as more than 10 ETH or 1 BTC.

Value USD

Dollar-denominated limits across assets.

Asset symbol

Asset-specific rules for symbols such as USDT, ETH, BTC, or SOL.

Native asset

Different controls for native network assets versus tokens.

Destination address

Blocking or allowing specific recipient addresses.

Network code

Network-specific limits, such as stricter rules on one chain.

Whitelisted address

Controls for recipients that are or are not in the address book.

Address age

Cooling-off rules for newly added address book records.

Withdrawal Activity Fields

Field

Use it for

Wallet outflow

Per-wallet USD outflow over the last 1, 6, or 24 hours.

Wallet withdrawal count

Burst controls for many withdrawals from one wallet in the last hour.

Workspace outflow

Workspace-wide USD outflow over the last 1, 6, or 24 hours.

Workspace withdrawal count

Workspace-wide withdrawal volume in the last hour.

Network outflow

Workspace USD outflow on the selected network over the last 1, 6, or 24 hours.

Network withdrawal count

Workspace withdrawal volume on the selected network in the last hour.

Contract Call Fields

Field

Use it for

Network code

Chain-specific contract call rules.

Contract address

Blocking unknown contracts or allowing known contracts.

Method selector

Low-level function checks, such as ERC-20 transfer selector 0xa9059cbb.

Method name

Human-readable method checks when metadata is available.

Value wei

Native value sent with a contract call.

Gas limit

Blocking unusually expensive or risky calls.

Decoded arguments

Argument-level rules when Fystack can decode the call. ERC-20 transfers expose recipient and token value.

Example Conditions

Goal

Effect

Condition

Block large transfers to unknown addresses

Deny

value over $10,000 and address not whitelisted

Auto-approve small transfers to trusted addresses

Allow

value under $100 and address whitelisted

Throttle wallets making many withdrawals quickly

Deny

more than 10 withdrawals in the last hour
Condition Builder

Policy Statuses

Status

Meaning

Pending

The policy, or a change to it, is awaiting sign-off from its approval group. It is not yet enforced.

Active

The policy is approved and live. Its rules are evaluated against every guarded action on the targeted wallets.

Inactive

The policy is disabled and not evaluated.

Rejected

A pending change was rejected by an approver and did not take effect.

Change History

Every change to a policy is recorded. The policy's History shows each revision with who proposed it, what changed (field by field), and whether it was approved or rejected. This gives you a complete audit trail of how your guardrails evolved over time.

Policy Change History

Best Practices

  • Start with Deny rules for your highest-risk scenarios (large transfers, unknown destinations) before adding convenience Allow rules
  • Remember that Deny always wins, use this to set hard limits that no Allow rule can override
  • Scope policies to specific wallets when different wallets have different risk profiles, rather than applying one broad policy everywhere
  • Use Allow rules sparingly, they bypass your approval queue, so reserve them for low-value, clearly trusted patterns
  • Validate every condition before submitting, and review the change in the approval step to confirm it behaves as intended
  • Treat policy changes with the same care as withdrawals, the approval gate exists so no single person can weaken your controls unnoticed