CrypDefi is now Fortkey. read the announcement

    Policy engine

    Policies are rules that govern wallet activity, enforced by the platform before any signature is created. One policy can be attached to multiple wallets. Policies are created per chain, because rules have chain-specific interpretations (an XRPL transaction type is not an EVM transaction type).

    There are two categories:

    • Access policies control who can use a wallet: grant or revoke permissions for users or groups.
    • Trading policies (signing policies) ensure specific criteria are met before a transaction signature can be created.

    Admins can simulate any policy against real transaction bytes before saving it (see the simulator section below).

    Access policies

    Each wallet has an access list of users and groups. A user may interact with a wallet only if they are explicitly listed or are a member of a listed group. Access is managed per wallet in the console.

    Trading policy rules

    Individual rules that can be enforced on a wallet. Rules combine through rule logic (below) into complex policies.

    Blacklist

    Blocks any transaction that directly involves a blacklisted address, even if other addresses are present. By default this evaluates clearly defined, directly accessible transaction fields (the primary address or contract), not addresses embedded inside smart contract payloads; use smart contract data validation for those.

    InputTypeDescription
    blacklist_addressesarray[string]Addresses that block signing if present in the transaction's destination fields.

    Whitelist

    Signs only if all directly involved addresses are whitelisted. Same payload caveat as the blacklist: embedded addresses need a data validation rule.

    InputTypeDescription
    whitelist_addressesarray[string]All destination addresses must be in this list.

    User access and group access

    Apply different nested restrictions to individual users or groups sharing the same wallet. Does not override the wallet's access list; combine with other rules. Example: a senior trader trades freely while a junior group is restricted to whitelisted swaps only.

    InputTypeDescription
    user_list / group_listarrayThe users or groups the nested rule logic applies to.

    Byte comparison

    Checks that a specific byte sequence appears at a given offset in the transaction. Powerful, but use only if you fully understand the transaction structure: variable-length fields can shift offsets, and different browser extensions can encode the same transaction differently. Prepare test cases covering every variation.

    InputTypeDescription
    expected_bytesstring (bytes)Byte sequence expected at the offset.
    indexintegerByte offset in the transaction.

    Transaction type

    Signs only payloads of an allowed type. Supported types are chain-specific.

    IP whitelist

    Restricts which source IPs can request signatures for a wallet, in standard CIDR notation (for example 192.0.2.0/24). Useful when trading runs from known network zones or a VPN.

    Smart contract data validation

    Byte comparison scoped to a specific smart contract address: if that address is involved in the transaction, the rule checks the associated data field for an expected byte sequence at a given offset; if the address is not involved, the rule passes. This is how you validate function calls and arguments embedded in contract payloads. Ask your Fortkey team for chain-specific examples.

    InputTypeDescription
    addressstringContract address to monitor.
    indexintegerByte offset in the data field.
    expected_bytesstring (bytes)Byte sequence that must match.

    Callback: bring your own policy (on request)

    Delegates the signing decision to your own server. The policy engine POSTs the user, wallet address, and transaction hex to your URL; your server responds allow or deny with a reason. Secured by an authorization token you validate, optional IP whitelisting in both directions, and a mandatory signed response: your server signs a SHA-256 hash of the response body with its ECDSA key, and Fortkey verifies it against your registered public key.

    Rule logic

    Rules combine with AND, OR, and NOT:

    • AND: all nested rules must pass.
    • OR: at least one nested rule must pass.
    • NOT: the nested rule must fail for the policy to pass.

    Pattern: user and group specific rules

    Combine OR with user access and group access rules to give different permission levels on a shared wallet: for example, full trading (minus a blacklist) for a senior trader, whitelisted swaps only for a junior group.

    Pattern: require an address to be present

    Whitelists are impractical when counterparties are only known at runtime (Solana swaps, for example). Wrapping a blacklist in NOT(...) flips the logic: the listed addresses must be present or the transaction is rejected, while unknown addresses are still allowed. Use as a structural safeguard, not as a replacement for instruction-level validation: on chains that allow multiple instructions per transaction, the presence of a trusted address does not prove the absence of a malicious instruction elsewhere.

    Chain-specific interpretations

    Signing is supported across 9 chain families including Canton. Every rule is documented per chain for Aptos, EVM, Polkadot, Radix, Solana, Stellar, Sui, and XRPL; Canton policy rule interpretation is on the roadmap. Two examples of why this matters:

    • On Aptos, destination addresses parse as the receiver of a transfer_coins payment or the module address being called, and raw signature requests carry no destination at all, so combining raw signing with whitelist rules will always fail (by design).
    • On Sui, destination addresses cannot be read from raw bytes and require an RPC call, which makes whitelist and blacklist rules unsuitable for high frequency flows on that chain today.

    Policy simulator

    Simulate policies before saving:

    • Sample transfer: prebuilt transactions where you set only the recipient, for quick whitelist and blacklist testing. Not suitable for byte-level rules.
    • Custom transaction: paste exact transaction hex to test byte comparison and data validation rules with full fidelity. Transaction history shows requested bytes you can reuse here.

    Each simulation runs as a selected user, so user and group rules are exercised too. Results show pass or fail per rule, with tooltips explaining any failure.

    Fortkey policy simulator running a sample transfer against active rules.

    The policy simulator: per-rule pass/fail results with tooltips on failures.

    Fortkey policy rules with a simulated transaction rejected by the whitelist.

    A simulated transaction rejected by a whitelist rule.

    Questions or a chain we should add?Talk to engineeringTry the sandboxpolicy-engine