Políticas
Las políticas de Fystack son salvaguardas programables para acciones sensibles de billeteras. Una política se aplica a un espacio de trabajo, opcionalmente se limita a billeteras específicas y contiene reglas que evalúan una expresión sobre un payload estructurado de la acción.
Las reglas se ejecutan para cuatro acciones:
- Name
- withdrawal.create
- Type
- trigger_action
- Description
Se evalúa antes de crear un retiro. Un
DENYbloquea la solicitud. UnALLOWcoincidente omite la aprobación de la transacción y permite que el retiro pase a la firma.
- Name
- web3.transfer
- Type
- trigger_action
- Description
Se evalúa cuando se envía una transferencia de moneda nativa o ERC-20 a través de la API de transacciones sin procesar de Web3. Usa los mismos campos
withdrawal.*quewithdrawal.create, por lo que una condición se lee igual en ambos disparadores. Los campos de velocidad no están disponibles, porque estas transferencias no son retiros. Las transferencias ERC-20 también se evalúan comoweb3.contract_call.
- Name
- web3.contract_call
- Type
- trigger_action
- Description
Se evalúa antes de que las llamadas a contratos EVM y las transferencias de tokens ERC-20 se envíen a la firma. Un
DENYregistra la actividad comodenied_by_policy. UnALLOWcoincidente omite la aprobación de la transacción y continúa con la firma.
- Name
- web3.sign_message
- Type
- trigger_action
- Description
Se evalúa cuando se solicita a una billetera firmar un mensaje con
personal_sign,eth_signoeth_signTypedData_v4. Solo admite denegación: un mensaje firmado siempre pasa por aprobación.
El esquema de políticas se genera a partir del esquema de acciones del backend en Apex. Usa Obtener el esquema de políticas al crear constructores de UI o para validar dinámicamente la disponibilidad de campos. Para reglas listas para usar, consulta Plantillas de políticas.
Estructura de una política
Una política es el contenedor. Una regla es la unidad ejecutable.
{
"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
El grupo de aprobación que revisa la creación, edición y eliminación de políticas, así como los cambios en las reglas.
- Name
- wallet_ids
- Type
- string[]
- Description
Billeteras a las que se aplica esta política. Un array vacío significa todas las billeteras del espacio de trabajo.
- Name
- rules
- Type
- array
- Description
Hasta 50 reglas. Cada regla tiene
trigger_action,condition,effect,descriptionopcional eis_enabledopcional.
Estados de una política
- Name
- pending
- Type
- status
- Description
Creada pero aún no aprobada. Las políticas pendientes no se evalúan.
- Name
- active
- Type
- status
- Description
Aprobada y en vigor. El evaluador solo carga las políticas activas.
- Name
- inactive
- Type
- status
- Description
Deshabilitada y no se evalúa.
- Name
- rejected
- Type
- status
- Description
Rechazada durante la aprobación y no se evalúa.
Evaluación de políticas
Para cada solicitud protegida, Fystack carga las políticas activas del espacio de trabajo, compila las reglas habilitadas, filtra las coincidencias por acción y por billeteras objetivo, y luego resuelve el resultado:
- Si alguna regla coincidente tiene
effect: "DENY", la acción se bloquea. - De lo contrario, si alguna regla coincidente tiene
effect: "ALLOW", la acción continúa y se omite la aprobación de la transacción. - De lo contrario, ninguna regla de política coincidió. La acción continúa por el flujo de aprobación normal.
DENY siempre prevalece sobre ALLOW, por lo que el orden de las reglas nunca cambia el resultado. Dentro del efecto ganador, la primera coincidencia en orden de declaración se usa para la atribución, de modo que la API puede devolver un rule_id estable y el motivo de la política.
No existe un efecto separado de "requerir aprobación". La aprobación es el comportamiento predeterminado para cualquier acción que no coincida con ninguna regla ALLOW.
La evaluación es fail-closed. Los fallos de caché, base de datos, compilación o evaluación en tiempo de ejecución deniegan la acción. Cada evaluación tiene un timeout de 100 ms.
Alcance y caché
Las políticas tienen alcance por espacio de trabajo. Apex almacena en caché un paquete de políticas compilado por espacio de trabajo y lo invalida tras aprobaciones o rechazos de políticas y cambios en las billeteras objetivo. El filtrado por billetera ocurre durante la evaluación, por lo que un mismo paquete puede servir a todas las billeteras de ese espacio de trabajo.
Condiciones
condition es una expresión que debe devolver un booleano. Haz referencia a los campos por sección y nombre de campo, por ejemplo principal.role, withdrawal.value_usd, wallet.purpose o resource.method_selector.
Usa los operadores habituales booleanos, de comparación y de pertenencia:
&& || ! == != > >= < <= in
in comprueba la pertenencia a una lista literal o a un campo de tipo lista, por ejemplo principal.api_key_id in ["<api_key_id>"] o "0x…" in resource.permit_tokens.
Ejemplos:
- Name
- Denegar retiros grandes a direcciones no incluidas en la lista blanca
- Type
- DENY
- Description
withdrawal.value_usd > 10000 && !withdrawal.is_whitelisted
- Name
- Limitar cada billetera a $100,000 por día
- Type
- DENY
- Description
wallet.projected_outflow_24h > 100000
- Name
- Mantener los fondos de custodia dentro del espacio de trabajo
- Type
- DENY
- Description
wallet.purpose == "custody" && !withdrawal.destination_is_internal
- Name
- Omitir la aprobación para una clave de API de pagos
- Type
- ALLOW
- Description
principal.initiator_type == "api_key" && principal.api_key_id in ["<api_key_id>"] && withdrawal.value_usd < 1000
- Name
- Omitir la aprobación para entradas antiguas de la libreta de direcciones
- Type
- ALLOW
- Description
withdrawal.is_whitelisted && withdrawal.address_age_sec >= 86400 && withdrawal.value_usd <= 1000
- Name
- Denegar retiros de alto valor en fin de semana
- Type
- DENY
- Description
(context.day_of_week == "Saturday" || context.day_of_week == "Sunday") && withdrawal.value_usd > 25000
- Name
- Denegar transferencias ERC-20 con gas elevado
- Type
- DENY
- Description
resource.method_selector == "0xa9059cbb" && resource.gas_limit > 100000
- Name
- Denegar permits de tokens ilimitados
- Type
- DENY
- Description
resource.is_permit && resource.permit_amount_is_unlimited
resource.decoded_args es dinámico. Protege los campos dinámicos con
has(...) antes de leerlos, por ejemplo has(resource.decoded_args.to) && resource.decoded_args.to == "0x000000000000000000000000000000000000dead".
Campos de referencia
Los campos marcados con ref en el esquema contienen el ID o código de otra entidad del espacio de trabajo: workspace_user, api_key, wallet, address_book, network o asset_symbol. Los constructores de condiciones deben mostrar un selector para estos campos.
Cuando se guarda una regla, Fystack comprueba que cada ID referenciado pertenezca a tu espacio de trabajo. Si una entidad se elimina o revoca más adelante, la regla conserva el ID y solo puede coincidir con menos casos, nunca con más.
Esquema de acciones
El esquema de acciones define los campos disponibles dentro de una condición. Los campos marcados como deprecated se siguen evaluando en las reglas existentes, pero no deben usarse en reglas nuevas.
Campos comunes
Todas las acciones disparadoras exponen los siguientes campos.
- Name
- principal.user_id
- Type
- string · ref workspace_user
- Description
ID del miembro del espacio de trabajo que inició la acción. Vacío cuando el iniciador es una clave de API.
- Name
- principal.role
- Type
- string
- Description
Rol en el espacio de trabajo. Uno de
owner,admin,signer,proposeroviewer.
- Name
- principal.initiator_type
- Type
- string
- Description
userpara una sesión web, oapi_keypara una clave de API.
- Name
- principal.api_key_id
- Type
- string · ref api_key
- Description
ID de la clave de API que inició la acción. Vacío para sesiones web, así que combínalo con
principal.initiator_type.
- Name
- principal.user_email
- Type
- string · deprecated
- Description
Email del usuario iniciador. Usa
principal.user_iden su lugar, porque un email puede cambiar.
- Name
- wallet.id
- Type
- string · ref wallet
- Description
ID de la billetera de origen. Úsalo para reglas que apuntan a billeteras específicas dentro de una política.
- Name
- wallet.purpose
- Type
- string
- Description
Propósito de la billetera de origen. Uno de
general,custody,payment,user,one_time_use,gas_tankodeployment.
- Name
- wallet.type
- Type
- string
- Description
Tipo de la billetera de origen.
standardompc.
- Name
- context.hour
- Type
- integer
- Description
Hora UTC de la evaluación, de
0a23.
- Name
- context.day_of_week
- Type
- string
- Description
Nombre del día de la semana en UTC, por ejemplo
MondayoSaturday.
Campos de retiro
Disponibles en withdrawal.create y web3.transfer.
- Name
- withdrawal.amount
- Type
- number
- Description
Cantidad solicitada del activo.
- Name
- withdrawal.value_usd
- Type
- number
- Description
Valor solicitado en USD.
- Name
- withdrawal.asset_symbol
- Type
- string · ref asset_symbol
- Description
Símbolo del activo, como
USDT,ETHoBTC.
- Name
- withdrawal.asset_is_native
- Type
- boolean
- Description
Indica si el activo es el activo nativo de la red.
- Name
- withdrawal.asset_is_known
- Type
- boolean
- Description
Indica si el token está en el catálogo de activos de Fystack. Cuando es
false,amount,value_usdyasset_symbolestán vacíos, así que deniega explícitamente los tokens desconocidos si lo necesitas.
- Name
- withdrawal.token_address
- Type
- string
- Description
Dirección del contrato del token. Vacía para monedas nativas.
- Name
- withdrawal.destination_address
- Type
- string
- Description
Dirección del destinatario.
- Name
- withdrawal.network_code
- Type
- string · ref network
- Description
Internal network code.
- Name
- withdrawal.is_whitelisted
- Type
- boolean
- Description
Indica si la dirección de destino está en alguna entrada de la libreta de direcciones del espacio de trabajo.
- Name
- withdrawal.address_book_id
- Type
- string · ref address_book
- Description
La entrada de la libreta de direcciones que contiene la dirección de destino. Una entrada abarca todas sus direcciones, por lo que funciona como una lista con nombre.
- Name
- withdrawal.address_age_sec
- Type
- number
- Description
Segundos transcurridos desde que la dirección de destino se agregó a su entrada de la libreta de direcciones. Úsalo para reglas de periodo de espera sobre destinatarios agregados recientemente.
- Name
- withdrawal.destination_is_internal
- Type
- boolean
- Description
Indica si el destino es otra billetera del mismo espacio de trabajo.
- Name
- withdrawal.destination_wallet_id
- Type
- string · ref wallet
- Description
La billetera de destino cuando el destino es interno.
Campos de velocidad de retiros
Disponibles solo en withdrawal.create. Todos los valores están en USD salvo que se indique lo contrario.
- Name
- wallet.outflow_1h / outflow_6h / outflow_24h
- Type
- number
- Description
Salida de fondos realizada de la billetera de origen en las últimas 1, 6 o 24 horas.
- Name
- wallet.withdrawal_count_1h
- Type
- integer
- Description
Intentos de retiro desde la billetera de origen en la última hora.
- Name
- wallet.pending_outflow
- Type
- number
- Description
Valor de los retiros de la billetera de origen que aún no se han ejecutado.
- Name
- wallet.projected_outflow_24h
- Type
- number
- Description
Salida realizada en 24 horas, más la salida pendiente, más el retiro que se está evaluando, para la billetera de origen.
- Name
- wallet.asset_projected_outflow_24h
- Type
- number
- Description
La misma proyección para la billetera de origen en unidades del activo retirado, por ejemplo como máximo 5 BTC por día.
- Name
- workspace.outflow_1h / outflow_6h / outflow_24h
- Type
- number
- Description
Salida de fondos realizada del espacio de trabajo en las últimas 1, 6 o 24 horas.
- Name
- workspace.withdrawal_count_1h
- Type
- integer
- Description
Intentos de retiro del espacio de trabajo en la última hora.
- Name
- workspace.pending_outflow
- Type
- number
- Description
Valor de los retiros del espacio de trabajo que aún no se han ejecutado.
- Name
- workspace.projected_outflow_24h
- Type
- number
- Description
Proyección del espacio de trabajo: salida realizada en 24 horas, más la salida pendiente, más el retiro que se está evaluando.
- Name
- workspace.network_outflow_1h / network_outflow_6h / network_outflow_24h
- Type
- number
- Description
Salida realizada del espacio de trabajo en la red actual durante las últimas 1, 6 o 24 horas.
- Name
- workspace.network_withdrawal_count_1h
- Type
- integer
- Description
Intentos de retiro del espacio de trabajo en la red actual en la última hora.
- Name
- workspace.network_pending_outflow
- Type
- number
- Description
Salida pendiente del espacio de trabajo en la red actual.
- Name
- workspace.network_projected_outflow_24h
- Type
- number
- Description
Proyección del espacio de trabajo en la red actual.
- Name
- workspace.initiator_projected_outflow_24h
- Type
- number
- Description
Proyección de los retiros creados por el mismo miembro o clave de API, en todo el espacio de trabajo.
Los campos de salida y de conteo son realizados: cuentan un retiro solo después de que alcanza un estado final ejecutado o exitoso. La salida pendiente cuenta los retiros que están esperando aprobación, en cola o fondeando gas, sin importar su antigüedad.
Cuando una regla activa usa un campo pendiente o proyectado, Fystack evalúa
los retiros del espacio de trabajo de uno en uno, para que dos solicitudes
concurrentes no puedan superar un límite al mismo tiempo. Una solicitud que
espera más de 5 segundos su turno se rechaza con HTTP 429 y puede
reintentarse.
Campos de web3.contract_call
- Name
- resource.network_code
- Type
- string · ref network
- Description
Internal network code.
- Name
- resource.contract_address
- Type
- string
- Description
Dirección del contrato en minúsculas, tomada del campo
tode la transacción sin procesar.
- Name
- resource.method_selector
- Type
- string
- Description
Selector de 4 bytes en minúsculas, por ejemplo
0xa9059cbb.
- Name
- resource.method_name
- Type
- string
- Description
Nombre del método según los metadatos de la solicitud, si se proporciona.
- Name
- resource.value_wei
- Type
- string
- Description
Valor nativo enviado con la llamada, representado como string.
- Name
- resource.gas_limit
- Type
- integer
- Description
Límite de gas de la transacción sin procesar.
- Name
- resource.decoded_args
- Type
- map
- Description
Argumentos decodificados cuando Fystack reconoce la llamada.
transferde ERC-20 exponetoyvalue.
Campos de web3.sign_message
- Name
- resource.method
- Type
- string
- Description
Método de firma. Uno de
personal_sign,eth_signoeth_signTypedData_v4.
- Name
- resource.network_code
- Type
- string · ref network
- Description
Internal network code.
- Name
- resource.typed_data_primary_type
- Type
- string
- Description
Tipo primario EIP-712, para mensajes de datos tipados.
- Name
- resource.typed_data_domain_name
- Type
- string
- Description
Nombre de dominio EIP-712, para mensajes de datos tipados.
- Name
- resource.typed_data_verifying_contract
- Type
- string
- Description
Contrato verificador EIP-712, para mensajes de datos tipados.
- Name
- resource.is_permit
- Type
- boolean
- Description
truepara mensajes EIP-2612, DAI y Permit2, que permiten al spender mover tokens más adelante sin otra firma.
- Name
- resource.permit_spender
- Type
- string
- Description
La dirección que autoriza el permit.
- Name
- resource.permit_tokens
- Type
- string[]
- Description
Contratos de tokens que cubre el permit. Úsalo con
in, por ejemplo"0x…" in resource.permit_tokens.
- Name
- resource.permit_amount_is_unlimited
- Type
- boolean
- Description
truepara allowances de valor máximo (2159 o más, o un permit de DAI conallowedactivado).
- Name
- resource.permit_deadline
- Type
- integer
- Description
Hora Unix en que expira el permit o su firma.
0cuando el mensaje no tiene ninguna.
Ciclo de aprobación
Las operaciones de creación, actualización y eliminación de políticas requieren aprobación. La mutación crea una solicitud de aprobación de tipo policy y devuelve status: "pending_approval" con un approval_request_id. El cambio en la política se aplica solo después de que el grupo de aprobación alcanza el umbral.
Las operaciones de creación, actualización y eliminación de reglas siguen el mismo modelo cuando la política principal tiene un grupo de aprobación. La revisión pendiente almacena las diferencias a nivel de campo para auditoría y revisión.
Actualizar las billeteras objetivo mediante /wallets se aplica de inmediato tras la validación y la invalidación de la caché. Usa el endpoint de actualización de políticas cuando quieras que los cambios en las billeteras objetivo se revisen como parte de una revisión más amplia de la política.
Autenticación
Los endpoints de la API de políticas aceptan una solicitud firmada con clave de API o un token de acceso bearer.
- Name
- ACCESS-API-KEY
- Type
- header
- Description
UUID de la clave de API para solicitudes autenticadas con HMAC.
- Name
- ACCESS-TIMESTAMP
- Type
- header
- Description
Marca de tiempo UNIX en segundos usada para construir la firma HMAC.
- Name
- ACCESS-SIGN
- Type
- header
- Description
Firma HMAC codificada en Base64. Consulta Autenticación para ver el formato de firma.
- Name
- Authorization
- Type
- header
- Description
Token de acceso bearer para solicitudes de sesión de usuario.
Los endpoints de decisión de aprobación de políticas siguen siendo endpoints de sesión de usuario. Usa tokens de acceso bearer para aprobar o rechazar solicitudes de aprobación.
Envoltorio de respuesta
Las respuestas JSON exitosas usan el envoltorio estándar de Fystack.
- Name
- success
- Type
- boolean
- Description
truecuando la solicitud se realiza correctamente.
- Name
- message
- Type
- string
- Description
Mensaje de respuesta, normalmente
success.
- Name
- code
- Type
- integer
- Description
Código numérico del resultado. Las respuestas exitosas usan
0.
- Name
- data
- Type
- object | array | null
- Description
Payload de respuesta específico del endpoint.
Los errores de validación usan el mismo envoltorio con success: false y un array errors.
Tipos de datos
Política
- Name
- id
- Type
- string
- Description
UUID de la política.
- Name
- created_at
- Type
- string
- Description
Marca de tiempo ISO de creación de la política.
- Name
- updated_at
- Type
- string
- Description
Marca de tiempo ISO de la última actualización de la política.
- Name
- name
- Type
- string
- Description
Nombre de la política. De 3 a 100 caracteres.
- Name
- description
- Type
- string
- Description
Descripción opcional. Hasta 500 caracteres.
- Name
- status
- Type
- string
- Description
Uno de
pending,rejected,activeoinactive.
- Name
- version
- Type
- integer
- Description
Número de versión de la política.
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- approval_group_id
- Type
- string | null
- Description
UUID del grupo de aprobación asignado a la política.
- Name
- wallet_ids
- Type
- string[]
- Description
UUIDs de las billeteras objetivo. Un array vacío significa que la política se aplica a todas las billeteras del espacio de trabajo.
- Name
- rules
- Type
- PolicyRule[]
- Description
Presente en los endpoints que precargan las reglas.
- Name
- approval_group
- Type
- object
- Description
Presente en los endpoints que precargan el grupo de aprobación.
- Name
- pending_approval_request
- Type
- object
- Description
Presente cuando hay una solicitud de aprobación pendiente para la política.
PolicyRule
- Name
- id
- Type
- string
- Description
UUID de la regla.
- Name
- policy_id
- Type
- string
- Description
UUID de la política principal.
- Name
- trigger_action
- Type
- string
- Description
Uno de
withdrawal.create,web3.transfer,web3.contract_calloweb3.sign_message.
- Name
- condition
- Type
- string
- Description
Expresión de condición booleana. De 1 a 4000 caracteres.
- Name
- effect
- Type
- string
- Description
ALLOWoDENY.
- Name
- description
- Type
- string
- Description
Descripción opcional. Hasta 500 caracteres.
- Name
- is_enabled
- Type
- boolean
- Description
Indica si la regla está habilitada. Por defecto es
trueal crearla si se omite.
Respuesta de mutación
Los endpoints de mutación de políticas y reglas devuelven un payload de mutación en data.
- Name
- status
- Type
- string
- Description
Uno de
applied,pending_approvalodeleted, según la operación.
- Name
- policy
- Type
- Policy
- Description
Lo devuelven los endpoints de mutación de políticas cuando corresponde.
- Name
- rule
- Type
- PolicyRule
- Description
Lo devuelven los endpoints de mutación de reglas cuando corresponde.
- Name
- approval_request_id
- Type
- string
- Description
Se devuelve cuando la mutación está esperando aprobación.
Obtener el esquema de políticas
Devuelve los campos a los que puede hacer referencia una condición, agrupados
por trigger_action y sección. Usa este endpoint para constructores de
condiciones y vistas previas del lado del cliente.
Cada campo tiene name y type. Claves opcionales:
- Name
- enum
- Type
- string[]
- Description
Los valores permitidos para el campo.
- Name
- ref
- Type
- string
- Description
La entidad a la que hace referencia el campo. Muestra un selector para ella. Consulta Campos de referencia.
- Name
- deprecated
- Type
- boolean
- Description
Se sigue evaluando en las reglas existentes. Ocúltalo en los constructores de reglas nuevas.
Request
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 ..." ]
}
}
}
Validar una regla
Valida el cuerpo de una regla sin crear ni actualizar ninguna regla.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
Parámetros del cuerpo
- Name
- trigger_action
- Type
- string
- Required
- required
- Description
Uno de
withdrawal.create,web3.transfer,web3.contract_calloweb3.sign_message.
- Name
- condition
- Type
- string
- Required
- required
- Description
De 1 a 4000 caracteres. Debe compilar a una expresión booleana.
- Name
- effect
- Type
- string
- Required
- required
- Description
ALLOWoDENY. Las reglasweb3.sign_messagesolo admiten denegación.
Datos de respuesta
- Name
- valid
- Type
- boolean
- Description
truecuando el cuerpo de la regla es válido.
Request
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 }
}
Crear una política
Crea una mutación de política.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
Parámetros del cuerpo
- Name
- name
- Type
- string
- Required
- required
- Description
De 3 a 100 caracteres.
- Name
- description
- Type
- string
- Description
Opcional. Hasta 500 caracteres.
- Name
- approval_group_id
- Type
- string
- Required
- required
- Description
UUID del grupo de aprobación.
- Name
- wallet_ids
- Type
- string[]
- Description
Opcional. Hasta 500 UUIDs de billeteras.
- Name
- rules
- Type
- PolicyRuleCreate[]
- Description
Opcional. Hasta 50 reglas.
Request
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": []
}
}
}
Listar políticas
Devuelve las políticas de un espacio de trabajo.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
Parámetros de consulta
- Name
- status
- Type
- string
- Description
Opcional. Uno de
pending,rejected,activeoinactive.
- Name
- limit
- Type
- integer
- Description
Opcional. Máximo
1000.
- Name
- offset
- Type
- integer
- Description
Opcional. Máximo
100000.
Datos de respuesta
- Name
- data
- Type
- Policy[]
- Description
Array de objetos de política.
Request
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=="
Obtener una política
Devuelve una sola política.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Datos de respuesta
- Name
- data
- Type
- Policy
- Description
Objeto de política, que incluye las reglas, el grupo de aprobación y la solicitud de aprobación pendiente, si existe.
Request
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=="
Actualizar una política
Actualiza los campos de la política.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Parámetros del cuerpo
- Name
- name
- Type
- string
- Description
Opcional. De 3 a 100 caracteres.
- Name
- description
- Type
- string
- Description
Opcional. Hasta 500 caracteres.
- Name
- approval_group_id
- Type
- string
- Description
UUID opcional del grupo de aprobación.
- Name
- wallet_ids
- Type
- string[]
- Description
Opcional. Hasta 500 UUIDs de billeteras. Envía un array vacío para aplicarla a todas las billeteras.
- Name
- rules
- Type
- PolicyRuleCreate[]
- Description
Opcional. Si se incluye, reemplaza el conjunto completo de reglas. Envía un array vacío para eliminar todas las reglas.
Request
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"]
}'
Eliminar una política
Elimina una política o crea una mutación de eliminación que espera aprobación.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Datos de respuesta
- Name
- data
- Type
- Mutation response
- Description
Respuesta de mutación de la política.
Request
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=="
Obtener el historial de una política
Devuelve las revisiones de una política.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Datos de respuesta
- Name
- data
- Type
- PolicyRevision[]
- Description
Array de revisiones de la política, que incluye los
changesa nivel de campo cuando existen.
Request
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=="
Obtener las billeteras de una política
Devuelve la política con sus wallet_ids actuales.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Datos de respuesta
- Name
- data
- Type
- Policy
- Description
Objeto de política.
Request
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=="
Actualizar las billeteras de una política
Reemplaza la lista de billeteras objetivo de una política.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Parámetros del cuerpo
- Name
- wallet_ids
- Type
- string[]
- Description
Opcional. Hasta 500 UUIDs de billeteras. Envía un array vacío para aplicarla a todas las billeteras.
Request
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"] }'
Crear una regla de política
Crea una regla dentro de una política existente.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- policy_id
- Type
- string
- Description
UUID de la política.
Parámetros del cuerpo
- Name
- id
- Type
- string
- Description
UUID opcional de la regla.
- Name
- trigger_action
- Type
- string
- Required
- required
- Description
Uno de
withdrawal.create,web3.transfer,web3.contract_calloweb3.sign_message.
- Name
- condition
- Type
- string
- Required
- required
- Description
De 1 a 4000 caracteres.
- Name
- effect
- Type
- string
- Required
- required
- Description
ALLOWoDENY. Las reglasweb3.sign_messagesolo admiten denegación.
- Name
- description
- Type
- string
- Description
Opcional. Hasta 500 caracteres.
- Name
- is_enabled
- Type
- boolean
- Description
Opcional. Por defecto es
true.
Request
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
}'
Actualizar una regla de política
Actualiza los campos modificables de la regla. La acción disparadora es inmutable, así que elimina y vuelve a crear la regla para cambiarla.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- rule_id
- Type
- string
- Description
UUID de la regla.
Parámetros del cuerpo
- Name
- condition
- Type
- string
- Description
Opcional. De 1 a 4000 caracteres.
- Name
- effect
- Type
- string
- Description
Opcional.
ALLOWoDENY.
- Name
- description
- Type
- string
- Description
Opcional. Hasta 500 caracteres.
- Name
- is_enabled
- Type
- boolean
- Description
Opcional.
Request
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
}'
Eliminar una regla de política
Elimina una regla de política o crea una mutación de eliminación de regla que espera aprobación.
Parámetros de ruta
- Name
- workspace_id
- Type
- string
- Description
UUID del espacio de trabajo.
- Name
- rule_id
- Type
- string
- Description
UUID de la regla.
Datos de respuesta
- Name
- data
- Type
- Mutation response
- Description
Respuesta de mutación de la regla.
Request
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=="
Patrones de diseño
Usa reglas DENY para controles estrictos: listas de sanciones, destinatarios desconocidos, entradas nuevas en la libreta de direcciones, límites de salida proyectada, tokens desconocidos, permits ilimitados o métodos de contrato de alto riesgo.
Usa reglas ALLOW de forma acotada. Un ALLOW coincidente omite la aprobación, así que las condiciones deben ser precisas: bajo valor en USD, iniciador de confianza, billetera objetivo conocida, red conocida y un destinatario conocido con verificación de antigüedad de la dirección, o un contrato y método conocidos.
Combina cada ALLOW con un techo DENY, como wallet.projected_outflow_24h o workspace.initiator_projected_outflow_24h. Como DENY siempre prevalece, el techo también limita la ruta de aprobación automática.
Mantén los conjuntos de políticas pequeños y explícitos. Las políticas amplias a nivel de espacio de trabajo son útiles para controles básicos, mientras que las políticas por billetera son mejores cuando una hot wallet, una billetera de tesorería o una billetera de cliente tiene umbrales de riesgo distintos.
Consulta Plantillas de políticas para ver ejemplos completos.