Admin Login

Key Management Lifecycle

The Institutional Vault ensures that a complete private key never exists at any point in its lifecycle. The following sections describe the data flow for key generation, encrypted storage, and threshold signing.


Key Generation

Private keys are generated through a distributed key generation (DKG) protocol coordinated by the Wallet Service orchestrator. Each MPA Node independently contributes cryptographically secure randomness, and the MPC protocol produces a key share per node along with a shared public key. The complete private key is never assembled, computed, or transmitted.

%%{init: {'themeVariables': { 'noteBkgColor': '#9370DB', 'noteTextColor': '#ffffff', 'noteBorderColor': '#4B0082' }}}%%
sequenceDiagram
    participant Client as API Client
    participant WS as Wallet Service<br/>(Orchestrator)
    participant NATS as Broker
    participant PN0 as MPA Node 0
    participant PN1 as MPA Node 1
    participant PN2 as MPA Node 2

    Client->>WS: CreateMasterKey request
    WS->>NATS: Distribute DKG session
    NATS->>PN0: DKG round
    NATS->>PN1: DKG round
    NATS->>PN2: DKG round
    Note over PN0,PN2: Each node contributes<br/>local CSPRNG randomness
    PN0-->>PN1: MPC protocol messages
    PN1-->>PN2: MPC protocol messages
    PN2-->>PN0: MPC protocol messages
    Note over PN0,PN2: DKG completes:<br/>each node holds a key share<br/>complete key never exists
    PN0->>PN0: Encrypt share (AES-256-GCM)<br/>and persist to local DB
    PN1->>PN1: Encrypt share (AES-256-GCM)<br/>and persist to local DB
    PN2->>PN2: Encrypt share (AES-256-GCM)<br/>and persist to local DB
    PN0-->>WS: Public key + success
    WS-->>Client: MasterKey created (public key)

Key Storage

Each policy node's key share is encrypted at rest using AES-256-GCM with a per-node Master Encryption Key (MEK) derived via HKDF. Encrypted shares are persisted to that node's isolated PostgreSQL database. Shares are protected at rest (cloud KMS / Key Vault), in transit (TLS and mTLS between nodes), and in use inside a hardware-attested Trusted Execution Environment (TEE) on AWS Nitro Enclaves or Azure Confidential Containers.

For Nitro and Azure Confidential Container isolation, KMS attestation, hardware-bound storage, and how MPC combines with TEE versus physical HSMs, see MPC and TEE Security Architecture.

flowchart TD
    subgraph node0 [MPA Node 0]
        MEK0["MEK 0"]
        HKDF0["HKDF"]
        AES0["AES-256-GCM Encrypt"]
        Share0["Key Share 0<br/>(in-memory only)"]
        Share0 --> AES0
        MEK0 --> HKDF0
        HKDF0 --> AES0
        AES0 --> Enc0["Encrypted Share 0"]
    end

    subgraph node1 [MPA Node 1]
        MEK1["MEK 1"]
        HKDF1["HKDF"]
        AES1["AES-256-GCM Encrypt"]
        Share1["Key Share 1<br/>(in-memory only)"]
        Share1 --> AES1
        MEK1 --> HKDF1
        HKDF1 --> AES1
        AES1 --> Enc1["Encrypted Share 1"]
    end

    subgraph node2 [MPA Node 2]
        MEK2["MEK 2"]
        HKDF2["HKDF"]
        AES2["AES-256-GCM Encrypt"]
        Share2["Key Share 2<br/>(in-memory only)"]
        Share2 --> AES2
        MEK2 --> HKDF2
        HKDF2 --> AES2
        AES2 --> Enc2["Encrypted Share 2"]
    end

    subgraph storage [Isolated Databases]
        DB0["MPA Node 0<br/>PostgreSQL"]
        DB1["MPA Node 1<br/>PostgreSQL"]
        DB2["MPA Node 2<br/>PostgreSQL"]
    end

    Enc0 --> DB0
    Enc1 --> DB1
    Enc2 --> DB2

    subgraph tee [TEE Protection]
        Nitro["AWS Nitro Enclave /<br/>Azure Confidential Containers"]
        KMS["KMS Remote Attestation"]
        Nitro --> KMS
    end

    MEK0 -.->|"Protected by"| Nitro
    MEK1 -.->|"Protected by"| Nitro
    MEK2 -.->|"Protected by"| Nitro

Key Usage (Signing)

When a transaction intent is submitted, it passes through policy evaluation and approval before the Wallet Service initiates a threshold MPC signing ceremony. Each MPA Node decrypts its share in memory, validates the transaction against the approved intent, and participates in the multi-party signing protocol. The partial signatures are combined into a single standard ECDSA or EdDSA signature. The complete private key is never reconstructed during signing.

%%{init: {'themeVariables': { 'noteBkgColor': '#9370DB', 'noteTextColor': '#ffffff', 'noteBorderColor': '#4B0082' }}}%%
sequenceDiagram
    participant WS as Wallet Service<br/>(Orchestrator)
    participant NATS as Broker
    participant PN0 as MPA Node 0
    participant PN1 as MPA Node 1
    participant PN2 as MPA Node 2
    Note over WS: Transaction approval<br/>quorum completed

    WS->>NATS: Initiate signing ceremony
    NATS->>PN0: Sign request
    NATS->>PN1: Sign request
    NATS->>PN2: Sign request

    PN0->>PN0: Decrypt share with MEK<br/>from local DB
    PN1->>PN1: Decrypt share with MEK<br/>from local DB
    PN2->>PN2: Decrypt share with MEK<br/>from local DB

    Note over PN0,PN2: Pre-sign validation:<br/>outputs, fees, spec,<br/>code authorizations<br/>must match intent

    PN0-->>PN1: MPC signing protocol
    PN1-->>PN2: MPC signing protocol
    PN2-->>PN0: MPC signing protocol

    Note over PN0,PN2: Threshold signing completes:<br/>single ECDSA/EdDSA signature<br/>key never reconstructed

    PN0-->>WS: Combined signature