> For the complete documentation index, see [llms.txt](https://docs.sigilvault.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sigilvault.xyz/introduction.md).

# Introduction

## What Sigil is

Sigil pairs a **physical signing appliance** the user owns with an **octane co-signer** that runs in Sigil's cloud. Every signing request ultimately needs three signatures stacked together:

1. **SP signature** — your service provider, authenticating the request came from your backend (Ed25519, your private key seed).
2. **Octane signature** — Sigil's cloud, validating policy and routing to the right device (Ed25519, managed by Sigil).
3. **Device signature** — the user's appliance, the only signature that actually authorises the on-chain action (secp256k1 for EVM, Ed25519 for Solana, etc.).

Without all three, the chain doesn't accept the transaction. The device is the cryptographic root of authority; octane and the SP key are gates that determine *whether the device will be asked* in the first place.

## How an SP integration works

1. **Pair**. Once per user, you mint a *pair session* (`POST /sp/pair/sessions`). The user opens Sigil on their phone, approves a list of wallets your SP wants access to, and the appliance returns a durable `pair_id`. You store that `pair_id` against your user row.
2. **Sign**. Whenever you need a signature, you POST a request to `/sp/sign` with the `pair_id`, the chain, and the payload. Octane routes to the device, the user (optionally) confirms, and you get back the three signatures bundled.
3. **Revoke**. Either side can break the pair: the user from the appliance, or you from your SP backend (via `revokePairing` / `astrotrain::pairing::revoke_pairing`). Subsequent signing requests fail with `403`.

## Key terms

* **Appliance** — the physical Sigil device. Holds the on-chain keys.
* **Octane** — Sigil's cloud co-signer. Validates SP requests, routes to the right appliance, applies policy.
* **Service Provider (SP)** — you. Pairs with the user's appliance, then asks for signatures.
* **Pair session** — short-lived (5min default). Used once to establish a `pair_id`.
* **`pair_id`** — durable UUID. Identifies a `(SP, user, appliance)` binding. The thing you actually store.
* **`sp_user_ref`** — opaque string you pass to identify your own user to the appliance. Shows up on the approval card. Use anything stable per user (`user-42`, an email, a UUID).
* **Validation code** — six-digit code minted at session creation. The user types it (or it rides in the URL on single-device flows) so the appliance can later prove to your backend that *this specific appliance* approved *this specific session*.
* **Bindings** — the per-chain wallet entries the user approved. Returned with the `pair_id` after pair completes.

## Onboarding as an SP

Each SP gets:

1. **A user record in ironhide** with role `service_provider`. Created via the metroplex admin console or by SQL insert. This row holds your public profile (name, logo, homepage) plus your operational policy (allowed return origins for single-device flows, supported chains).
2. **An API key** issued against that user row (`api_keys` table). Bearer auth on every octane call.
3. **An Ed25519 keypair**. The 32-byte private seed lives only in your backend — it signs the SP-side envelope on each request. The public key is registered in `signing_keys` so octane and the appliance can verify it.
4. **One or more allowed return origins** (HTTPS only) registered on your user row. Required if you want the single-device handoff loop to land users back on your domain after approval.

Talk to your Sigil contact to get these provisioned. After that, every SDK in this doc tree just needs the API key + (for Rust signers) the private seed.

## Pair flow shapes

Two ways the user can complete a pair:

### Two-device

The user is on their **desktop browser** looking at your SP page; their **phone** has Sunstorm installed. You render a QR code containing the session URL, they scan it with the phone's camera, approve, and desktop-side your `awaitPairResult` long-poll resolves with the `pair_id`.

### Single-device

The user is on their **phone**, with both Sunstorm and your mobile-web SP page on the same device. A QR scan from the same screen would be absurd. Instead, you render a Universal Link (`https://sigilvault.xyz/pair?session=…`) that, when tapped, opens Sunstorm directly. The validation code rides in the URL so the user doesn't transcribe it; after approval Sunstorm fires a `return_url` that bounces back to your page.

The two flows share the same backend protocol — your code differs only in the URL it renders and whether you supply a `return_url`. See [Single-device flow](/single-device.md) for the full mechanics.

## Next

* [Quickstart](/quickstart.md) — the shortest path to a working pair.
* [@sigil/astrotrain](/typescript/astrotrain-ts.md) — TypeScript SDK reference.
* [astrotrain](/rust/astrotrain.md) — Rust SDK reference.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.sigilvault.xyz/introduction.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
