A guide to understanding how Trusted Execution Environments (TEEs) enable automated, secure key management across multiple blockchains.
You hold your own keys. Sounds great until:
- You lose them - Seed phrases get lost, hardware fails, people die without passing on access
- You get phished - Social engineering, fake sites, malicious contract approvals
- You have to be present - Every transaction needs your signature. Can't automate. Can't sleep.
- Multi-chain is a nightmare - Different wallets, different formats, different seed phrases for each chain
The numbers don't lie: billions in crypto lost to user error. Most people shouldn't be responsible for their own keys.
Let someone else hold the keys. Simple, but:
- Single point of failure - They get hacked, you lose everything
- Trust required - You're trusting humans with access
- "Not your keys, not your crypto" - They could rug, freeze, or lose your funds
- Regulatory risk - They're subject to legal pressure you can't control
Even if you solve custody, there's a deeper issue: you can't automate what requires your signature.
Want to:
- Rebalance your portfolio weekly?
- Take profit when price hits X?
- Arbitrage across chains?
- Execute complex DeFi strategies?
With self-custody, you have to be at your computer, signing transactions. No automation possible.
With custodians, you're trusting them to execute correctly. They could front-run you, fail to execute, or simply make mistakes.
A Trusted Execution Environment is a hardware-enforced secure enclave inside a CPU. Think of it as a black box that:
- Runs code in isolation - Even the server operator can't peek inside
- Measures its own code - Produces a cryptographic hash of what's running
- Proves itself to the world - The hardware manufacturer signs attestation quotes
The most relevant TEE today is Intel TDX (Trust Domain Extensions).
┌─────────────────────────────────────────────────────────┐
│ Server │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ TEE Enclave (TDX) │ │
│ │ │ │
│ │ Code runs here │ │
│ │ Keys live here │ │
│ │ Operator CANNOT see inside │ │
│ │ │ │
│ │ CPU measures code → RTMR3 (hash) │ │
│ │ Intel signs attestation quote │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Operator can start/stop enclave │
│ Operator CANNOT extract keys or modify code │
│ │
└─────────────────────────────────────────────────────────┘
You're not trusting a company. You're trusting:
- The code - It's open source, auditable, you can verify what it does
- The hardware - Intel/AMD attestation proves the code is actually running in a real enclave
If you trust the code (it's audited) and the hardware confirms that exact code is running, you can trust the output without trusting the operator.
The TEE can hold keys and sign transactions 24/7:
- Deterministic execution - Code does exactly what it says
- No human in the loop - Operator can't interfere with signing
- Always available - Signs while you sleep
- Programmable - Define rules, TEE executes them
It's like having a robot that holds your keys and only does what the audited code tells it to do.
Here's the catch: when a TEE enclave shuts down, everything in memory is gone.
┌─────────────────────────┐
│ TEE (running) │
│ │
│ master_secret: 0xABC... │
│ derived keys in memory │
│ │
└─────────────────────────┘
│
│ restart / crash / hardware swap
▼
┌─────────────────────────┐
│ TEE (fresh boot) │
│ │
│ master_secret: ??? │
│ keys: ??? │
│ │
└─────────────────────────┘
If the master secret is lost, all derived keys are lost. User funds are locked forever.
The TEE needs a way to recover its master secret. There are three approaches:
| Approach | How It Works | Tradeoff |
|---|---|---|
| Sealed storage | Encrypt to disk with hardware-bound key | Breaks if hardware changes |
| MPC derivation | Derive from NEAR MPC Network | Requires MPC availability |
| User backup | User provides master secret | User's responsibility |
NEAR has a Multi-Party Computation network where multiple nodes hold threshold shares of a master secret. No single node knows the complete secret.
This network can:
- Sign transactions (Chain Signatures) - Produce signatures for any chain
- Derive secrets (CKD) - Produce deterministic secrets for any derivation path
When the TEE needs its master secret:
┌─────────────────────┐ ┌─────────────────────┐
│ TEE │ │ MPC Network │
│ │ │ │
│ 1. Generate fresh │ │ │
│ keypair (a, A) │ │ │
│ a = private │ │ │
│ A = public │ │ │
│ │ │ │
│ "Derive secret for path │ │
│ 'alice.near:keystore' │ │
│ Here's my public key A" │ │
│ ───────────────────────────────────────>│ │
│ │ │ │
│ │ │ 2. Each MPC node │
│ │ │ computes partial │
│ │ │ value using its │
│ │ │ secret share │
│ │ │ │
│ │ │ 3. Combine partials │
│ │ │ Encrypt to A │
│ │ │ │
│ │ Enc(A, secret) │ │
│ <───────────────────────────────────────│ │
│ │ │ │
│ 4. Decrypt with a │ │ │
│ → master_secret │ │ │
│ │ │ │
└─────────────────────┘ └─────────────────────┘
- MPC nodes never see the final secret - They only see encrypted partials
- Network transport sees only ciphertext - Encrypted to TEE's public key
- Only the TEE can decrypt - It holds the private key
a - Deterministic - Same derivation path always produces same secret
Day 1: TEE boots
TEE asks MPC: derive("alice.near:keystore")
MPC returns: encrypted(0xABC123...)
TEE decrypts: 0xABC123...
TEE uses 0xABC123... as master secret
TEE derives all keys from master secret
Day 2: TEE restarts (crash, update, hardware change)
TEE asks MPC: derive("alice.near:keystore") ← same request
MPC returns: encrypted(0xABC123...) ← same answer
TEE decrypts: 0xABC123... ← same secret
TEE derives same keys
Funds still accessible.
The MPC network is the persistence layer. The TEE is stateless. Same question, same answer, forever.
TEE MPC Network
│ │
│ CKD("alice.near:keystore") │
│ ──────────────────────────────────>│
│ │
│ encrypted(master_secret) │
│ <──────────────────────────────────│
│ │
│ Decrypt → master_secret │
│ Derive child keys │
│ │
TEE DAO Contract
│ │
│ register_worker_key(pubkey, quote)│
│ ──────────────────────────────────>│
│ │
│ ┌───────────────────────────┤
│ │ Verify Intel attestation │
│ │ Check RTMR3 is approved │
│ │ Store pubkey → RTMR3 map │
│ └───────────────────────────┤
│ │
│ ✓ Registered │
│ <──────────────────────────────────│
│ │
On-chain: One transaction. Happens once per TEE instance.
User Keystore (TEE) chain-keys Contract
│ │ │
│ "ETH addr" │ │
│ ─────────────>│ │
│ │ │
│ ┌──────────┤ │
│ │ Derive │ │
│ │ secp256k1│ │
│ │ keypair │ │
│ └──────────┤ │
│ │ │
│ │ register_tee_key(...) │
│ │ ────────────────────────>│
│ │ │
│ │ ┌─────────────────┤
│ │ │ Verify RTMR3 │
│ │ │ (cross-contract)│
│ │ │ Derive address │
│ │ │ Store binding │
│ │ └─────────────────┤
│ │ │
│ │ ✓ 0x7E5F4552... │
│ │ <────────────────────────│
│ │ │
│ 0x7E5F4552...│ │
│ <─────────────│ │
On-chain: One transaction per (user, chain) pair. Stores the address binding with TEE attestation proof.
User Keystore (TEE) Ethereum
│ │ │
│ "Sign this" │ │
│ ─────────────>│ │
│ │ │
│ ┌──────────┤ │
│ │ Sign TX │ │
│ │ inside │ │
│ │ enclave │ │
│ └──────────┤ │
│ │ │
│ Signed TX │ │
│ <─────────────│ │
│ │ │
│ Broadcast ─────────────────────────>│
│ │ │
On-chain (NEAR): None! Signing happens off-chain in TEE.
On-chain (target): The signed transaction lands on Ethereum/Bitcoin/etc.
TEE (new instance) MPC Network
│ │
│ CKD("alice.near:keystore") │
│ ──────────────────────────────────>│
│ │
│ encrypted(master_secret) │ ← Same as before
│ <──────────────────────────────────│
│ │
│ Decrypt → same master_secret │
│ Derive same child keys │
│ │
│ Ready to sign again │
│ │
On-chain: None. The keys are re-derived, not recovered from storage.
chain-keys is a NEAR contract that stores cross-chain address bindings:
alice.near
├── secp256k1:abc... → 0x7E5F4552... (Ethereum)
│ └── tee_attestation:
│ tee_type: "tdx"
│ rtmr3: "abc123..."
│ verified_at: block 12345678
│
├── secp256k1:def... → bc1p0xlx... (Bitcoin Taproot)
│ └── tee_attestation: ...
│
└── ed25519:ghi... → BGCCDDHf... (Solana)
└── tee_attestation: ...
Automated systems need to know: "What addresses am I operating?"
Automation Logic
│
│ "I need to swap on Uniswap"
│ "What's my Ethereum address?"
│
▼
┌─────────────────┐
│ chain-keys │ ← Query on-chain
│ │
│ alice.near: │
│ ETH: 0x7E5... │
│ BTC: bc1p... │
│ SOL: BGCC... │
└─────────────────┘
│
│ "Use 0x7E5F... for this swap"
│
▼
Keystore signs
| Capability | Without chain-keys | With chain-keys |
|---|---|---|
| Address lookup | Ask keystore | Query on-chain |
| Attestation proof | Trust keystore | Verify on-chain |
| Persistence | Keystore availability | Always available |
| Composability | N/A | Other contracts can query |
chain-keys stores bindings but doesn't add NEAR access keys:
// register_tee_key: Registry only, no NEAR access key
// - Stores the binding with attestation proof
// - Does NOT add key to NEAR account
// - Perfect for cross-chain TEE keysThis is the typical case for TEE keystores where keys sign for Ethereum/Bitcoin but not NEAR.
┌─────────────────┐ ┌─────────────────┐
│ TEE Keystore │ <────── │ NEAR MPC Network│
│ │ CKD │ │
│ Derives keys │ │ Threshold secret│
│ on boot │ │ (persistence) │
└─────────────────┘ └─────────────────┘
- Persistence: MPC network
- Recovery: Automatic on restart
- Trust: MPC network + TEE hardware
┌─────────────────┐ ┌─────────────────┐
│ TEE Keystore │ <────── │ User's backup │
│ │ config │ │
│ Derives keys │ │ MASTER_SECRET │
│ on boot │ │ (user stores) │
└─────────────────┘ └─────────────────┘
- Persistence: User's backup
- Recovery: User provides secret
- Trust: TEE hardware only
┌─────────────────┐
│ Phala Network │
│ │
│ ┌─────────────┐ │
│ │ Worker 1 │ │ Shared: Multiple users per worker
│ └─────────────┘ │ Key derivation isolates them
│ │
│ ┌─────────────┐ │
│ │ Worker 2 │ │ Dedicated: One user per worker
│ └─────────────┘ │ Maximum isolation
│ │
└─────────────────┘
- Persistence: Phala infrastructure + MPC or sealed storage
- Recovery: Depends on configuration
- Trust: Phala + TEE hardware
NEAR offers two paths for cross-chain operations:
| Chain Signatures (MPC) | TEE Signing | |
|---|---|---|
| Who signs | MPC network | TEE enclave |
| Key storage | Threshold shares | TEE memory (derived from MPC) |
| Latency | Higher (coordination) | Lower (single signer) |
| Trust | MPC network | Code + hardware |
| Automation | Via contract calls | Via keystore API |
Use Chain Signatures when:
- You need maximum decentralization
- Signing frequency is low
- You're building contract-to-contract flows
Use TEE Signing when:
- You need high-frequency signing
- You want programmable key management
- You're building automated strategies
Your App
│
├── Query chain-keys: "What's alice's ETH address?"
│ └── On-chain, always available
│
├── Request signing: POST to keystore API
│ └── Off-chain, TEE signs
│
└── Verify attestation: Query chain-keys
└── On-chain, includes RTMR3 proof
| Component | Role |
|---|---|
| TEE | Holds keys, signs transactions, runs audited code |
| MPC Network | Provides deterministic secret derivation (persistence) |
| DAO Contract | Verifies TEE attestation, stores approved code measurements |
| chain-keys | On-chain address book with attestation proof |
The result: Automated multi-chain key management with verifiable security.
- Keys never leave TEE memory
- Persistence via MPC derivation, not storage
- On-chain proof of TEE provenance
- Queryable cross-chain identity
One NEAR account. All chains. Programmable. Verifiable.