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

# Getting Started

> From zero to your first authorized execution in 2 minutes.

# Getting Started

<Note>
  Policy 2.3 can block or redact exact covered MCP tool results and can use an
  operator-hosted scanner or time-bounded observe mode on the maintained,
  inspection-enabled Sigil MCP Proxy path. Response content stays inside the
  operator trust boundary. See [Policy 2.3 response controls](/developer-toolkit/policy-2-3)
  for exact coverage and limitations.
</Note>

Sigil Sign is the reference implementation of the [SOF enforcement specification](/conformance), a deterministic execution firewall for agent-driven EVM actions. It sits between your AI agent and the blockchain, ensuring that high-stakes actions cannot execute without explicit authorization.

**Base URL:** `https://sign.sigilcore.com`

***

## Choose Your Path

Three roles, three starting points:

* **Integrating an agent with SOF?** This page is for you. Use the Sigil API or self-host the reference implementation. The API Quick Start below is the fastest route.
* **Hacking on SOF locally?** Use the [Developer Toolkit](/developer-toolkit/quick-start), with a mock Express.js engine and Python LangChain authorizer, no API key required.
* **Building your own SOF-conforming signer?** (Audit firms, custodians, enterprise security teams.) Read the [Conformance Contract](/conformance). It defines what your implementation must honor to interoperate with the SOF ecosystem.

The remainder of this guide assumes you are integrating an agent and using the reference implementation, hosted or self-hosted.

***

## API Quick Start

The fastest path to your first governed action. The Sigil API handles signing infrastructure, key management, and attestation issuance so you do not have to run anything yourself.

**1. Get your API key.** Register your email at [sigilcore.com/tools/keys](https://sigilcore.com/tools/keys) to receive a Developer tier key. 1,000 governed actions per month, free.

**2. Sign your warranty.md.** Use [Sigil Warrant](https://sigilcore.com/tools/warrant) to define your policy and generate a signed `warranty.md`. The tool produces your Ed25519 keypair in the browser, signs the policy, and gives you your `SIGIL_OPERATOR_PUBLIC_KEY` value.

**3. Authorize your first action.** Submit an intent to `POST /v1/authorize` with your API key. If the intent passes your policy, you receive an Ed25519-signed JWT. Attach it to your transaction via `Authorization: Bearer <jwt>` and route through the Sigil RPC gateway.

That is the complete flow. The sections below cover each step in detail.

**Pricing tiers:**

| Tier       | Cost       | Governed actions                                                                                         |
| ---------- | ---------- | -------------------------------------------------------------------------------------------------------- |
| Developer  | Free       | 1,000/month                                                                                              |
| Growth     | \$49/month | 10,000/month, \$0.002 per action above                                                                   |
| Enterprise | Custom     | Dedicated infrastructure, custom SLAs, audit support via [Sigil Governance](https://sigilgovernance.com) |

> Need to run your own signing infrastructure? `sigil-sign` is MIT-licensed and self-hostable. See the [Self-hosted deployment](#self-hosted-deployment) section below. For most teams, managing your own cryptographic signing layer is unnecessary overhead.

***

## Before You Deploy: Two Prerequisites

Whether you use the hosted Sigil API or self-host sigil-sign, two things must be in place. Without both, the service refuses to authorize anything. This is intentional: the service will not run without a verified operator policy.

### 1. A signed warranty.md file

Your warranty.md defines what your agent is allowed to do. The file must be signed with your Ed25519 operator key. An unsigned policy file is rejected at startup.

**Use [Sigil Warrant](https://sigilcore.com/tools/warrant)** to generate, sign, and download your `warranty.md`. Two paths are available:

* **Warrant Builder:** guided step-by-step flow for common policies, including repository and Git controls plus the 28 supported database operations. No policy syntax required. Recommended for first-time operators.
* **Manual Warrant:** choose the structured Form for common policies or Advanced Mode to author any field that the current Sign policy contract accepts. Advanced Mode preserves the exact source bytes through validation, signing, download, re-import, and deployment. See the [current generated authoring-capability matrix](/developer-toolkit/policy-2-3#authoring-capability-matrix) before choosing a surface.

When you create a policy, either path can generate an Ed25519 keypair in the browser and provide the `SIGIL_OPERATOR_PUBLIC_KEY` value ready to paste. An unchanged signed import verifies with its operator public key and can download or deploy without generating a new keypair or re-signing.

Deploy the signed warranty.md to your server and set `WARRANTY_PATH` to its location. If you omit this path, the service looks for `config/warranty.md` relative to `process.cwd()`.

### 2. SIGIL\_OPERATOR\_PUBLIC\_KEY environment variable

Set this to the base64url-encoded public key value Sigil Warrant gives you in Step 1. Sigil Lex verifies your policy signature against this key at startup.

```bash theme={null}
SIGIL_OPERATOR_PUBLIC_KEY=<base64url-encoded-public-key>
```

This variable must be present in `.env.local` (development) or your production environment. If it is missing, the service throws with:

```
[Sigil] SIGIL_OPERATOR_PUBLIC_KEY is not set.
```

**Together, these two items form the cryptographic chain:**
`operator signature → policy content → Intent Attestation JWT`

Every attestation your service issues is verifiably linked to the exact policy version you signed and deployed. If anyone modifies the warranty.md after signing, Sigil Lex detects it on the next restart and refuses to start.

> **Sigil Warrant** is the tool that satisfies both requirements. It lives at
> [sigilcore.com/tools/warrant](https://sigilcore.com/tools/warrant).
> Use the guided Builder or Manual flow to generate your keypair, define your policy, and download the
> signed file. The whole flow takes under two minutes.

***

## The Execution Flow

Once your policy is deployed, executing an agent-driven transaction is a strict two-step process:

1. **Request Authorization:** Submit your intent to the firewall to receive a short-lived Intent Attestation.
2. **Execute:** Submit the transaction to the Sigil RPC/Bundler gateway, attaching the attestation as your authorization bearer token.

***

### Step 1: Request an Intent Attestation

Before your agent can route a write transaction, it must obtain an **Intent Attestation**.

**Endpoint:** `POST /v1/authorize`

```bash theme={null}
curl -X POST https://sign.sigilcore.com/v1/authorize \
 -H "Content-Type: application/json" \
 -d '{
   "framework": "agent-hooks",
   "txCommit": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
   "agentId": "agent_alpha_01",
   "chainId": 8453,
   "intent": {
     "action": "wallet.transfer",
     "targetAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
     "token": "USDC",
     "amount": "1000.00"
   }
 }'
```

**Crucial Formatting Rules:**

* `framework`: A string identifying your agent framework (e.g. `"agent-hooks"`, `"eliza"`, `"langchain"`, `"ironclaw"`). Any non-empty string is accepted. See the [Framework Registry](framework-registry) for known values.
* `txCommit`: Must be a lowercase 64-character hex SHA-256 string. **Do not include a `0x` prefix.**
* `chainId`: Must be in your warranty.md `allowed_chains` list. Supported values: 1, 10, 56, 137, 999, 8453, 42161.
* `intent.action`: Must be in your warranty.md `allowed_actions` list (or the per-chain override for the requested chain).
* `intent.token` (optional): ERC-20 token symbol (`"USDC"`) or `0x` contract address. When present, the policy's `token.<SYM>.*` rules govern the amount; without a matching rule the intent is `DENIED`. If the matched rule pins addresses, `targetAddress` must match one of them. Omit for native ETH.
* `intent.to` (optional): recipient email address or array of addresses for `email.send` intents. Required when the policy declares `email.allowed_recipients` or `email.blocked_recipients`.

If your intent passes your warranty.md policy, you will receive an Ed25519-signed JWT in the `intent_attestation` field, with a parallel ML-DSA-65 post-quantum signature embedded in its `pqc` claim. The JWT embeds a `policyHash`, a SHA-256 of the exact policy content that was evaluated, excluding the signature block. This is your cryptographic proof that the correct policy version was in effect.

***

### Step 2: Route the Transaction

Once you hold a valid Intent Attestation, you have exactly **60 seconds** to execute the transaction.

Read operations are public. **Write operations require your Intent Attestation.**

**Endpoints:**

* Standard EVM: `POST /rpc/:chainId`
* Account Abstraction: `POST /bundler/:chainId`

Provide your attestation in the headers using either `Authorization: Bearer <jwt>` or `Sigil-Receipt: <jwt>`.

```bash theme={null}
curl -X POST https://sign.sigilcore.com/rpc/8453 \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..." \
 -d '{
   "jsonrpc": "2.0",
   "method": "eth_sendRawTransaction",
   "params": ["0x..."],
   "id": 1
 }'
```

***

### Verifying Attestations Locally

You do not need to trust the firewall blindly. You can verify Intent Attestations locally using Sigil's published JWK set.

**Endpoint:** `GET /.well-known/jwks.json`

Verification rules are strictly defined in our canonical specification: [sigil-attestations](https://github.com/Sigil-Core/sigil-attestations).

***

## Defining Your Policy

Your warranty.md uses typed section blocks. Sigil Lex evaluates them at runtime to govern agent behavior.

**Use [Sigil Warrant](https://sigilcore.com/tools/warrant)** to generate a signed policy interactively. The tool produces a signed `warranty.md` with an embedded Ed25519 operator signature, the cryptographic proof that the policy evaluated at runtime is the one you authorized.

Pre-built templates for common deployment contexts are available in the [FAF policy-templates directory](https://github.com/Sigil-Core/faf/tree/main/policy-templates).

### Policy Format Reference

Sigil Lex parses a strict structured Markdown format. A 1.x policy requires an enforceable EVM, tool-call, custom, or model-budget rule. A 2.0 or profileless 2.1 policy may also consist of enforced `## soft_limits`. A 2.1 resource profile adds a trusted execution-shim boundary only when the policy declares one of the resource-profile blocks. Unknown fields are rejected at parse time. The `## signature` block at the end is generated by Sigil Warrant; do not edit it manually.

```markdown theme={null}
version: 2.1.0

## evm
max_transaction_eth: 5.0
allowed_actions: wallet.transfer, contract.call
allowed_chains: 1, 8453, 42161
chain_actions:
  "1": wallet.transfer, contract.call
  "8453": wallet.transfer
consensus_threshold_eth: 3.0
consensus_require_hold: true
token.USDC.max_transaction: 10000
token.USDC.decimals: 6   # required; USDC/USDT are 6, most ERC-20s are 18
token.USDC.addresses: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

## tool_calls
allowed: bash, web_fetch, file_write, wallet_sign, email.send
bash.blocked_commands: rm -rf, curl, wget
web_fetch.blocked_domains: evil.com, malicious.io
file_write.blocked_paths: /etc, /root, ~/.ssh
email.require_approval: true
email.allowed_recipients: *@yourcompany.com, partner@example.com
email.blocked_recipients: noreply@yourcompany.com

## custom
allow_only.intent.metadata.job_type: research, data_labeling
deny_if.metadata.phone starts_with +1900
deny_string: DROP TABLE

## soft_limits
daily_evm_limit_eth: 20.0
daily_tool_calls: 500

## execution_limits
max_tool_calls_per_task: 50
max_tool_calls_per_hour: 1000
max_model_spend_usd_per_task: "5.00"
max_model_tokens_per_task: 50000

## signature
sigil-sig: <base64url-ed25519-signature>
```

Policy formats 2.0 through 2.2 are opt-in. A typed HTTP policy must declare a
supported 2.x version; adding HTTP keys to a 1.x policy is a parse error. The
current example uses profileless Policy 2.1, which preserves the same EVM and
tool-call surface without adding a resource profile or claiming inbound result
inspection.

MCP actions use the same 2.x policy gate and are deny-by-default unless an `## mcp` block declares an allowed server or allowed tool boundary. `blocked_tools` only narrows an existing allow boundary and never grants access by itself, so a block containing only `blocked_tools` remains deny-by-default. Named caps live under `## soft_limits` and consume budget only after the base policy approves the action.

```markdown theme={null}
version: 2.0.0

## tool_calls
allowed: http
http.allowed_methods: GET, POST
http.blocked_methods: DELETE
http.allowed_hosts: api.example.com, *.uploads.example.com

## custom
allow_only[action=http].intent.path starts_with: /v1/posts, /v1/uploads/

## mcp
allowed_servers: buffer
allowed_tools: buffer.*
blocked_tools: buffer.delete_*
require_approval: buffer.create_post
require_shim: true

## soft_limits
cap.linkedin_posts.max_count: 2
cap.linkedin_posts.window: day
cap.linkedin_posts.action: mcp.buffer.create_post
cap.linkedin_posts.group_by: metadata.arguments.channelId

## execution_limits
max_tool_calls_per_task: 50

## signature
sigil-sig: <base64url-ed25519-signature>
```

| Section               | Behavior                                                                                                                                                                                                                                                                                                    |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `## evm`              | EVM transaction limits and consensus gates. Violations return `DENIED`. Consensus-gated intents return `PENDING`. Per-token rules (`token.<SYM>.*`) cap ERC-20 spends; an intent carrying a `token` with no matching rule is `DENIED` fail-closed, and ETH-denominated limits never apply to token amounts. |
| `## tool_calls`       | Agent tool call allowlist and blocklists. Blocked calls return `DENIED`. For `email.send`, recipient checks run denylist first, then allowlist, then the `require_approval` hold (`PENDING`). Missing recipients with recipient rules present are `DENIED` fail-closed.                                     |
| `## custom`           | Operator-defined deny rules and affirmative allowlists. In 2.0, `allow_only` supports `equals`, `starts_with`, `ends_with`, `contains`, and bounded `matches`; missing or unlisted values are `DENIED` fail-closed, and deny rules take precedence.                                                         |
| `## soft_limits`      | Informational under 1.x. Enforced count and USD-sum caps under 2.0; exceeded caps return `DENIED`. Day and hour buckets use UTC.                                                                                                                                                                            |
| Typed `http`          | 2.0 HTTP intents carry an explicit method and URL; Sign derives host/path/query server-side. Legacy `web_fetch` remains supported but has no known method and cannot satisfy a non-empty HTTP method allowlist.                                                                                             |
| `## execution_limits` | Hard runaway-loop ceilings for tool calls and model budget brakes. Tool-call overages return `DENIED` with `SIGIL_LOOP_LIMIT_EXCEEDED`. Model budget overages return `SIGIL_MODEL_SPEND_LIMIT_EXCEEDED` or `SIGIL_MODEL_TOKEN_LIMIT_EXCEEDED`. Available on the Developer tier.                             |

Model budget brakes require a compatible adapter to report cumulative provider usage for the current `intent.task_id` in `intent.metadata.model_usage`. Sigil does not proxy LLM inference, bill model calls, or maintain a provider price table. Dollar caps depend on adapter-reported `estimated_spend_usd`; token caps depend on provider-reported token usage.

> **Compatibility:** `token.<SYM>.*`, `email.allowed_recipients` / `email.blocked_recipients`, `allow_only`, and tool-call `execution_limits` ship with sigil-sign builds from June 2026 onward. Model budget fields require v2-compatible sigil-sign and adapter builds. Older strict runtimes can reject these fields at parse time; upgrade before publishing policies that rely on them. Policies that do not use the new fields keep their existing `policyHash` unchanged.

### Updating Your Policy

If you update your warranty.md, you must re-sign it with Sigil Warrant before redeploying. An updated but unsigned policy will be rejected at startup. Keep `version: 2.0.0` unchanged for typed HTTP policies because `version` selects the policy format, not an operator-managed revision. The schema has no separate revision field; `policyHash` changes with the signed policy content and distinguishes one deployed revision from another in subsequent attestations.

***

## Self-hosted Deployment

`sigil-sign` is MIT-licensed and can be run on your own infrastructure. This path gives you full control over the execution firewall, policy storage, and signing keys. For most teams, the hosted Sigil API is the faster and lower-maintenance option.

The minimum deployment surface:

```
sigil-sign/
  ├── config/
  │   └── warranty.md   # signed operator policy
  └── .env.local         # SIGIL_OPERATOR_PUBLIC_KEY
```

Set `SIGIL_OPERATOR_PUBLIC_KEY` in `.env.local` and place your signed `warranty.md` at the path `WARRANTY_PATH` points to (defaults to `config/warranty.md`). The prerequisites and execution flow documented above apply identically to self-hosted deployments.

***

## Building a Conforming Signer

If you are an audit firm, custody provider, or enterprise security team building your own SOF-conforming signer rather than running the reference implementation, the integration path is different. Start with the [Conformance Contract](/conformance). It defines exactly what your signer must implement (six MUST clauses) and what it may extend.

The [sigil-attestations specification](https://github.com/Sigil-Core/sigil-attestations) defines the wire format. The Conformance Contract defines the obligations against that format. Together they are the complete contract for any third-party signer.

Until the SOF Conformance Test Suite ships, conformance is asserted by the signer operator and verified through direct integration testing with the reference implementation at `sign.sigilcore.com`. See the [self-assertion protocol](/conformance#self-assertion-interim) for the registry process.
