Skip to content

How Sigil works

Sigil splits one private key into three Shamir shares. Any two of them rebuild the key; one alone is useless. The shares live in three different trust domains:

ShareWhere it livesWho controls it
Devicethe user’s browser (localStorage, namespaced by wallet)end user
ProviderSigil backend, envelope-encrypted with Cloud KMSSigil
Recoveryyour backend (default) or Sigil with a separate KEKyou (or Sigil)

The reconstruction (Device + Provider) only happens inside the wallet iframe, in browser memory, for the milliseconds it takes to sign one message. Then the buffer is wiped.

The pieces

┌────────────────────────────────────────────────────────────────────┐
│ Your app │
│ │
│ <SigilProvider/> │
│ │ │
│ ▼ postMessage │
│ ┌──────────────────────┐ HTTPS ┌──────────────────────┐ │
│ │ wallet iframe │────────────▶│ Sigil API │ │
│ │ wallet.sigilkeys.com │ │ api.sigilkeys.com │ │
│ │ │ │ │ │
│ │ • generates key │ │ • lazy user records │ │
│ │ • SSS split │ │ • provider share │ │
│ │ • signs in memory │ │ under Cloud KMS │ │
│ └──────────────────────┘ └──────────┬───────────┘ │
│ │ │
│ ┌─────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ Your backend │ (recovery share custody) │
│ │ POST /sigil/recovery │ │
│ └────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘

What touches what

  • Your bundle ships only the SDK + a publishable key. No secrets.
  • The iframe loads from wallet.sigilkeys.com, so the browser enforces origin isolation. The iframe code is the only place the reconstructed private key ever exists.
  • Sigil API stores only the encrypted provider share and the metadata needed to authenticate the end user (or proxy your OIDC).
  • Cloud KMS holds the KEK that wraps the DEK that wraps the share. AAD binds it to (organization_id, wallet_id) so a leaked ciphertext can’t be replayed for another wallet.
  • Your backend (in the default recovery model) receives a webhook with the recovery share at wallet creation and serves it back during recovery. See Recovery for details.

Why an iframe

Browsers enforce a real, hardware-backed isolation between origins. Embedding Sigil as a same-origin SDK would mean any XSS in your app could read the reconstructed key. By living on a separate origin (wallet.sigilkeys.com), the iframe is unreachable from your DOM — your code can only talk to it via postMessage, and Sigil verifies every message against the per-org allowlist of origins.

The iframe ships a strict Content-Security-Policy, no third-party scripts, no analytics, no inline JS. Reproducible builds.