> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Guardrail templates

> Start from a tested Guardrail policy for app-owned wallets: spending caps, allowlists, approval tiers, treasury payouts and message signing.

export const PermissionsCards = ({basePath, pages, cols = 2, horizontal = false}) => {
  const ImageCard = Card;
  const hrefOverrides = {
    "/v3/react/guides/permissions": {
      "conditional-approvals": "/v3/react/guides/conditional-approvals"
    },
    "/v3/rest/permissions": {
      "backend": "/v3/rest/permissions-administration"
    }
  };
  const guardrailBases = ["/v3/rest/permissions", "/v3/server/guides/permissions"];
  const ownership = guardrailBases.includes(basePath) ? 'guardrail' : 'request';
  const overviewImages = {
    "/v3/rest/permissions": {
      "imgUrl": "/images/v3/cards/rest-guardrails.png",
      "horizontalImgUrl": "/images/v3/cards/rest-guardrails-horizontal.png"
    },
    "/v3/server/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-server-guardrail-signing.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-server-guardrail-signing-horizontal.png"
    },
    "/v3/react/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-get-policy-consent-url.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-get-policy-consent-url-horizontal.png"
    },
    "/v3/react-native/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-get-policy-consent-url.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-get-policy-consent-url-horizontal.png"
    }
  };
  const registry = {
    overview: {
      title: "Permissions overview",
      description: "Return to the start of the Permissions path.",
      ...overviewImages[basePath]
    },
    "developer-portal": {
      title: "Create policies in the Developer Portal",
      description: "Build a policy with the Portal forms and activate it on a beta key.",
      imgUrl: "/images/v3/cards/developer-portal-policy-form.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-form-horizontal.png"
    },
    "json": {
      title: "Write policy JSON",
      description: "Move to JSON for policies the forms cannot express.",
      imgUrl: "/images/v3/cards/developer-portal-policy-json.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-json-horizontal.png"
    },
    "testing": {
      title: "Test your policies",
      description: "Exercise every rule on beta before you ship.",
      imgUrl: "/images/v3/cards/concept-policy-testing.png",
      horizontalImgUrl: "/images/v3/cards/concept-policy-testing-horizontal.png"
    },
    "production": {
      title: "Go to production",
      description: "Request a production review and publish your policy.",
      imgUrl: "/images/v3/cards/concept-policy-publication.png",
      horizontalImgUrl: "/images/v3/cards/concept-policy-publication-horizontal.png"
    },
    "conditional-approvals": {
      title: "Conditional approvals",
      description: "Require people to approve a request before it signs.",
      imgUrl: "/images/v3/cards/portal-conditional-approval-case.png",
      horizontalImgUrl: "/images/v3/cards/portal-conditional-approval-case-horizontal.png"
    },
    "approval-signatures": {
      title: "Collect approval signatures",
      description: "Collect signatures from approvers for multisig workflows.",
      imgUrl: "/images/v3/cards/sdk-get-approval-signatures.png",
      horizontalImgUrl: "/images/v3/cards/sdk-get-approval-signatures-horizontal.png"
    },
    "adjustable-parameters": {
      title: "Adjustable parameters",
      description: "Let users set their own limits and managers adjust approval settings.",
      imgUrl: "/images/v3/cards/portal-user-policy-limits.png",
      horizontalImgUrl: "/images/v3/cards/portal-user-policy-limits-horizontal.png"
    },
    "lifecycle": {
      title: "Manage the policy lifecycle",
      description: "Version, activate, replace and retire policies.",
      imgUrl: "/images/v3/cards/developer-portal-policy-versions.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-versions-horizontal.png"
    },
    "backend": {
      title: "Manage permissions from your backend",
      description: "Assign approvers and read policy state with your server secret.",
      imgUrl: "/images/v3/cards/rest-permissions-administration.png",
      horizontalImgUrl: "/images/v3/cards/rest-permissions-administration-horizontal.png"
    },
    templates: ownership === "guardrail" ? {
      title: "Guardrail templates",
      description: "Start from a tested Guardrail policy.",
      imgUrl: "/images/v3/cards/concept-guardrail-templates.png",
      horizontalImgUrl: "/images/v3/cards/concept-guardrail-templates-horizontal.png"
    } : {
      title: "Request templates",
      description: "Start from a tested Request policy.",
      imgUrl: "/images/v3/cards/concept-request-templates.png",
      horizontalImgUrl: "/images/v3/cards/concept-request-templates-horizontal.png"
    },
    "guardrail:templates/spending-caps": {
      title: "Spending caps",
      description: "Cap native and token transfers per transaction or per day.",
      imgUrl: "/images/v3/cards/concept-spending-limits.png",
      horizontalImgUrl: "/images/v3/cards/concept-spending-limits-horizontal.png"
    },
    "guardrail:templates/allowlists": {
      title: "Recipient and contract allowlists",
      description: "Limit transfers and contract calls to addresses you know.",
      imgUrl: "/images/v3/cards/concept-recipient-allowlists.png",
      horizontalImgUrl: "/images/v3/cards/concept-recipient-allowlists-horizontal.png"
    },
    "guardrail:templates/approval-tiers": {
      title: "Approval thresholds and tiers",
      description: "Hold large transfers for approval, or deny the largest.",
      imgUrl: "/images/v3/cards/concept-approval-tiers.png",
      horizontalImgUrl: "/images/v3/cards/concept-approval-tiers-horizontal.png"
    },
    "guardrail:templates/treasury": {
      title: "Treasury approvals",
      description: "Deny unplanned actions and approve wallet or Safe payouts in stages.",
      imgUrl: "/images/v3/cards/concept-treasury-approvals.png",
      horizontalImgUrl: "/images/v3/cards/concept-treasury-approvals-horizontal.png"
    },
    "guardrail:templates/message-signing": {
      title: "Message and raw signing",
      description: "Block or hold raw signatures, and block permits.",
      imgUrl: "/images/v3/cards/concept-signing-actions.png",
      horizontalImgUrl: "/images/v3/cards/concept-signing-actions-horizontal.png"
    },
    "request:templates/allowances": {
      title: "Transfer allowances",
      description: "Let small transfers and a daily budget sign without a prompt.",
      imgUrl: "/images/v3/cards/concept-spending-limits.png",
      horizontalImgUrl: "/images/v3/cards/concept-spending-limits-horizontal.png"
    },
    "request:templates/recipients-and-contracts": {
      title: "Known recipients and app contracts",
      description: "Cover transfers to known addresses and your contract's calls.",
      imgUrl: "/images/v3/cards/concept-recipient-allowlists.png",
      horizontalImgUrl: "/images/v3/cards/concept-recipient-allowlists-horizontal.png"
    },
    "request:templates/cosigner-approval": {
      title: "Co-signer approval",
      description: "Send large transfers to a co-signer for approval.",
      imgUrl: "/images/v3/cards/portal-conditional-approval-case.png",
      horizontalImgUrl: "/images/v3/cards/portal-conditional-approval-case-horizontal.png"
    },
    "request:templates/adjustable-limits": {
      title: "User-adjustable limits",
      description: "Let each user choose their own spending limits.",
      imgUrl: "/images/v3/cards/portal-user-policy-limits.png",
      horizontalImgUrl: "/images/v3/cards/portal-user-policy-limits-horizontal.png"
    },
    "request:templates/message-signing": {
      title: "Message signing",
      description: "Sign messages from users' wallets without a prompt.",
      imgUrl: "/images/v3/cards/concept-signing-actions.png",
      horizontalImgUrl: "/images/v3/cards/concept-signing-actions-horizontal.png"
    }
  };
  const entryFor = slug => registry[slug] || registry[`${ownership}:${slug}`];
  const hrefFor = slug => {
    if (slug === 'overview') return basePath;
    const overrides = hrefOverrides[basePath] || ({});
    return overrides[slug] || `${basePath}/${slug}`;
  };
  return <CardGroup cols={cols}>
      {pages.map(slug => {
    const entry = entryFor(slug);
    return <ImageCard key={slug} title={entry.title} description={entry.description} href={hrefFor(slug)} imgUrl={horizontal ? entry.horizontalImgUrl : entry.imgUrl} horizontal={horizontal} />;
  })}
    </CardGroup>;
};

export const PermissionsScenarioContent = () => <p>Each scenario page has the policy JSON, sample signing requests with their results, and the values to change for your app.</p>;

Guardrail templates are tested policies for the app-owned wallets your backend signs with. Pick a scenario, adjust the addresses and amounts, and publish it on beta through the Developer Portal or the CLI. When it behaves as expected there, request a production review to apply it to production.

A Guardrail restricts signing. Its rules deny a request or hold it for approval, and a request that no rule blocks signs as usual. When several active Guardrails cover the same wallet, all of them apply, and a block in any of them wins.

| Scenario | What the templates do | Developer Portal forms |
| - | - | - |
| Spending caps | Limit native and token transfers per transaction or per day, on EVM, Solana and Stellar | Yes |
| Allowlists | Limit transfers to known recipients and calls to known contracts and functions | Partly |
| Approval tiers | Hold large transfers for approval, or sign, approve or deny by amount | No, use JSON |
| Treasury | Deny everything except planned payouts, check Safe payouts by recipient, amount and asset, and require staged approval for each payout | No, use JSON |
| Message signing | Block or hold raw signatures, and block permit signatures sent through REST | No, use JSON |

Each template lists sample signing requests with one of three results: signs, denied, or needs approval. Your platform's Permissions page shows what your backend receives for each.

Raw signatures sign by default as well, and no transfer rule can read them. The message signing templates show how to block or hold them:

<Note>
  While Permissions is on, raw signatures follow the same defaults as other signing requests: an app-owned wallet signs them, and a user-owned wallet sends them to the user for review. Rules that name the `raw_signature` action, and rules with `"actions": "all"`, can change that. Raw signatures are `sign-raw` requests, messages from Solana, Stellar and Sui wallets, and REST `sign-message` requests from a Cosmos wallet that do not pass `walletType: "EVM"`. The SDKs sign messages from Cosmos wallets as EVM `sign_message` requests. Raw signatures carry no network a selector can name, so only a policy without `chainId` governs them. A rule that names `raw_signature` can read only `para.wallet.*` facts. The Developer Portal forms cannot create one, so write it in policy JSON, with **Edit JSON** in the Developer Portal or with the [CLI](/v3/cli/permissions).
</Note>

## Choose a scenario

<PermissionsScenarioContent />

<PermissionsCards basePath="/v3/rest/permissions" pages={["templates/spending-caps", "templates/allowlists", "templates/approval-tiers", "templates/treasury", "templates/message-signing"]} cols={3} />

## Use a template

Every template comes with a JSON policy. Templates the Developer Portal forms can express also list the form steps. Publish each one on your Development key, which runs on beta, and test it there first.

<Tabs>
  <Tab title="Developer Portal forms">
    Follow the template's **Developer Portal** tab. A policy saved from the forms gets generated policy and rule IDs, and its JSON can differ in small ways that the template points out. Compare it with the **Normalized policy JSON** on the **Review** step before you select **Save Draft**.
  </Tab>

  <Tab title="Developer Portal JSON editor">
    1. On your **Development** key, open **Permissions**, select the **Guardrails** or **Requests** tab, and select **Add**. Once the tab lists policies, the button is **New Guardrail** or **New Request**.
    2. Enter a name, select the networks the template's `selector` names, and select **Continue**.
    3. Select the **JSON** tab, then **Edit JSON**.
    4. Replace everything in **Policy JSON** with the template and select **Review**. Para validates the policy before anything is saved, and the template's `metadata.description` replaces the name you entered.
    5. Select **Save Draft**, then **Activate** on the draft.
  </Tab>

  <Tab title="CLI">
    Save the template to a file, then validate it, create a draft and activate it on your beta key:

    ```bash theme={null}
    para keys permissions validate KEY_ID --file policy.json --environment beta
    para keys permissions create KEY_ID --file policy.json --environment beta
    para keys permissions activate RECORD_ID KEY_ID --environment beta
    ```

    `create` prints the draft's record ID and the exact `activate` command to run.
  </Tab>
</Tabs>

<Note>
  If your key already has a policy of the same type on the same networks, the Developer Portal opens that policy for editing, and the page title changes to **Edit Guardrail Policy** or **Edit Request Policy**. The editor holds that policy's JSON with the next `version` filled in. Merge the template's rules into it and keep its `id`, selector and `version`, because pasting the template over it fails with `policy_record_identity_conflict`, `policy_record_selector_conflict` or `policy_record_version_conflict`. The button there is **Save changes**, and an active policy enforces the merged rules as soon as you save.
</Note>

## Conventions

The templates share a few conventions. Keep them when you adapt a template, or validation fails.

### Amounts

Amounts are strings of whole base units, such as `"1000000"`. A JSON number fails validation with `value_type_mismatch`.

| Asset | Decimals | 1 unit in base units |
| - | - | - |
| ETH (wei) | 18 | `1000000000000000000` |
| USDC on EVM networks | 6 | `1000000` |
| SOL (lamports) | 9 | `1000000000` |
| XLM (stroops) and Stellar assets such as USDC | 7 | `10000000` |

### Addresses

Para lowercases EVM addresses before it compares them, so checksummed and lowercase addresses match. The templates use lowercase, as the Developer Portal does. Other wallet types need each network's canonical form: a Solana base58 key as is, a Stellar `G…` account in upper case, and a Sui `0x` address with 64 lowercase hex characters.

### Networks

`chainId` in the selector picks the networks a policy covers. Omit it to cover every network of the wallet type. A personal message and a raw signature carry no network, and the Para SDKs sign typed data and authorizations as messages, so the message signing templates leave `chainId` out. The treasury templates leave it out as well and check the network through each asset value, such as `eip155:8453:native`. The other templates use mainnets. To test with testnet funds, swap in the testnet everywhere the template names the network, including asset values and token addresses.

| Wallet type | Templates use | Testnet | Accepted forms |
| - | - | - | - |
| EVM | `8453` (Base) | `84532` (Base Sepolia), where USDC is `0x036cbd53842c5426634e7929541ec2318f3dcf7e` | Numeric chain ID or `eip155:<id>` |
| SOLANA | `solana:mainnet` | `solana:devnet` | `solana:mainnet`, `solana:devnet`, `solana:testnet` |
| STELLAR | `stellar:mainnet` | `stellar:testnet` | `stellar:mainnet`, `stellar:testnet` or the network passphrase, which the Developer Portal writes |

### IDs, versions and windows

Give each policy an `id` your key does not use yet. IDs that start with `para-` are reserved.

* Raise `version` when you publish a change to a policy.
* `window: "24h"` is a fixed daily window that resets at 00:00 UTC, not 24 hours after the first transfer. The Developer Portal writes windows in hours, and `1d` is the same window. A policy can use one window length per spend fact.

<Info>
  Production keys are read-only in the Developer Portal. Once a template behaves as expected on beta, request a production review from your Production key, and Para applies your active beta policies to production.
</Info>

<PermissionsCards basePath="/v3/rest/permissions" pages={["json", "testing", "production"]} cols={3} />


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.