How we secure private keys
Open-source key management. Audited cryptography. No single point of compromise.
Table of contents
Last updated: December 2025
Private keys are split into encrypted shares using Shamir Secret Sharing (2-of-3 threshold). The complete key never persists anywhere—it's reconstructed only in browser-isolated memory during signing, then immediately cleared.
This means no single database breach, no rogue employee, and no compromised server can steal user funds. You can self-host the entire stack via OpenSigner if you want full infrastructure control.
Key Sharding
Wallet entropy is split into three shares distributed across independent security boundaries. Any two shares can reconstruct the key. No single party—including Openfort—can access funds alone.
Share Distribution (2-of-3 Threshold)
Keys use Shamir's algorithm over GF(2^8)—the same math used in RAID storage and cryptographic protocols for decades. The secret is reconstructed via Lagrange interpolation only when needed. Each share alone reveals zero information about the key (information-theoretic security):
| Share Type | Storage & Access |
|---|---|
| Device Share | IndexedDB in cross-origin iframe. Isolated by browser same-origin policy. Survives only on this device/browser. |
| Auth Share | AES-256-GCM encrypted, stored server-side. Released only after valid JWT authentication. Self-hostable via Shield. |
| Recovery Share | Encrypted with user password, passkey, or stored in Shield. Used when device share is lost. |
Execution Environment
All cryptographic operations run in a cross-origin iframe hosted on a separate domain (e.g., signer.openfort.xyz). This leverages browser sandboxing that has protected banking and payments for decades. The parent application cannot access iframe memory or storage:
- • Same-origin policy enforces memory isolation between origins.
- • CSP frame-ancestors restricts which domains can embed the iframe.
- • postMessage origin validation on all cross-frame communication.
- • No network access from iframe—shares retrieved via parent relay.
Authentication
Before any wallet operation, the user must authenticate. This proves identity and authorizes the release of the auth share from Openfort's servers. We support multiple methods to fit your UX:
Supported Methods
- • Email + password (Argon2id hashed)
- • OAuth 2.0: Google, Apple, Twitter, Discord
- • SIWE (Sign In With Ethereum) / SIWS (Solana)
- • WebAuthn passkeys, Farcaster, custom OIDC
Access Tokens
JWT signed with RS256, scoped per application. 1-hour TTL. Stored in HttpOnly cookies (default) or localStorage. Required for all share retrieval and signing operations.
Key Generation
When a user creates their first wallet, all cryptographic operations happen inside the browser iframe. The key is generated, sharded, and distributed before the parent app ever sees anything. Nothing leaves the client unencrypted:
- 1
CSPRNG Entropy
128 bits from crypto.getRandomValues()
- 2
BIP-39 → HD Keys
Mnemonic derivation, secp256k1 keypair generation
- 3
Shamir Split
Entropy split into 3 shares (2-of-3 threshold)
- 4
Distribute
AES-256-GCM encrypt, send to storage boundaries
Zero persistence: The complete key exists only in iframe memory during generation, then is immediately wiped.
Signing Flow
When a user signs a transaction or message, the flow stays entirely client-side. The key is reconstructed in iframe memory for milliseconds, used to sign, then immediately zeroed. Your server never sees the key:
Sequence
- →SDK sends tx payload to iframe via postMessage
- →Iframe validates JWT, fetches auth share from server
- →Lagrange interpolation reconstructs key in memory
- →ECDSA sign (secp256k1) or EdDSA (ed25519)
- →Return signature only—key material zeroed
Latency: Full signing flow completes in ~200ms. No HSM round-trips, no server-side key access.
Wallet Types
Not every use case needs the same custody model. A consumer app might want fully non-custodial wallets, while a backend service needs programmatic access. We offer three configurations:
Embedded Wallet
The default for end-users. Keys are SSS-sharded via the OpenSigner iframe, with the device share stored locally. Openfort cannot sign transactions without the user's device share—making this truly non-custodial.
Global Wallet
Same sharding security, but portable across multiple apps in your ecosystem. The auth share is scoped to the ecosystem rather than a single app, so users can move between your products without creating new wallets. Supports session key delegation for specific apps.
Backend Wallet
For server automation where user interaction isn't possible. Openfort KMS holds the complete key server-side. Ideal for treasury operations, automated minting, gas sponsorship accounts, and other programmatic use cases where you trust your own infrastructure.
Recovery
Users lose phones, clear browsers, and forget passwords. Because we use 2-of-3 threshold sharding, losing the device share doesn't mean losing the wallet. The auth share (from authentication) plus recovery share can reconstruct the key:
Recovery Share Options
- •Shield (automatic): Encrypted recovery share in Openfort's open-source Shield server. Released on re-auth.
- •Password: Recovery share encrypted client-side with user password. Zero-knowledge—Openfort can't decrypt.
- •Passkey: WebAuthn credential encrypts recovery share. Syncs via iCloud/Google.
On-chain Recovery
For smart contract wallets: guardian-based social recovery. M-of-N guardians approve signer rotation via on-chain tx.
New Device Flow
Authenticate → fetch auth share → decrypt recovery share → reconstruct key → generate new device share → store locally.
Attack Vectors
We design against specific attacks, not hypothetical ones. Here's what each attack looks like and how our architecture defends against it:
Rogue App Embeds Iframe
Defense: CSP frame-ancestors allowlist configured per project. Iframe validates parent origin before any operation.
Stolen JWT / Session Hijack
Defense: JWT alone can't sign. Requires device share (different browser = no share). 1h token TTL. HttpOnly cookies prevent XSS extraction.
Malicious Browser Extension
Defense: Cross-origin iframe = memory inaccessible to extensions. CSP blocks inline scripts. Optional MFA adds second factor before signing.
Insider Threat / Server Compromise
Defense: Auth share alone = useless (need device share). Key reconstruction only in client iframe, never server-side. Multi-party deploy approvals. Signed release artifacts.
Infrastructure Controls
IP Allowlisting
Lock API access to specific CIDRs
Rate Limiting
Per-endpoint limits + WAF DDoS mitigation
Audit Logs
Immutable, append-only logs for all API and admin actions
Smart Contract Accounts
Key sharding protects the signing key. But smart contract wallets add another layer—programmable rules enforced on-chain. Even if someone somehow gets the key, on-chain limits, timelocks, and multi-sig can still protect funds:
Standards
We support ERC-4337 (bundler model) and EIP-7702 (native AA). The custody model depends on the signer type—if the signer uses SSS sharding, the smart wallet is non-custodial. If it uses a custodial key, the smart wallet is custodial.
On-chain Security
- • Multi-sig / M-of-N approval for high-value txs
- • Spending limits (daily/tx caps)
- • Timelocks on sensitive operations
- • Session keys with scoped permissions
- • Guardian-based social recovery
Audits
All contracts audited by CertiK and Quantstamp. Reports public.
Audits & Compliance
We don't ask you to trust our claims—we prove them. Our code is open-source, our infrastructure is regularly tested, and third-party auditors verify our security posture:
Third-Party Audits
Our SSS implementation, smart contracts, and paymasters have all been audited by security firms. The cryptographic libraries are open-source on GitHub for community review. We run quarterly penetration tests and maintain an active bug bounty program.
Standards
- • OWASP Top 10 Web3 compliance
- • GDPR-compliant data handling (EU data residency available)
- • AES-256-GCM encryption at rest
- • TLS 1.3 for all traffic in transit
Report a Vulnerability
Found something? Email security@openfort.io. Responsible disclosure rewarded via bug bounty.