Enterprise Data Model
SSP Enterprise maintains the core security principle of never
storing private keys or sensitive data, while enabling seamless
business coordination:
Data Storage Model:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SSP Enterprise Data Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β NEVER STORED (Remains on user devices): β
β βββ Private keys (stay in SSP Wallet/Key) β
β βββ Seed phrases (user-controlled) β
β βββ Transaction signing data β
β βββ Sensitive authentication tokens β
β β
β β
COORDINATION DATA (Stored in SSP Relay): β
β βββ Public keys for address generation β
β βββ Multi-party wallet addresses β
β βββ Business policy configurations β
β βββ Transaction proposals (unsigned) β
β βββ Approval workflows and status β
β βββ Audit trails and compliance logs β
β βββ User roles and permissions β
β β
β π SECURITY BENEFITS: β
β βββ Enables seamless enterprise integration β
β βββ Facilitates analytics and reporting β
β βββ Maintains true self-custody principles β
β βββ Zero risk of private key exposure β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Security Assurance: All stored data is
non-sensitive by design. Even if the SSP Enterprise platform were
compromised, no private keys or funds would be at risk since all
signing operations occur on user-controlled devices.
Cryptographic Foundation of SSP Identity
SSP's entire architecture β from consumer wallet up to
enterprise M-of-N vaults β rests on a single primitive we call
SSP Identity: a 2-of-2 multisignature wallet split
across two independent user-controlled devices (browser extension
and mobile app). Every higher-level construct in the system reduces
to combinations of SSP Identities. Understanding it is the
foundation of understanding everything else.
The 2-of-2 multisignature identity
Each SSP user holds two BIP-32 hierarchical-deterministic seeds,
generated independently on two different devices:
-
s_wallet β generated on first
install of the SSP Wallet browser extension, stored encrypted at
rest with a user-chosen passphrase
-
s_key β generated independently on
first install of the SSP Key mobile app, stored in the OS-level
secure enclave / Keychain with biometric unlock
These two seeds never meet β there is no point in
the system where a single device, server, or process has access to
both. From each seed, the device derives an extended public key
(xpub_wallet, xpub_key) at the BIP-48
multisig branch and exchanges only the extended
public keys with the other device via the relay (or
out-of-band QR scan, for users who want zero-relay setup).
The user's wallet address on each chain is then constructed
as:
SSP Identity address = Multisig(pubkey_wallet, pubkey_key, threshold=2)
derived at BIP-48 path m/48'/coin'/account'/script_type'/0/i
For UTXO chains (Bitcoin, Litecoin, etc.), this materializes as a
native P2WSH 2-of-2 script. For EVM chains, it's
a Schnorr-aggregated key pair that controls an ERC-4337 smart
account. For Solana, it's a 2-of-2 entry in our custom Anchor
multisig program. In every case,
both private keys must produce a signature for any transaction
to be valid
β there is no recoverable threshold of one.
Threat model: why 2-of-2 is strictly stronger than single-key
custody
Single-key wallets (MetaMask, Phantom, Ledger-only setups) have a
1-device security model: compromise of the single device or seed =
total loss. Standard 3-of-5 multisig in business contexts often
degenerates in practice β keys are stored on the same machine, the
same hardware vendor, or the same cloud KMS β collapsing back to
single-point-of-failure.
SSP Identity is structurally resistant to the most common attack
surfaces:
| Attack |
Effect on SSP Identity |
|
Browser extension malware / supply-chain attack on Wallet
|
Attacker has 1 of 2 keys. Cannot sign. |
| Mobile device theft + biometric coercion |
Attacker has 1 of 2 keys. Cannot sign. |
|
Cloud backup leak (iCloud / Google Drive) when seeds backed
up to different services per SSP guidance
|
Recovers at most 1 seed. Cannot sign. |
| Phishing of the user's wallet passphrase |
Decrypts s_wallet only. Still missing
s_key.
|
| Compromise of SSP Relay infrastructure |
Relay holds only public keys and ciphertext message
envelopes. No keys exposed.
|
| Lost device |
Recover via the other device's seed export + reinstall.
Funds intact.
|
The only attack that defeats 2-of-2 is
simultaneous compromise of both devices β a
meaningfully harder threshold than compromising any single device,
and the foundation on which enterprise M-of-N is built.
Wallet βοΈ Key identity proof: the wk_sign protocol
When an application needs to prove the user controls a particular
SSP Identity β for relay authentication, SSP Enterprise login, or
any signed-message workflow β both devices must produce a
signature over a freshness-bound challenge. The protocol is
intentionally minimal:
Message format:
<13-digit ms timestamp> <random hex, 32+ chars>
Total length 45β500 chars
Validation rules (enforced on the receiving device):
β’ First 13 chars parse as a millisecond Unix timestamp
β’ Timestamp is within Β±5 min future drift and β€ 15 min in the past
β’ Message length between 45 and 500 chars
β’ Random portion present and well-formed
Signing:
β’ Both SSP Wallet and SSP Key sign the message under Bitcoin
message signing (BIP-137 style) using their respective
secp256k1 keys derived at the SSP Identity path
m/48'/coin'/account'/script_type'/10/0
β’ Combined response carries: walletSignature, walletPubKey,
keySignature, keyPubKey, witnessScript, wkIdentity, message
Reference implementation:
ssp-wallet/src/lib/wkSign.ts. The 15-minute validity window and 5-minute future-drift
allowance are the only freshness mechanism β there is no separate
replay database. Reuse is bounded by the sliding window; the
verifier's only requirement is that the timestamp falls inside
that window when checked.
Transaction signing is a separate flow that
varies per chain family β UTXO uses progressive
SIGHASH co-signing across both devices using P2WSH
(or P2SH on chains without SegWit), EVM uses MuSig2 Schnorr
aggregation with on-chain ERC-4337 verification, and Solana uses
the custom Anchor program. In every case, both
s_wallet and s_key must produce a
signature for the transaction to be valid.
Sensitive data clearing is enforced at the
application layer β decrypted seed material is zeroed from memory
after the signature is produced; this was hardened in the audit
reviews after an early bug where the encryption password was
cleared one step too early in the mobile flow.
What You See Is What You Sign β on-device transaction decoding
Every multisig wallet faces the same threat: an intermediary
(relay, server, message bus) sends you a transaction to sign, and
you have no way to be sure the summary you see matches
the bytes you sign. A malicious or compromised
intermediary could attach human-readable labels like "Send
100 USDC to alice.eth" while the underlying transaction
actually transfers 1,000,000 USDC to an attacker. This is a
well-known class of attack against any wallet that relies on a
server-decoded preview.
SSP eliminates this entire attack surface by independently
decoding the raw transaction bytes on every signing
device.
Neither the SSP Wallet nor the SSP Key trusts a single byte of
human-readable metadata from the relay. Both devices receive only
the raw transaction data β the same bytes that will be broadcast
to chain β and each device decodes them locally before presenting
them to the user:
-
UTXO chains β both devices independently call
utxolib.Transaction.fromHex() (and PSBT helpers
where applicable) on the raw transaction hex. They extract
sender, recipients, amounts, fees, and any non-change outputs
from the actual bytes. A relay that tampered with a label would
produce a transaction whose on-chain effect differs from the
relay's claim; the local decode catches it.
-
EVM chains β both devices parse the ERC-4337
UserOperation JSON locally and run
viem's decodeFunctionData against
the standard erc20Abi (and against SSP's own
aa-schnorr-multisig-sdk ABI for execute calls) to
recover the real recipient, the real token contract, and the
real base-unit amount. The relay never gets to label a
transaction; the wallet and key apps each compute the label from
on-chain bytes.
-
Solana β both devices decode the bundled
transaction (which contains
nonceAdvance + create_transaction + approve_transaction Γ
threshold + execute_transaction + close_transaction) using on-device Solana SDK helpers, extract the instructions,
and verify the inner program invocations.
This is implemented in
ssp-wallet/src/lib/transactions.ts
(decodeVaultTransaction) and
ssp-key/src/lib/transactions.ts
(same function name, same logic, separate codebase). Both
EnterpriseVaultSignTx
on the wallet side and
VaultSignRequest
on the key side render their UI from this locally-decoded data,
not from anything the relay sent in a metadata field.
The user signs exactly what they see, and what they see came
from the bytes that will hit the chain.
A compromised SSP Relay β or a compromised SSP Enterprise backend,
or a man-in-the-middle, or a malicious dApp speaking WalletConnect
β cannot get either device to display a misleading preview,
because neither device trusts the preview source. The same applies
to the SSP Identity proof flow (wk_sign): the message
that gets signed is the message both devices independently parse
from the raw envelope, not a server-provided rendering of it.
Self-hostable, zero-trust relay design
The SSP Relay is deliberately minimal:
-
Stateless message forwarding with TTL-bounded
mailboxes per WK Identity
-
No private key material, ever β only ciphertext
envelopes and public coordination data (xpubs, addresses,
unsigned proposals, audit logs)
-
Public, AGPL v3, self-hostable β any
organisation that wants zero dependency on InFlux infrastructure
can run their own relay endpoint and point their wallet + mobile
app at it
-
No central authority β the relay cannot
authorize, block, or modify any signature. It is a dumb pipe
with a database of public coordination data
Even a fully compromised relay leaks no signing capability. The
worst-case adversary model is a relay that drops messages or
attempts replay β both of which are detected by the device-side
validation in step 4 above.