Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Backend wallet security

Openfort backend wallets use a Trusted Execution Environment (TEE) hosted on GCP Confidential Space for all cryptographic operations. This isolated compute environment provides hardware-enforced security guarantees that protect private keys from unauthorized access, including access from system operators.

Architecture overview

┌─────────────────────────────────────────────────────────────────────┐
│                         API SERVICE                                 │
│  (Request validation, rate limiting, audit logging)                 │
└────────────────────────────────┬────────────────────────────────────┘
                                 │ gRPC + JWT

┌─────────────────────────────────────────────────────────────────────┐
│                    GCP CONFIDENTIAL SPACE (TEE)                     │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │                      Wallet Service                           │  │
│  │                                                               │  │
│  │  • JWT signature verification (ES256)                         │  │
│  │  • Key generation (secp256k1, ed25519)                        │  │
│  │  • Transaction signing                                        │  │
│  │  • Key import/export (RSA E2E encryption)                     │  │
│  │                                                               │  │
│  │  Private keys never leave TEE memory in plaintext             │  │
│  └───────────────────────────────────────────────────────────────┘  │
│                                │                                    │
│                                │ Attestation token                  │
└────────────────────────────────┼────────────────────────────────────┘

            ┌────────────────────┼────────────────────┐
            ▼                    ▼                    ▼
     ┌─────────────┐      ┌─────────────┐      ┌─────────────┐
     │  Cloud KMS  │      │  Database   │      │    STS      │
     │    (KEK)    │      │  (Encrypted │      │ (Identity)  │
     │             │      │   Storage)  │      │             │
     └─────────────┘      └─────────────┘      └─────────────┘

All requests flow through the API service for validation before being routed to the TEE. The TEE is the only place where private key operations happen.

Trusted execution environment (TEE)

What is a TEE?

A Trusted execution environment provides hardware-enforced isolation:

  • Memory encryption: Protects code and data from the host operating system using AMD SEV-SNP memory encryption.
  • No persistent storage: The TEE doesn't have persistent storage, interactive access, or external networking.
  • Remote attestation: Cryptographic proofs verify exactly what code is running inside the enclave.
  • Operator isolation: Even cloud provider administrators can't access TEE memory.

Security properties

PropertyHow TEE provides it
ConfidentialityAMD SEV-SNP encrypts memory; keys are never exposed outside the TEE.
IntegrityAttestation proves the code hasn't been modified.
AuthenticityAttestation tokens prove the TEE identity to KMS.
Operator isolationEven with root access, operators can't read TEE memory.

Trust boundaries

Inside the TEE (Trusted):
  • Application code running wallet operations.
  • Private key generation and signing.
  • JWT verification.
Outside the TEE (Untrusted):
  • API service layer.
  • Database (stores only encrypted data).
  • Network infrastructure.
  • Cloud infrastructure and operators.

Key management

Envelope encryption

Openfort protects private keys with two-layer envelope encryption:

┌─────────────────────────────────────────────────────────────────────┐
│                        KEY HIERARCHY                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                    KEK (Key Encryption Key)                 │    │
│  │                                                             │    │
│  │  Location: Cloud KMS (HSM-backed)                           │    │
│  │  Type: AES-256-GCM                                          │    │
│  │  Access: Attested Confidential Space workloads only         │    │
│  │  Rotation: KMS-managed (automatic)                          │    │
│  │  Export: Never (hardware-protected)                         │    │
│  │                                                             │    │
│  └──────────────────────────┬──────────────────────────────────┘    │
│                             │ encrypts                              │
│                             ▼                                       │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                    DEK (Data Encryption Key)                │    │
│  │                                                             │    │
│  │  Location: Database (encrypted)                             │    │
│  │  Type: AES-256-GCM (32 bytes)                               │    │
│  │  Scope: One per wallet                                      │    │
│  │  Encrypted with: KEK via Cloud KMS                          │    │
│  │  AAD: Wallet address (prevents DEK swapping)                │    │
│  │                                                             │    │
│  └──────────────────────────┬──────────────────────────────────┘    │
│                             │ encrypts                              │
│                             ▼                                       │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                    Wallet Private Key                       │    │
│  │                                                             │    │
│  │  Location: Database (encrypted)                             │    │
│  │  Type: secp256k1 (32 bytes) or ed25519 (64 bytes)           │    │
│  │  Encrypted with: DEK using AES-256-GCM                      │    │
│  │  Plaintext: Only exists in TEE memory during operations     │    │
│  │                                                             │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

How encryption works

Wallet creation:
  1. Generate a key pair inside the TEE (secp256k1 or ed25519) based on the chain type.
  2. Generate a unique DEK (32 random bytes) inside the TEE.
  3. Encrypt the private key with the DEK using AES-256-GCM.
  4. Encrypt the DEK with the KEK via Cloud KMS (with the wallet address as AAD).
  5. Zero sensitive memory inside the TEE.
  6. Store encrypted data in the database.
Transaction signing:
  1. Retrieve encrypted wallet data from the database.
  2. Decrypt the DEK via KMS (requires TEE attestation).
  3. Decrypt the private key with the DEK inside the TEE.
  4. Sign the transaction inside the TEE.
  5. Zero sensitive memory.
  6. Return the signature.

Attack vector analysis

Attack vectorProtection
Stolen databaseDEKs are useless without KMS access and attestation.
Compromised API serverCan't decrypt the DEK (no attestation).
Malicious operatorCan't decrypt the DEK (no TEE access).
KMS compromiseRequires also compromising the database.
DEK swappingAAD binding prevents cross-wallet attacks.

Authentication

Backend wallet operations use JWT-based authentication with ECDSA P-256 (ES256) signatures. This provides strong authentication and doesn't require secrets to be stored in the TEE.

Wallet secrets

Wallet secrets are asymmetric ECDSA private keys conforming to the secp256r1 (P-256) elliptic curve standard. You must sign each request with the private key, and the server verifies it using the stored public key.

Authentication flow

  1. Client: Creates the request body and computes reqHash = SHA256(sorted JSON body).
  2. Client: Builds a JWT with the reqHash, timestamps, and request identifiers.
  3. Client: Signs the JWT with the wallet secret (ES256).
  4. API Service: Validates the secret key and checks for replay attacks.
  5. TEE: Verifies the ES256 signature and validates all claims.
  6. TEE: Executes the operation if authentication succeeds.

JWT claim validation

ClaimValidationPurpose
algMust be "ES256"Only P-256 ECDSA allowed
kidMust exist; lookup in DBIdentifies the public key
urisAt least one; must match requestScopes request to specific endpoints
reqHashSHA256 of sorted JSON bodyRequest integrity
iatNot in the future and not older than two minutesToken freshness
nbfNot in the future (30-second skew allowed)Prevents pre-activated tokens
jtiUnique (checked by API Service)Replay protection

Security properties

PropertyHow achieved
AuthenticationES256 signature verification.
IntegrityreqHash binds the signature to the request body.
Freshnessiat max age (two minutes) and nbf validation.
Replay protectionjti tracking (API Service) and iat freshness (TEE).
Non-repudiationAsymmetric signature (only client has the private key).

Secret rotation and recovery

  • You can delete compromised wallet secrets and generate new ones through the Openfort Dashboard without risking fund loss.
  • Rotation immediately invalidates the old secret.
  • A project can have multiple active secrets for seamless rotation.

Key import and export

Transfer private keys securely using RSA-4096 OAEP SHA-256 end-to-end encryption:

OperationEncryption keyDecryption key
ImportStatic server public key (embedded in SDK)KMS HSM private key (non-extractable)
ExportEphemeral client public key (per-request)Client private key (SDK-local)

Import flow

  1. SDK encrypts the private key with the static RSA public key of the server.
  2. Server decrypts via KMS AsymmetricDecrypt (requires TEE attestation).
  3. Server stores the key using envelope encryption.

Export flow

  1. SDK generates an ephemeral RSA-4096 key pair.
  2. SDK sends the public key with the export request.
  3. Server encrypts the private key with the client public key.
  4. SDK decrypts locally and discards ephemeral keys.

The import key is HSM-backed, so operators can't extract it and only attested workloads can perform decryption operations.

Best practices

  • Store wallet secrets securely using your platform's secret management (for example, environment variables or secret managers).
  • Never expose wallet secrets in client-side code.
  • Rotate secrets periodically and immediately if you suspect a compromise.
Copyright © 2023-present Alamas Labs, Inc