策略

Fystack 策略是针对敏感钱包操作的可编程防护机制。策略以工作区为目标,可选地限定到特定钱包,并包含若干规则,这些规则会针对结构化的操作 payload 评估表达式。

规则会在以下四种操作上运行:

  • Name
    withdrawal.create
    Type
    trigger_action
    Description

    在创建提现之前评估。DENY 会阻止该请求。匹配的 ALLOW 会绕过交易审批,让提现直接进入签名阶段。

  • Name
    web3.transfer
    Type
    trigger_action
    Description

    当通过 Web3 原始交易 API 发送原生币或 ERC-20 转账时评估。它使用与 withdrawal.create 相同的 withdrawal.* 字段,因此同一个条件在两个触发器上含义一致。由于这些转账不是提现,速率(velocity)字段不可用。ERC-20 转账还会作为 web3.contract_call 进行评估。

  • Name
    web3.contract_call
    Type
    trigger_action
    Description

    在 EVM 合约调用和 ERC-20 代币转账发送去签名之前评估。DENY 会将该活动记录为 denied_by_policy。匹配的 ALLOW 会跳过交易审批并直接进入签名阶段。

  • Name
    web3.sign_message
    Type
    trigger_action
    Description

    当钱包被要求使用 personal_sign、eth_sign 或 eth_signTypedData_v4 签名消息时评估。仅支持拒绝:签名消息始终需要经过审批。

策略 schema 由 Apex 中的后端操作 schema 生成。构建 UI 构建器或动态校验字段可用性时,请使用获取策略 schema。如需现成的规则,请参阅策略模板。


策略结构

策略是容器,规则是可执行单元。

{
  "name": "Large withdrawal guard",
  "approval_group_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
  "wallet_ids": [],
  "rules": [
    {
      "trigger_action": "withdrawal.create",
      "condition": "withdrawal.value_usd > 10000 && !withdrawal.is_whitelisted",
      "effect": "DENY"
    }
  ]
}
  • Name
    approval_group_id
    Type
    string
    Description

    负责审核策略创建、策略编辑、策略删除和规则变更的审批组。

  • Name
    wallet_ids
    Type
    string[]
    Description

    该策略适用的钱包。空数组表示工作区中的所有钱包。

  • Name
    rules
    Type
    array
    Description

    最多 50 条规则。每条规则包含 trigger_action、condition、effect,以及可选的 description 和 is_enabled。

策略状态

  • Name
    pending
    Type
    status
    Description

    已创建但尚未批准。待处理的策略不会被评估。

  • Name
    active
    Type
    status
    Description

    已批准并生效。评估器只加载 active 状态的策略。

  • Name
    inactive
    Type
    status
    Description

    已禁用,不会被评估。

  • Name
    rejected
    Type
    status
    Description

    在审批中被拒绝,不会被评估。


策略评估

对于每个受保护的请求,Fystack 会加载工作区的 active 策略,编译已启用的规则,按操作和钱包目标筛选匹配项,然后按以下方式得出结果:

  1. 如果任一匹配规则的 effect: "DENY",则该操作被阻止。
  2. 否则,如果任一匹配规则的 effect: "ALLOW",则该操作继续执行,并绕过交易审批。
  3. 否则,表示没有策略规则匹配。该操作继续走正常的审批流程。

DENY 始终优先于 ALLOW,因此规则顺序永远不会改变结果。在胜出的 effect 中,按声明顺序第一个匹配的规则用于归因,因此 API 可以返回稳定的 rule_id 和策略原因。

不存在单独的 "require approval" effect。对于没有任何 ALLOW 规则匹配的操作,默认都需要审批。

评估采用失败即拒绝(fail-closed)原则。缓存、数据库、编译或运行时评估出现故障时,操作都会被拒绝。每次评估的超时时间为 100 ms。

作用域与缓存

策略以工作区为作用域。Apex 会为每个工作区缓存一个编译后的策略包,并在策略被批准、拒绝以及钱包目标变更后使其失效。钱包筛选在评估时进行,因此一个工作区的策略包可以服务于该工作区内的所有钱包。


条件

condition 是一个必须返回布尔值的表达式。通过分区和字段名引用字段,例如 principal.role、withdrawal.value_usd、wallet.purpose 或 resource.method_selector。

可使用常规的布尔、比较和成员运算符:

&&  ||  !  ==  !=  >  >=  <  <=  in

in 用于检查是否属于某个列表字面量或列表字段,例如 principal.api_key_id in ["<api_key_id>"] 或 "0x…" in resource.permit_tokens。

示例:

  • Name
    拒绝大额且未加入白名单的提现
    Type
    DENY
    Description

    withdrawal.value_usd > 10000 && !withdrawal.is_whitelisted

  • Name
    每个钱包每天上限 $100,000
    Type
    DENY
    Description

    wallet.projected_outflow_24h > 100000

  • Name
    将托管资金保留在工作区内
    Type
    DENY
    Description

    wallet.purpose == "custody" && !withdrawal.destination_is_internal

  • Name
    为支付 API key 绕过审批
    Type
    ALLOW
    Description

    principal.initiator_type == "api_key" && principal.api_key_id in ["<api_key_id>"] && withdrawal.value_usd < 1000

  • Name
    为添加已久的地址簿条目绕过审批
    Type
    ALLOW
    Description

    withdrawal.is_whitelisted && withdrawal.address_age_sec >= 86400 && withdrawal.value_usd <= 1000

  • Name
    拒绝周末的高额提现
    Type
    DENY
    Description

    (context.day_of_week == "Saturday" || context.day_of_week == "Sunday") && withdrawal.value_usd > 25000

  • Name
    拒绝高 gas 的 ERC-20 转账
    Type
    DENY
    Description

    resource.method_selector == "0xa9059cbb" && resource.gas_limit > 100000

  • Name
    拒绝无限额的代币 permit
    Type
    DENY
    Description

    resource.is_permit && resource.permit_amount_is_unlimited

resource.decoded_args 是动态的。读取动态字段前请先用 has(...) 进行判断,例如 has(resource.decoded_args.to) && resource.decoded_args.to == "0x000000000000000000000000000000000000dead"。

引用字段

schema 中标记了 ref 的字段保存的是另一个工作区实体的 ID 或代码:workspace_user、api_key、wallet、address_book、network 或 asset_symbol。条件构建器应为这些字段渲染选择器。

保存规则时,Fystack 会检查每个被引用的 ID 是否属于你的工作区。如果某个实体之后被删除或吊销,规则仍保留该 ID,只会匹配得更少,绝不会更多。


操作 schema

操作 schema 定义了条件中可用的字段。标记为 deprecated 的字段在已有规则中仍会被评估,但不应在新规则中使用。

通用字段

每种触发操作都提供以下字段。

  • Name
    principal.user_id
    Type
    string · ref workspace_user
    Description

    发起操作的工作区成员 ID。当发起方为 API key 时为空。

  • Name
    principal.role
    Type
    string
    Description

    工作区角色。取值为 owner、admin、signer、proposer 或 viewer 之一。

  • Name
    principal.initiator_type
    Type
    string
    Description

    网页会话为 user,API key 为 api_key。

  • Name
    principal.api_key_id
    Type
    string · ref api_key
    Description

    发起操作的 API key 的 ID。网页会话时为空,因此请与 principal.initiator_type 结合使用。

  • Name
    principal.user_email
    Type
    string · deprecated
    Description

    发起用户的邮箱。由于邮箱可能变更,请改用 principal.user_id。

  • Name
    wallet.id
    Type
    string · ref wallet
    Description

    源钱包 ID。用于在一个策略内针对特定钱包的规则。

  • Name
    wallet.purpose
    Type
    string
    Description

    源钱包用途。取值为 general、custody、payment、user、one_time_use、gas_tank 或 deployment 之一。

  • Name
    wallet.type
    Type
    string
    Description

    源钱包类型。standard 或 mpc。

  • Name
    context.hour
    Type
    integer
    Description

    评估时的 UTC 小时,取值 0 到 23。

  • Name
    context.day_of_week
    Type
    string
    Description

    UTC 星期名称,例如 Monday 或 Saturday。

提现字段

适用于 withdrawal.create 和 web3.transfer。

  • Name
    withdrawal.amount
    Type
    number
    Description

    请求的资产数量。

  • Name
    withdrawal.value_usd
    Type
    number
    Description

    请求的 USD 价值。

  • Name
    withdrawal.asset_symbol
    Type
    string · ref asset_symbol
    Description

    资产符号,例如 USDT、ETH 或 BTC。

  • Name
    withdrawal.asset_is_native
    Type
    boolean
    Description

    该资产是否为网络原生资产。

  • Name
    withdrawal.asset_is_known
    Type
    boolean
    Description

    该代币是否在 Fystack 资产目录中。为 false 时,amount、value_usd 和 asset_symbol 为空,因此如有需要,请显式拒绝未知代币。

  • Name
    withdrawal.token_address
    Type
    string
    Description

    代币合约地址。原生币时为空。

  • Name
    withdrawal.destination_address
    Type
    string
    Description

    收款地址。

  • Name
    withdrawal.network_code
    Type
    string · ref network
    Description

    内部网络代码。

  • Name
    withdrawal.is_whitelisted
    Type
    boolean
    Description

    目标地址是否存在于工作区的任一地址簿条目中。

  • Name
    withdrawal.address_book_id
    Type
    string · ref address_book
    Description

    包含目标地址的地址簿条目。一个条目涵盖其下的所有地址,因此条目可以作为命名列表使用。

  • Name
    withdrawal.address_age_sec
    Type
    number
    Description

    目标地址被添加到其地址簿条目以来的秒数。可用于对新添加的收款方设置冷却期规则。

  • Name
    withdrawal.destination_is_internal
    Type
    boolean
    Description

    目标是否为同一工作区内的另一个钱包。

  • Name
    withdrawal.destination_wallet_id
    Type
    string · ref wallet
    Description

    当目标为内部钱包时的目标钱包。

提现速率字段

仅适用于 withdrawal.create。除非另有说明,所有值均以 USD 计。

  • Name
    wallet.outflow_1h / outflow_6h / outflow_24h
    Type
    number
    Description

    源钱包在过去 1、6 或 24 小时内的已实现流出量。

  • Name
    wallet.withdrawal_count_1h
    Type
    integer
    Description

    源钱包在过去一小时内的提现尝试次数。

  • Name
    wallet.pending_outflow
    Type
    number
    Description

    源钱包中尚未执行的提现总价值。

  • Name
    wallet.projected_outflow_24h
    Type
    number
    Description

    源钱包的预计流出量:过去 24 小时已实现流出量,加上待处理流出量,再加上正在检查的这笔提现。

  • Name
    wallet.asset_projected_outflow_24h
    Type
    number
    Description

    以所提现资产为单位计算的源钱包同类预计值,例如每天最多 5 BTC。

  • Name
    workspace.outflow_1h / outflow_6h / outflow_24h
    Type
    number
    Description

    工作区在过去 1、6 或 24 小时内的已实现流出量。

  • Name
    workspace.withdrawal_count_1h
    Type
    integer
    Description

    工作区在过去一小时内的提现尝试次数。

  • Name
    workspace.pending_outflow
    Type
    number
    Description

    工作区中尚未执行的提现总价值。

  • Name
    workspace.projected_outflow_24h
    Type
    number
    Description

    工作区预计流出量:过去 24 小时已实现流出量,加上待处理流出量,再加上正在检查的这笔提现。

  • Name
    workspace.network_outflow_1h / network_outflow_6h / network_outflow_24h
    Type
    number
    Description

    工作区在当前网络上过去 1、6 或 24 小时内的已实现流出量。

  • Name
    workspace.network_withdrawal_count_1h
    Type
    integer
    Description

    工作区在当前网络上过去一小时内的提现尝试次数。

  • Name
    workspace.network_pending_outflow
    Type
    number
    Description

    工作区在当前网络上的待处理流出量。

  • Name
    workspace.network_projected_outflow_24h
    Type
    number
    Description

    工作区在当前网络上的预计流出量。

  • Name
    workspace.initiator_projected_outflow_24h
    Type
    number
    Description

    由同一成员或 API key 在整个工作区内创建的提现的预计流出量。

流出量和计数字段均为已实现值:只有当提现达到已执行或成功的终态后才会被计入。待处理流出量统计的是正在等待审批、排队中或正在补充 gas 的提现,无论其存在多久。

当某条 active 规则使用了待处理或预计字段时,Fystack 会逐个评估该工作区的提现,因此两个并发请求不可能同时通过同一限额。等待超过 5 秒仍未轮到的请求会以 HTTP 429 被拒绝,可以重试。

web3.contract_call 字段

  • Name
    resource.network_code
    Type
    string · ref network
    Description

    内部网络代码。

  • Name
    resource.contract_address
    Type
    string
    Description

    来自原始交易 to 字段的小写合约地址。

  • Name
    resource.method_selector
    Type
    string
    Description

    小写的 4 字节选择器,例如 0xa9059cbb。

  • Name
    resource.method_name
    Type
    string
    Description

    请求元数据中提供的方法名(如有)。

  • Name
    resource.value_wei
    Type
    string
    Description

    随调用发送的原生币数量,以字符串表示。

  • Name
    resource.gas_limit
    Type
    integer
    Description

    原始交易中的 gas limit。

  • Name
    resource.decoded_args
    Type
    map
    Description

    当 Fystack 能识别该调用时解码出的参数。ERC-20 transfer 会提供 to 和 value。

web3.sign_message 字段

  • Name
    resource.method
    Type
    string
    Description

    签名方法。取值为 personal_sign、eth_sign 或 eth_signTypedData_v4 之一。

  • Name
    resource.network_code
    Type
    string · ref network
    Description

    内部网络代码。

  • Name
    resource.typed_data_primary_type
    Type
    string
    Description

    EIP-712 primary type,用于类型化数据消息。

  • Name
    resource.typed_data_domain_name
    Type
    string
    Description

    EIP-712 domain name,用于类型化数据消息。

  • Name
    resource.typed_data_verifying_contract
    Type
    string
    Description

    EIP-712 verifying contract,用于类型化数据消息。

  • Name
    resource.is_permit
    Type
    boolean
    Description

    对于 EIP-2612、DAI 和 Permit2 消息为 true,这类消息允许 spender 之后无需再次签名即可转移代币。

  • Name
    resource.permit_spender
    Type
    string
    Description

    permit 授权的地址。

  • Name
    resource.permit_tokens
    Type
    string[]
    Description

    permit 涵盖的代币合约。可与 in 一起使用,例如 "0x…" in resource.permit_tokens。

  • Name
    resource.permit_amount_is_unlimited
    Type
    boolean
    Description

    对于最大额度授权(2159 或以上,或设置了 allowed 的 DAI permit)为 true。

  • Name
    resource.permit_deadline
    Type
    integer
    Description

    permit 或其签名过期的 Unix 时间。消息中没有时为 0。


审批生命周期

创建、更新和删除策略的操作都受审批管控。变更操作会创建一个 policy 审批请求,并返回 status: "pending_approval" 以及 approval_request_id。只有在审批组达到门限后,策略变更才会生效。

当父策略配置了审批组时,规则的创建、更新和删除操作也遵循相同的模式。待处理的修订会保存字段级差异,以供审计和审核。

通过 /wallets 更新钱包目标会在校验和缓存失效后立即生效。如果希望钱包目标的变更作为更大的策略修订的一部分接受审核,请使用策略更新 endpoint。


认证

策略 API endpoint 接受已签名的 API key 请求或 bearer access token。

  • Name
    ACCESS-API-KEY
    Type
    header
    Description

    用于 HMAC 认证请求的 API key UUID。

  • Name
    ACCESS-TIMESTAMP
    Type
    header
    Description

    用于构建 HMAC 签名的 UNIX 时间戳(秒)。

  • Name
    ACCESS-SIGN
    Type
    header
    Description

    Base64 编码的 HMAC 签名。签名格式请参阅认证。

  • Name
    Authorization
    Type
    header
    Description

    用于用户会话请求的 bearer access token。

策略审批决策 endpoint 仍然是用户会话 endpoint。批准和拒绝审批请求时请使用 bearer access token。

响应信封

成功的 JSON 响应使用标准的 Fystack 信封格式。

  • Name
    success
    Type
    boolean
    Description

    请求成功时为 true。

  • Name
    message
    Type
    string
    Description

    响应消息,通常为 success。

  • Name
    code
    Type
    integer
    Description

    数字结果代码。成功响应使用 0。

  • Name
    data
    Type
    object | array | null
    Description

    特定于 endpoint 的响应 payload。

校验错误使用相同的信封格式,其中 success: false,并包含 errors 数组。

数据类型

Policy

  • Name
    id
    Type
    string
    Description

    策略 UUID。

  • Name
    created_at
    Type
    string
    Description

    策略创建时间的 ISO 时间戳。

  • Name
    updated_at
    Type
    string
    Description

    策略最后更新时间的 ISO 时间戳。

  • Name
    name
    Type
    string
    Description

    策略名称。3 到 100 个字符。

  • Name
    description
    Type
    string
    Description

    可选描述。最多 500 个字符。

  • Name
    status
    Type
    string
    Description

    取值为 pending、rejected、active 或 inactive 之一。

  • Name
    version
    Type
    integer
    Description

    策略版本号。

  • Name
    workspace_id
    Type
    string
    Description

    工作区 UUID。

  • Name
    approval_group_id
    Type
    string | null
    Description

    分配给该策略的审批组 UUID。

  • Name
    wallet_ids
    Type
    string[]
    Description

    目标钱包 UUID。空数组表示该策略针对工作区中的所有钱包。

  • Name
    rules
    Type
    PolicyRule[]
    Description

    在预加载规则的 endpoint 中返回。

  • Name
    approval_group
    Type
    object
    Description

    在预加载审批组的 endpoint 中返回。

  • Name
    pending_approval_request
    Type
    object
    Description

    当该策略存在待处理的审批请求时返回。

PolicyRule

  • Name
    id
    Type
    string
    Description

    规则 UUID。

  • Name
    policy_id
    Type
    string
    Description

    父策略 UUID。

  • Name
    trigger_action
    Type
    string
    Description

    取值为 withdrawal.create、web3.transfer、web3.contract_call 或 web3.sign_message 之一。

  • Name
    condition
    Type
    string
    Description

    布尔条件表达式。1 到 4000 个字符。

  • Name
    effect
    Type
    string
    Description

    取值为 ALLOW 或 DENY 之一。

  • Name
    description
    Type
    string
    Description

    可选描述。最多 500 个字符。

  • Name
    is_enabled
    Type
    boolean
    Description

    规则是否启用。创建时如省略则默认为 true。

变更响应

策略和规则的变更 endpoint 会在 data 中返回变更 payload。

  • Name
    status
    Type
    string
    Description

    取值为 applied、pending_approval 或 deleted 之一,取决于具体操作。

  • Name
    policy
    Type
    Policy
    Description

    适用时由策略变更 endpoint 返回。

  • Name
    rule
    Type
    PolicyRule
    Description

    适用时由规则变更 endpoint 返回。

  • Name
    approval_request_id
    Type
    string
    Description

    当变更正在等待审批时返回。

获取策略 schema

GET
/policy/schema

返回条件可以引用的字段,按 trigger_action 和分区分组。可将此 endpoint 用于条件构建器和客户端预览。

每个字段都有 name 和 type。可选键:

  • Name
    enum
    Type
    string[]
    Description

    该字段允许的取值。

  • Name
    ref
    Type
    string
    Description

    该字段引用的实体。请为其渲染选择器。参阅引用字段。

  • Name
    deprecated
    Type
    boolean
    Description

    在已有规则中仍会被评估。请在新规则构建器中隐藏它。

Request

GET
/policy/schema
curl -X GET https://api.fystack.io/api/v1/policy/schema \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

Response

200
{
  "success": true,
  "message": "success",
  "code": 0,
  "data": {
    "withdrawal.create": {
      "principal": [
        { "name": "user_email", "type": "string", "deprecated": true },
        { "name": "user_id", "type": "string", "ref": "workspace_user" },
        { "name": "role", "type": "string", "enum": ["owner", "admin", "signer", "proposer", "viewer"] },
        { "name": "initiator_type", "type": "string", "enum": ["user", "api_key"] },
        { "name": "api_key_id", "type": "string", "ref": "api_key" }
      ],
      "withdrawal": [
        { "name": "amount", "type": "number" },
        { "name": "value_usd", "type": "number" },
        { "name": "asset_symbol", "type": "string", "ref": "asset_symbol" },
        { "name": "asset_is_native", "type": "boolean" },
        { "name": "asset_is_known", "type": "boolean" },
        { "name": "token_address", "type": "string" },
        { "name": "destination_address", "type": "string" },
        { "name": "network_code", "type": "string", "ref": "network" },
        { "name": "is_whitelisted", "type": "boolean" },
        { "name": "address_age_sec", "type": "number" },
        { "name": "address_book_id", "type": "string", "ref": "address_book" },
        { "name": "destination_is_internal", "type": "boolean" },
        { "name": "destination_wallet_id", "type": "string", "ref": "wallet" }
      ],
      "wallet": [
        { "name": "id", "type": "string", "ref": "wallet" },
        { "name": "purpose", "type": "string", "enum": ["general", "custody", "payment", "user", "one_time_use", "gas_tank", "deployment"] },
        { "name": "type", "type": "string", "enum": ["standard", "mpc"] },
        { "name": "outflow_1h", "type": "number" },
        { "name": "outflow_6h", "type": "number" },
        { "name": "outflow_24h", "type": "number" },
        { "name": "withdrawal_count_1h", "type": "integer" },
        { "name": "pending_outflow", "type": "number" },
        { "name": "projected_outflow_24h", "type": "number" },
        { "name": "asset_projected_outflow_24h", "type": "number" }
      ],
      "workspace": [
        { "name": "outflow_1h", "type": "number" },
        { "name": "outflow_6h", "type": "number" },
        { "name": "outflow_24h", "type": "number" },
        { "name": "withdrawal_count_1h", "type": "integer" },
        { "name": "network_outflow_1h", "type": "number" },
        { "name": "network_outflow_6h", "type": "number" },
        { "name": "network_outflow_24h", "type": "number" },
        { "name": "network_withdrawal_count_1h", "type": "integer" },
        { "name": "pending_outflow", "type": "number" },
        { "name": "projected_outflow_24h", "type": "number" },
        { "name": "network_pending_outflow", "type": "number" },
        { "name": "network_projected_outflow_24h", "type": "number" },
        { "name": "initiator_projected_outflow_24h", "type": "number" }
      ],
      "context": [
        { "name": "hour", "type": "integer" },
        { "name": "day_of_week", "type": "string" }
      ]
    },
    "web3.transfer": {
      "principal": [ "... same as withdrawal.create ..." ],
      "withdrawal": [ "... same as withdrawal.create ..." ],
      "wallet": [
        { "name": "id", "type": "string", "ref": "wallet" },
        { "name": "purpose", "type": "string", "enum": ["general", "custody", "payment", "user", "one_time_use", "gas_tank", "deployment"] },
        { "name": "type", "type": "string", "enum": ["standard", "mpc"] }
      ],
      "context": [ "... same as withdrawal.create ..." ]
    },
    "web3.contract_call": {
      "principal": [ "... same as withdrawal.create ..." ],
      "resource": [
        { "name": "network_code", "type": "string", "ref": "network" },
        { "name": "contract_address", "type": "string" },
        { "name": "method_selector", "type": "string" },
        { "name": "method_name", "type": "string" },
        { "name": "value_wei", "type": "string" },
        { "name": "gas_limit", "type": "integer" },
        { "name": "decoded_args", "type": "map" }
      ],
      "wallet": [ "... id, purpose, type ..." ],
      "context": [ "... same as withdrawal.create ..." ]
    },
    "web3.sign_message": {
      "principal": [ "... same as withdrawal.create ..." ],
      "resource": [
        { "name": "method", "type": "string", "enum": ["personal_sign", "eth_sign", "eth_signTypedData_v4"] },
        { "name": "network_code", "type": "string", "ref": "network" },
        { "name": "typed_data_primary_type", "type": "string" },
        { "name": "typed_data_domain_name", "type": "string" },
        { "name": "typed_data_verifying_contract", "type": "string" },
        { "name": "is_permit", "type": "boolean" },
        { "name": "permit_spender", "type": "string" },
        { "name": "permit_tokens", "type": "string[]" },
        { "name": "permit_amount_is_unlimited", "type": "boolean" },
        { "name": "permit_deadline", "type": "integer" }
      ],
      "wallet": [ "... id, purpose, type ..." ],
      "context": [ "... same as withdrawal.create ..." ]
    }
  }
}

校验规则

POST
/workspaces/{workspace_id}/policies/rules/validate

校验规则内容,而不创建或更新规则。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

请求体参数

  • Name
    trigger_action
    Type
    string
    Required
    required
    Description

    取值为 withdrawal.create、web3.transfer、web3.contract_call 或 web3.sign_message 之一。

  • Name
    condition
    Type
    string
    Required
    required
    Description

    1 到 4000 个字符。必须能编译为布尔表达式。

  • Name
    effect
    Type
    string
    Required
    required
    Description

    取值为 ALLOW 或 DENY 之一。web3.sign_message 规则仅支持拒绝。

响应数据

  • Name
    valid
    Type
    boolean
    Description

    规则内容校验通过时为 true。

Request

POST
/workspaces/{workspace_id}/policies/rules/validate
curl -X POST https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/rules/validate \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature==" \
  -H "Content-Type: application/json" \
  -d '{
    "trigger_action": "withdrawal.create",
    "condition": "withdrawal.value_usd > 10000",
    "effect": "DENY"
  }'

Response

200
{
  "success": true,
  "message": "success",
  "code": 0,
  "data": { "valid": true }
}

创建策略

POST
/workspaces/{workspace_id}/policies

创建一个策略变更。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

请求体参数

  • Name
    name
    Type
    string
    Required
    required
    Description

    3 到 100 个字符。

  • Name
    description
    Type
    string
    Description

    Optional. Up to 500 characters.

  • Name
    approval_group_id
    Type
    string
    Required
    required
    Description

    审批组 UUID。

  • Name
    wallet_ids
    Type
    string[]
    Description

    可选。最多 500 个钱包 UUID。

  • Name
    rules
    Type
    PolicyRuleCreate[]
    Description

    可选。最多 50 条规则。

Request

POST
/workspaces/{workspace_id}/policies
curl -X POST https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature==" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Large withdrawal guard",
    "approval_group_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
    "wallet_ids": [],
    "rules": [
      {
        "trigger_action": "withdrawal.create",
        "condition": "withdrawal.value_usd > 10000",
        "effect": "DENY"
      }
    ]
  }'

Response

200
{
  "success": true,
  "message": "success",
  "code": 0,
  "data": {
    "status": "pending_approval",
    "approval_request_id": "b7e2a1c4-9d8f-4a3b-8c1d-2e3f4a5b6c7d",
    "policy": {
      "id": "9c8b7a6d-5e4f-3210-9a8b-7c6d5e4f3210",
      "name": "Large withdrawal guard",
      "status": "pending",
      "version": 1,
      "wallet_ids": []
    }
  }
}

列出策略

GET
/workspaces/{workspace_id}/policies

返回工作区中的策略。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

查询参数

  • Name
    status
    Type
    string
    Description

    可选。取值为 pending、rejected、active 或 inactive 之一。

  • Name
    limit
    Type
    integer
    Description

    可选。最大值 1000。

  • Name
    offset
    Type
    integer
    Description

    可选。最大值 100000。

响应数据

  • Name
    data
    Type
    Policy[]
    Description

    策略对象数组。

Request

GET
/workspaces/{workspace_id}/policies
curl -X GET "https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies?status=active&limit=20&offset=0" \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

获取策略

GET
/workspaces/{workspace_id}/policies/{policy_id}

返回单个策略。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

响应数据

  • Name
    data
    Type
    Policy
    Description

    策略对象,包含规则、审批组以及待处理的审批请求(如有)。

Request

GET
/workspaces/{workspace_id}/policies/{policy_id}
curl -X GET https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id} \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

更新策略

PUT
/workspaces/{workspace_id}/policies/{policy_id}

更新策略字段。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

请求体参数

  • Name
    name
    Type
    string
    Description

    可选。3 到 100 个字符。

  • Name
    description
    Type
    string
    Description

    Optional. Up to 500 characters.

  • Name
    approval_group_id
    Type
    string
    Description

    可选的审批组 UUID。

  • Name
    wallet_ids
    Type
    string[]
    Description

    可选。最多 500 个钱包 UUID。传入空数组表示针对所有钱包。

  • Name
    rules
    Type
    PolicyRuleCreate[]
    Description

    可选。传入时会替换完整的规则集。传入空数组可清除所有规则。

Request

PUT
/workspaces/{workspace_id}/policies/{policy_id}
curl -X PUT https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id} \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature==" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Updated policy description",
    "wallet_ids": ["e0851607-417a-475a-b399-5f3aa262b81d"]
  }'

删除策略

DELETE
/workspaces/{workspace_id}/policies/{policy_id}

删除策略,或创建一个等待审批的删除变更。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

响应数据

  • Name
    data
    Type
    Mutation response
    Description

    策略变更响应。

Request

DELETE
/workspaces/{workspace_id}/policies/{policy_id}
curl -X DELETE https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id} \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

获取策略历史

GET
/workspaces/{workspace_id}/policies/{policy_id}/history

返回某个策略的修订记录。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

响应数据

  • Name
    data
    Type
    PolicyRevision[]
    Description

    策略修订数组,包含字段级 changes(如有)。

Request

GET
/workspaces/{workspace_id}/policies/{policy_id}/history
curl -X GET https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id}/history \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

获取策略钱包

GET
/workspaces/{workspace_id}/policies/{policy_id}/wallets

返回策略及其当前的 wallet_ids。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

响应数据

  • Name
    data
    Type
    Policy
    Description

    策略对象。

Request

GET
/workspaces/{workspace_id}/policies/{policy_id}/wallets
curl -X GET https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id}/wallets \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

更新策略钱包

PUT
/workspaces/{workspace_id}/policies/{policy_id}/wallets

替换策略的钱包目标列表。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

请求体参数

  • Name
    wallet_ids
    Type
    string[]
    Description

    可选。最多 500 个钱包 UUID。传入空数组表示针对所有钱包。

Request

PUT
/workspaces/{workspace_id}/policies/{policy_id}/wallets
curl -X PUT https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id}/wallets \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature==" \
  -H "Content-Type: application/json" \
  -d '{ "wallet_ids": ["e0851607-417a-475a-b399-5f3aa262b81d"] }'

创建策略规则

POST
/workspaces/{workspace_id}/policies/{policy_id}/rules

在已有策略下创建一条规则。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    policy_id
    Type
    string
    Description

    Policy UUID.

请求体参数

  • Name
    id
    Type
    string
    Description

    可选的规则 UUID。

  • Name
    trigger_action
    Type
    string
    Required
    required
    Description

    取值为 withdrawal.create、web3.transfer、web3.contract_call 或 web3.sign_message 之一。

  • Name
    condition
    Type
    string
    Required
    required
    Description

    1 到 4000 个字符。

  • Name
    effect
    Type
    string
    Required
    required
    Description

    取值为 ALLOW 或 DENY 之一。web3.sign_message 规则仅支持拒绝。

  • Name
    description
    Type
    string
    Description

    可选。最多 500 个字符。

  • Name
    is_enabled
    Type
    boolean
    Description

    可选。默认为 true。

Request

POST
/workspaces/{workspace_id}/policies/{policy_id}/rules
curl -X POST https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/{policy_id}/rules \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature==" \
  -H "Content-Type: application/json" \
  -d '{
    "trigger_action": "web3.contract_call",
    "condition": "resource.gas_limit > 100000",
    "effect": "DENY",
    "is_enabled": true
  }'

更新策略规则

PUT
/workspaces/{workspace_id}/policies/rules/{rule_id}

更新可变的规则字段。触发操作不可变,如需更改,请删除并重新创建该规则。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    rule_id
    Type
    string
    Description

    Rule UUID.

请求体参数

  • Name
    condition
    Type
    string
    Description

    可选。1 到 4000 个字符。

  • Name
    effect
    Type
    string
    Description

    可选。取值为 ALLOW 或 DENY 之一。

  • Name
    description
    Type
    string
    Description

    可选。最多 500 个字符。

  • Name
    is_enabled
    Type
    boolean
    Description

    可选。

Request

PUT
/workspaces/{workspace_id}/policies/rules/{rule_id}
curl -X PUT https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/rules/{rule_id} \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature==" \
  -H "Content-Type: application/json" \
  -d '{
    "condition": "resource.gas_limit > 150000",
    "is_enabled": true
  }'

删除策略规则

DELETE
/workspaces/{workspace_id}/policies/rules/{rule_id}

删除一条策略规则,或创建一个等待审批的规则删除变更。

路径参数

  • Name
    workspace_id
    Type
    string
    Description

    Workspace UUID.

  • Name
    rule_id
    Type
    string
    Description

    Rule UUID.

响应数据

  • Name
    data
    Type
    Mutation response
    Description

    规则变更响应。

Request

DELETE
/workspaces/{workspace_id}/policies/rules/{rule_id}
curl -X DELETE https://api.fystack.io/api/v1/workspaces/{workspace_id}/policies/rules/{rule_id} \
  -H "ACCESS-API-KEY: your_api_key" \
  -H "ACCESS-TIMESTAMP: 1667836889" \
  -H "ACCESS-SIGN: YourBase64EncodedSignature=="

设计模式

将 DENY 规则用于硬性控制:制裁名单、未知收款方、新的地址簿条目、预计流出量限额、未知代币、无限额 permit 或高风险合约方法。

谨慎地缩小 ALLOW 规则的范围。匹配的 ALLOW 会跳过审批,因此条件应当精确:低 USD 金额、受信任的发起方、已知的目标钱包、已知的网络,以及经过地址存在时长检查的已知收款方,或已知的合约和方法。

为每条 ALLOW 搭配一个 DENY 上限,例如 wallet.projected_outflow_24h 或 workspace.initiator_projected_outflow_24h。由于 DENY 始终优先,这个上限同样会限制自动批准的路径。

保持策略集精简且明确。覆盖整个工作区的宽泛策略适合作为基线控制;当热钱包、资金库钱包或客户钱包有不同的风险阈值时,以钱包为作用域的策略更为合适。

完整示例请参阅策略模板。