# Policies

Openfort's policy engine defines rules that restrict what a backend wallet can sign. For Hyperliquid trading, you can allow orders while blocking withdrawals, limit agent approvals, or enforce custom signing constraints.

## How Hyperliquid actions map to signing

Every Hyperliquid action is an EIP-712 typed data signature. Openfort policies can inspect these signatures using the `signEvmTypedData` operation and `evmTypedDataField` criteria to match specific fields.

| Hyperliquid action | EIP-712 type | Key field |
|-------------------|-------------|-----------|
| Place order | `Order` | `a` (asset), `b` (buy/sell) |
| Withdraw | `Withdraw` | `destination`, `amount` |
| USD transfer | `UsdTransfer` | `destination`, `amount` |
| Approve agent | `ApproveAgent` | `agentAddress` |
| Update leverage | `UpdateLeverage` | `asset`, `leverage` |

## Deny withdrawals

Prevent a backend wallet from ever signing a withdrawal:

```ts
import Openfort from '@openfort/openfort-node'

const openfort = new Openfort(process.env.OPENFORT_SECRET_KEY!, {
  walletSecret: process.env.OPENFORT_WALLET_SECRET!,
})

await openfort.policies.create({
  scope: 'account',
  accountId: account.id,
  rules: [
    {
      action: 'reject',
      operation: 'signEvmTypedData',
      criteria: [
        {
          type: 'evmTypedDataField',
          operator: 'match',
          fieldPath: 'type',
          value: 'HyperliquidTransaction:Withdraw',
        },
      ],
    },
  ],
})
```

:::tip
This is the most common policy for trading wallets. It ensures that even if your server is compromised, an attacker cannot withdraw funds from Hyperliquid.
:::

## Deny transfers

Block USDC transfers between Hyperliquid accounts:

```ts
await openfort.policies.create({
  scope: 'account',
  accountId: account.id,
  rules: [
    {
      action: 'reject',
      operation: 'signEvmTypedData',
      criteria: [
        {
          type: 'evmTypedDataField',
          operator: 'match',
          fieldPath: 'type',
          value: 'HyperliquidTransaction:UsdTransfer',
        },
      ],
    },
  ],
})
```

## Restrict agent approvals

Only allow agent approval for a specific set of addresses:

```ts
await openfort.policies.create({
  scope: 'account',
  accountId: account.id,
  rules: [
    {
      action: 'reject',
      operation: 'signEvmTypedData',
      criteria: [
        {
          type: 'evmTypedDataField',
          operator: 'match',
          fieldPath: 'type',
          value: 'HyperliquidTransaction:ApproveAgent',
        },
      ],
    },
  ],
})
```

:::info
The policy above blocks all agent approvals by default. To allow specific agents, combine with an `accept` rule that matches the permitted agent addresses before the `reject` rule.
:::

## Combine multiple rules

Policies evaluate rules in order. The first matching rule determines the outcome. Create a comprehensive trading policy:

```ts
await openfort.policies.create({
  scope: 'account',
  accountId: account.id,
  rules: [
    // Block withdrawals
    {
      action: 'reject',
      operation: 'signEvmTypedData',
      criteria: [
        {
          type: 'evmTypedDataField',
          operator: 'match',
          fieldPath: 'type',
          value: 'HyperliquidTransaction:Withdraw',
        },
      ],
    },
    // Block transfers
    {
      action: 'reject',
      operation: 'signEvmTypedData',
      criteria: [
        {
          type: 'evmTypedDataField',
          operator: 'match',
          fieldPath: 'type',
          value: 'HyperliquidTransaction:UsdTransfer',
        },
      ],
    },
    // Accept everything else (orders, leverage updates, etc.)
    {
      action: 'accept',
      operation: 'signEvmTypedData',
    },
  ],
})
```

## Policy use cases

| Scenario | Policy rules |
|----------|-------------|
| **Trading bot** | Deny withdrawals, deny transfers, allow orders |
| **Managed fund** | Deny withdrawals, deny agent approvals, allow orders |
| **Agent wallet** | Deny all except orders (agent can't withdraw by design, but policy adds defense-in-depth) |
| **Cold master** | Deny orders, allow withdrawals (only used for fund management) |
