# 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

```text
┌─────────────────────────────────────────────────────────────────────┐
│                         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

| Property | How TEE provides it |
| --- | --- |
| **Confidentiality** | AMD SEV-SNP encrypts memory; keys are never exposed outside the TEE. |
| **Integrity** | Attestation proves the code hasn't been modified. |
| **Authenticity** | Attestation tokens prove the TEE identity to KMS. |
| **Operator isolation** | Even 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:

```text
┌─────────────────────────────────────────────────────────────────────┐
│                        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 vector | Protection |
| --- | --- |
| Stolen database | DEKs are useless without KMS access and attestation. |
| Compromised API server | Can't decrypt the DEK (no attestation). |
| Malicious operator | Can't decrypt the DEK (no TEE access). |
| KMS compromise | Requires also compromising the database. |
| DEK swapping | AAD binding prevents cross-wallet attacks. |

## Key import and export

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

| Operation | Encryption key | Decryption key |
| --- | --- | --- |
| **Import** | Static server public key (embedded in SDK) | KMS HSM private key (non-extractable) |
| **Export** | Ephemeral 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.

:::warning
Your wallet secret is a sensitive value that authorizes transactions from your backend wallets. Treat it with the same security as your private keys. If you believe your secret is compromised, rotate it immediately through the **Openfort Dashboard**.
:::
