Use this page for reusable policy patterns and complete v0_CreatePolicy examples. For the concepts, see Policies. For launch design, see Design your policies. For field rules and JavaScript guidance, see Policy reference.
The examples use representative roles, domains, ledgers, thresholds, and UUIDs. Before publication or deployment, validate the payloads against your live environment, especially account, endpoint, ledger, and custom property paths.
| Pattern | Type | Goal | Intent types | Condition | Workflow | When to use |
|---|---|---|---|---|---|---|
| Maker-checker | Approval pattern | Require independent review. | Any sensitive intent type. | Usually author role or target operation. | Maker role first, checker role second. | Routine operations that need a second human review. |
| Quorum | Approval pattern | Require multiple approvals from one role. | Lock, unlock, policy, domain, recovery. | Usually broad or high-risk. | RoleQuorum with quorum greater than 1. | Sensitive actions controlled by one team. |
| Multi-step approval | Approval pattern | Escalate approval in sequence. | Transfers, policy changes, high-risk administration. | Amount, risk, domain, operation type. | Ordered workflow steps. | Later approvers should only act after earlier review. |
| And approval | Approval pattern | Require multiple groups in one step. | Transfers, exceptions, compliance, policy changes. | Any business condition. | And with left and right. | Two teams must both approve. |
| Or approval | Approval pattern | Allow alternative approver groups. | Transfers, operational routing, backup operations. | Any business condition. | Or with left and right. | Human or bot, regional alternatives, backup approvers. |
| Amount threshold | Condition pattern | Change approval by value. | v0_CreateTransactionOrder. | BigInt(...) amount comparison. | Tiered approval. | High-value outgoing transfers. |
| Trusted endpoint | Condition pattern | Treat known destinations differently. | v0_CreateTransactionOrder. | Destination is endpoint and trust score is high enough. | Lower or automated maker workflow. | Trusted address workflows. |
| System-signed service proposal | Automation pattern | Allow a service caller to submit a narrow set of API proposals without a client-side payload signature. | Usually v0_CreateTransactionOrder, v0_CreateTransferOrder, or another explicitly selected type. | Service submitter role or subject. | Null workflow for deliberate auto-approval, or user approval workflow. | API-only automation where the deployment supports system-signed intents. |
| Smart contract endpoint | Condition pattern | Escalate smart contract endpoint creation. | v0_CreateEndpoint. | Endpoint parameters exist. | System operator plus compliance. | Contract addresses require extra review. |
| User management | Operation policy | Govern user lifecycle changes. | v0_CreateUser, v0_UpdateUser, v0_LockUser, v0_UnlockUser. | Requester role or target role assignment. | User admin, security, compliance. | Creating users or changing user role assignments. |
| Policy management | Operation policy | Govern policy lifecycle changes. | v0_CreatePolicy, v0_UpdatePolicy, v0_LockPolicy, v0_UnlockPolicy. | Policy operator author role. | Policy operator plus compliance. | Any change to governance rules. |
| Account management | Operation policy | Govern account lifecycle changes. | v0_CreateAccount, v0_UpdateAccount, v0_LockAccount, v0_UnlockAccount. | System operator author role. | System operator plus compliance. | Account setup and maintenance. |
| Quarantine release | Operation policy | Govern release of quarantined funds. | v0_ReleaseQuarantinedTransfers. | Compliance or system operator role. | Compliance quorum. | AML and screening workflows. |
| Fallback | Operation policy | Catch unmatched legitimate workflows. | Omit intentTypes intentionally. | Maker role or true fallback condition. | Low-rank, high-control workflow. | Exceptions not handled by specific policies. |
Use this policy for user creation, user role-assignment changes, locking, and unlocking.
{
"id": "8925d558-d8d7-47d6-b789-92c49d6d66f6",
"alias": "user-management",
"rank": 300,
"scope": "SelfAndDescendants",
"intentTypes": [
"v0_CreateUser",
"v0_UpdateUser",
"v0_LockUser",
"v0_UnlockUser"
],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
"type": "Expression"
},
"workflow": [
{
"role": "system-operator",
"quorum": 2,
"type": "RoleQuorum"
}
],
"lock": "Unlocked",
"description": "Controls user lifecycle operations.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this policy for account creation, account updates, locking, and unlocking.
{
"id": "a13678a6-5f8c-4f85-8657-27f58933bffc",
"alias": "account-management",
"rank": 320,
"scope": "SelfAndDescendants",
"intentTypes": [
"v0_CreateAccount",
"v0_UpdateAccount",
"v0_LockAccount",
"v0_UnlockAccount"
],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "system-operator",
"quorum": 2,
"type": "RoleQuorum"
},
"right": {
"role": "compliance",
"quorum": 1,
"type": "RoleQuorum"
},
"type": "And"
}
],
"lock": "Unlocked",
"description": "Controls account lifecycle operations.",
"customProperties": {},
"type": "v0_CreatePolicy"
}{
"id": "18b187ad-9d2e-4e84-9ce8-0063bfe8d8da",
"alias": "endpoint-management",
"rank": 300,
"scope": "SelfAndDescendants",
"intentTypes": [
"v0_CreateEndpoint",
"v0_UpdateEndpoint",
"v0_LockEndpoint",
"v0_UnlockEndpoint"
],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
"type": "Expression"
},
"workflow": [
{
"role": "system-operator",
"quorum": 2,
"type": "RoleQuorum"
}
],
"lock": "Unlocked",
"description": "Controls endpoint lifecycle operations.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this higher-rank policy to catch smart contract endpoint creation before the generic endpoint-management policy.
{
"id": "ba4d7753-2756-4080-8d7b-9f6699f70ada",
"alias": "smart-contract-endpoint",
"rank": 450,
"scope": "SelfAndDescendants",
"intentTypes": ["v0_CreateEndpoint"],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('system-operator') && context.request.payload.hasOwnProperty('parameters') && context.request.payload.parameters != null",
"type": "Expression"
},
"workflow": [
{
"role": "system-operator",
"quorum": 2,
"type": "RoleQuorum"
},
{
"role": "compliance",
"quorum": 1,
"type": "RoleQuorum"
}
],
"lock": "Unlocked",
"description": "Escalates smart contract endpoint creation.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this policy to govern creation, update, lock, and unlock operations for other policies.
{
"id": "5b440ba5-d013-11eb-8cd0-dcfb48cfb3cb",
"alias": "policy-governance",
"rank": 700,
"scope": "Self",
"intentTypes": [
"v0_CreatePolicy",
"v0_UpdatePolicy",
"v0_LockPolicy",
"v0_UnlockPolicy"
],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('policy-operator')",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "policy-operator",
"quorum": 2,
"type": "RoleQuorum"
},
"right": {
"role": "compliance",
"quorum": 2,
"type": "RoleQuorum"
},
"type": "And"
}
],
"lock": "Unlocked",
"description": "Controls policy lifecycle operations.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this policy to escalate outgoing transaction orders to an unknown address. The condition checks that the destination field exists before reading it.
{
"id": "074fb6c8-f433-4f76-95f0-e01934486b73",
"alias": "unknown-address-transfer",
"rank": 420,
"scope": "Self",
"intentTypes": ["v0_CreateTransactionOrder"],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('transaction-operator') && context.request.payload.hasOwnProperty('parameters') && context.request.payload.parameters != null && context.request.payload.parameters.hasOwnProperty('destination') && context.request.payload.parameters.destination.type == 'Address'",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "transaction-operator",
"quorum": 2,
"type": "RoleQuorum"
},
"right": {
"role": "compliance",
"quorum": 2,
"type": "RoleQuorum"
},
"type": "And"
}
],
"lock": "Unlocked",
"description": "Escalates outgoing transfers to unknown addresses.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this policy for trusted endpoint destinations. Keep the rank lower than high-risk transfer policies so thresholds and compliance overrides can still win.
{
"id": "db8c31d5-26e6-4c46-8643-1cbe03019a1a",
"alias": "trusted-endpoint-transfer",
"rank": 250,
"scope": "Self",
"intentTypes": ["v0_CreateTransactionOrder"],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "(context.references.users[context.request.author.id].roles.includes('transaction-operator') || context.references.users[context.request.author.id].roles.includes('transaction-operator-bot')) && context.request.payload.hasOwnProperty('parameters') && context.request.payload.parameters != null && context.request.payload.parameters.hasOwnProperty('destination') && context.request.payload.parameters.destination.type == 'Endpoint' && context.references.endpoints[context.request.payload.parameters.destination.endpointId].trustScore >= 75",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "transaction-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"right": {
"role": "transaction-operator-bot",
"quorum": 1,
"type": "RoleQuorum"
},
"type": "Or"
},
{
"left": {
"role": "transaction-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"right": {
"role": "transaction-operator-bot",
"quorum": 1,
"type": "RoleQuorum"
},
"type": "Or"
}
],
"lock": "Unlocked",
"description": "Allows trusted endpoint transfer workflow.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this pattern when a service caller should submit a narrow set of API proposals without managing a user private key. This example allows service callers whose token includes the gas-station-service custody role to submit transaction order proposals. The policy does not match user-signed proposals.
{
"id": "af1d2e33-9a94-4456-bcb3-895bba820d38",
"alias": "gas-station-system-signed",
"rank": 420,
"scope": "SelfAndDescendants",
"intentTypes": ["v0_CreateTransactionOrder"],
"intentOrigin": "SystemSigned",
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.submitter.type === 'Service' && context.submitter.custodyRoles.includes('gas-station-service')",
"type": "Expression"
},
"lock": "Unlocked",
"description": "Allows Gas Station service-submitted transaction orders.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Omit workflow only when automatic execution is intentional. If the policy includes a workflow, user-signed approvers complete the approval steps.
Use this policy to require compliance approval for Ethereum transaction orders above 5 ETH.
{
"id": "0efa137d-5f59-4d3e-b720-06185c48ebbe",
"alias": "large-ethereum-transfer",
"rank": 500,
"scope": "Self",
"intentTypes": ["v0_CreateTransactionOrder"],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('transaction-operator') && context.references.accounts[context.request.payload.accountId].ledgerId == 'ethereum-testnet' && context.request.payload.hasOwnProperty('parameters') && context.request.payload.parameters != null && context.request.payload.parameters.hasOwnProperty('amount') && BigInt(context.request.payload.parameters.amount) >= 5000000000000000000n",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "transaction-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"right": {
"role": "compliance",
"quorum": 2,
"type": "RoleQuorum"
},
"type": "And"
}
],
"lock": "Unlocked",
"description": "Escalates Ethereum transfers above 5 ETH.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this policy to sum Bitcoin outputs and require compliance approval above 5 BTC.
{
"id": "4e9cc80b-e4d7-4be8-9940-a1eb0b2e1484",
"alias": "large-bitcoin-transfer",
"rank": 500,
"scope": "Self",
"intentTypes": ["v0_CreateTransactionOrder"],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('transaction-operator') && context.references.accounts[context.request.payload.accountId].ledgerId == 'bitcoin-testnet' && context.request.payload.hasOwnProperty('parameters') && context.request.payload.parameters != null && context.request.payload.parameters.hasOwnProperty('outputs') && context.request.payload.parameters.outputs.reduce((sum, output) => sum + BigInt(output.amount), 0n) >= 500000000n",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "transaction-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"right": {
"role": "compliance",
"quorum": 2,
"type": "RoleQuorum"
},
"type": "And"
}
],
"lock": "Unlocked",
"description": "Escalates Bitcoin transfers above 5 BTC.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use this policy for incoming funds that must stay quarantined until compliance releases them.
{
"id": "2431fbf2-69c1-4d74-b99a-a7ebf7bf5097",
"alias": "quarantine-release",
"rank": 400,
"scope": "SelfAndDescendants",
"intentTypes": ["v0_ReleaseQuarantinedTransfers"],
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('system-operator')",
"type": "Expression"
},
"workflow": [
{
"left": {
"role": "system-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"right": {
"role": "compliance",
"quorum": 1,
"type": "RoleQuorum"
},
"type": "And"
}
],
"lock": "Unlocked",
"description": "Requires compliance approval for quarantine release.",
"customProperties": {},
"type": "v0_CreatePolicy"
}Use fallback policies with low rank and strong approval. They should catch exceptions, not replace specific policies. This example intentionally omits intentTypes so it can match any intent type after more specific policies fail to match.
{
"id": "ed6a0b68-d18c-4d14-8ad6-0e9e595fa0d6",
"alias": "fallback-governance",
"rank": 10,
"scope": "SelfAndDescendants",
"scriptingEngine": "Javascript_v0",
"condition": {
"expression": "context.references.users[context.request.author.id].roles.includes('system-operator') || context.references.users[context.request.author.id].roles.includes('policy-operator') || context.references.users[context.request.author.id].roles.includes('transaction-operator')",
"type": "Expression"
},
"workflow": [
{
"left": {
"left": {
"role": "system-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"right": {
"role": "policy-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"type": "Or"
},
"right": {
"role": "transaction-operator",
"quorum": 1,
"type": "RoleQuorum"
},
"type": "Or"
},
{
"role": "compliance",
"quorum": 2,
"type": "RoleQuorum"
}
],
"lock": "Unlocked",
"description": "Low-rank fallback for unexpected governed workflows.",
"customProperties": {},
"type": "v0_CreatePolicy"
}