Skip to content

product-sdk-terminal: expose entropy / encryption-secret derivation (RFC-0007) from a UserSession #254

Description

@ReinhardHatko

Summary

@parity/product-sdk-host exposes a first-class deriveEntropy(context) helper (RFC-0007), so in-container (web) apps can derive deterministic, wallet-bound entropy — and from it an encryption identity — without touching truApi directly.

@parity/product-sdk-terminal has no equivalent, even though the QR/SSO UserSession already carries the needed material and @novasamatech/host-papp already implements the crypto. Terminal (CLI/headless) consumers therefore have to reach around the SDK into the low-level transport package and re-derive RFC-0007 themselves.

Please surface a supported entropy / encryption-secret derivation API on product-sdk-terminal, at parity with product-sdk-host.deriveEntropy.

Environment

  • @parity/product-sdk-terminal 0.5.4
  • @parity/product-sdk-host 0.12.0 (has deriveEntropy)
  • @novasamatech/host-papp 0.8.10 (has the crypto + the session field)

What already exists (so this is a re-export/wrapper, not new crypto)

Web side — clean wrapper (the parity target):

// @parity/product-sdk-host
declare function deriveEntropy(key: Uint8Array): Promise<Result<Uint8Array, HostError>>;
// "Derive deterministic entropy from a context key (RFC-0007). The host derives
//  entropy from the user's wallet + the provided context key. Same key + same
//  wallet → same bytes; different keys/wallets → uncorrelated entropy."

Terminal side — material is present but unexposed:

  • The UserSession (re-exported by product-sdk-terminal) already carries rootEntropySource: Uint8Array — per host-papp's handshakeV2, blake2b256_keyed(rootAccountSecret, "product-entropy-derivation"), i.e. RFC-0007 layer-1.
  • @novasamatech/host-papp's crypto module already implements the encryption primitives:
    createEncrSecret(entropy: Uint8Array): EncrSecret
    getEncrPub(secret: EncrSecret): EncrPublicKey
    createSharedSecret(secret: EncrSecret, publicKey: Uint8Array): SharedSecret   // ECDH

So everything needed is present — it's just not reachable through the terminal package's public surface (., ./host, ./testing expose adapter/allowance/signing only, no entropy).

The problem

To derive an app-scoped encryption identity from a terminal session today, a consumer must:

  1. import @novasamatech/host-papp directly (an internal/transport dep, not the public SDK), and
  2. read session.rootEntropySource and re-implement the RFC-0007 context derivation (host_derive_entropy) that product-sdk-host performs for web,
  3. then call createEncrSecret / getEncrPub / createSharedSecret.

That couples consumers to internal package layout and to a security-sensitive derivation detail that should live in one place.

Proposed API

Mirror product-sdk-host.deriveEntropy, taking the session explicitly (terminal is out-of-container, so there's no ambient host):

// @parity/product-sdk-terminal (or a ./crypto subpath)
export function deriveEntropy(session: UserSession, context: Uint8Array): Result<Uint8Array, TerminalError>;

// and/or a higher-level encryption-identity helper:
export function getEncrSecret(session: UserSession, context: Uint8Array): EncrSecret;
export function getEncrPublicKey(session: UserSession, context: Uint8Array): EncrPublicKey;
export function createSharedSecret(session: UserSession, context: Uint8Array, peerPublicKey: Uint8Array): SharedSecret;

Same determinism guarantee as the host version (same wallet + same context ⇒ same key), so keys survive device loss as long as the wallet is recoverable.

Why

  • Feature parity between in-container (host) and QR/SSO (terminal) apps for entropy-derived encryption.
  • E2E encryption under host-only auth. Our use case (d3pot — decentralized git host on Polkadot) does per-user, wallet-recoverable repo encryption: derive an encryption identity from RFC-0007 entropy, register its public key on-chain, wrap a per-repo symmetric key to collaborators via ECDH. This works on web via deriveEntropy today; the CLI is blocked purely on the missing terminal surface. (We previously derived x25519 from a local keystore seed; migrating to host/QR auth removed seed access, which is what this would restore — deterministically and recoverably.)
  • Avoids consumers depending on @novasamatech/host-papp internals or re-implementing a security-sensitive derivation.

Notes / open questions

  • Should the derivation be done client-side from rootEntropySource (deterministic, no round-trip), or routed through the host like the web truApi.entropy.derive? Client-side matches the fact that rootEntropySource is already local to the session.
  • A ./crypto subpath re-exporting host-papp's branded EncrSecret/EncrPublicKey/SharedSecret types + createSharedSecret would let consumers do per-user key wrapping without importing the internal package.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions