Skip to content

Normative · Part

Security considerations

SSP/1’s trust boundary runs around the mesh. Inside it: nodes admitted by the trust authority. Outside it: every other authority, every relay and mailbox operator, every hosting provider, and all shared infrastructure.

The boundary is enforced cryptographically rather than administratively. A node is inside because it holds an identity key the mesh has admitted, not because it sits on a particular network or is named in a configuration file.

There is no privilege gradient inside the boundary. A node authorized to write a table may write anything to it. Per-event signatures make authorship attributable, not constrained.

Position Obtains Does not obtain
Mailbox / relay operator Payload sizes, timing, site_id correspondence graph Payload plaintext; ability to forge events or membership
Network observer Whatever the binding leaks Event contents, if the binding provides confidentiality
Removed node Everything it held before removal Future events, future group secrets
Out-of-scope node Nothing for tables outside its scope Data its policy denies
Compromised authorized node Everything within its scope, and the ability to author events attributed to itself The ability to author events attributed to another node
Stolen locked node Ciphertext at rest and a protected key store; node-local at-rest key material where SOP/1 §7.9’s SHOULD is not met or no pre-boot factor prevents auto-unlock (see §43.1) IK_priv on the hardware tiers — where the identity signing key is generated inside a platform secure element with signing delegated to it, it never crosses the bus regardless of at-rest protection tier (see §43.1 for the software tier)
Stolen unlocked node Everything that node held —
Compromised host OS or hypervisor (authorized node on hardware the user does not control) Everything the authorized node holds and decrypts: in-scope plaintext, retained KEKs, ephemeral secrets resident in process memory; no mechanism in SSP/1 or SOP/1 closes this Events and data outside the compromised node’s in-scope feed

43.1. Conditions on the stolen-locked-node row

Section titled “43.1. Conditions on the stolen-locked-node row”

The “does not obtain” claim for IK_priv holds for the hardware tiers, and only for them. Identity §19 requires IK_priv to be generated inside a platform secure element, non-extractable, with all signing delegated to the element, where the platform provides one; on such a node the private key never crosses the bus and is unaffected by the at-rest tier. A node whose recorded key_protection is software has no element in that loop and the claim does not hold for it — which is why the level is a recorded, surfaced attribute rather than an assumption (identity §19.3), and why policy can refuse a node below a required level rather than admit it lower.

The at-rest claim is distinct and conditional. SOP/1 §7.9 SHOULDs but does not MUST a hardware-backed protecting key for retained application KEKs and offline DEKs — a software-tier implementation is conformant. Additionally, this specification does not require a pre-boot factor: a node that auto-unlocks at boot makes its protecting key recoverable by an attacker with physical access. The attack takes different forms depending on hardware class: on discrete TPM 2.0 implementations the protecting key transits the LPC/SPI bus at power-on and is recoverable by passive bus sniffing; on fTPM-class hardware (AMD fTPM, Intel PTT) the key does not cross an external bus — instead, the faulTPM attack (CVE-2023-20589, AMD-SB-4005) applies voltage fault injection to the AMD Secure Processor on Zen 1–3 silicon to recover the chip-unique secret with low-cost off-the-shelf hardware. A pre-boot factor prevents auto-unlock and defeats both attack families.

The three-tier vocabulary — hardware_attested, hardware_unattested, software — defined in SOP/1 §5.2 and adopted by identity §19.2 records the protection level of the node root key (IK_priv). Deployments that require strong at-rest guarantees SHOULD apply analogous tiering to the §7.9 protecting key and enforce a pre-boot factor. Neither is currently required by this specification.

The compromised-host-OS row names a distinct and non-closeable boundary: no cryptographic mechanism in SSP/1 or SOP/1 prevents a host controlling the hardware from reading a decrypting node’s process. This position is relevant only where an authorized node runs on hardware the user does not physically control; on user-controlled hardware it collapses into the stolen-unlocked-node position.

43.2. The retained event log holds more than the schema does

Section titled “43.2. The retained event log holds more than the schema does”

Wherever a row above says a position obtains what a node holds, that means the node’s retained event log as well as its materialized tables, and the two do not hold the same columns. Semantics §13.6 makes the difference normative: a receiver applies the payload columns its schema has, ignores the rest, and MUST be able to rebuild an ignored column from the log if a migration later adds it. The log therefore retains column values that appear in no table the node could enumerate, for as long as the eviction horizon keeps them.

At-rest protection scoped to the materialized store is under-scoped for that reason. An implementation applying SOP/1 §7.9 MUST cover the retained event log at the level it covers the tables — protecting a column in one place and leaving the event that carried it in the clear protects nothing, and the stolen-node rows above would overstate what a locked node holds back.

Event authorship is verifiable. Every event is a COSE_Sign1 message signed under the authoring node’s root identity key, with the verifier’s own mesh_id supplied as external AAD. A node cannot author an event attributed to another node, and an event captured from one mesh fails verification in every other.

Convergence is deterministic. The materialized state is a pure function of the delivered event set, so no delivery order produces a divergent replica. This is a correctness property with a security consequence: an attacker who controls delivery ordering cannot induce two honest nodes to disagree.

Scope is enforced by the holder. Policy is a sender-side decision that never appears on the wire, so a receiver cannot widen its own feed by misrepresenting its policy.

Clock abuse is bounded. The skew bound stops a node with a hostile clock winning every future comparison indefinitely.

Admission requires a human. Both direct pairing and vouched joining require an affirmative human confirmation, defaulting to deny.

Enumerated in limitations. In brief: no retroactive revocation, no permanent erasure, no revocation announcement, no metadata protection at this layer, no intra-mesh privilege separation, and no specified trust resumption after first pairing.

Purpose Primitive
Durable record container COSE_Sign1 ([RFC 9052], [RFC 9053]), ES256 suite only, under the substrate signature profile
Identity, event, vouch, role and binding signatures ES256 — ECDSA over P-256 with SHA-256 (signature profile)
Transport channel keys (default binding) Ed25519 ([RFC 8032]), as [RFC 7250] raw public keys in TLS 1.3 — deliberately not the identity suite; see transport §28
Pairing key agreement X25519 ([RFC 7748])
Key derivation HKDF-SHA256 ([RFC 5869])
All hashing: identifiers, commitments, event ids, chain links BLAKE3
Canonical encoding Deterministic CBOR ([RFC 8949] section 4.2.1)

Two narrowings are intentional rather than accidental. There is exactly one hash specification: every identifier, commitment, chain link and event id is BLAKE3 over exact bytes, the same convention as SOP/1 — SOVM/1 maintains no second hash namespace. And SSP/1 defines no encryption primitive at all, because it seals nothing: confidentiality is the binding’s responsibility. SHA-256 appears inside ES256 as the signature digest and inside HKDF-SHA256 as the PRF; it is never a content address.

An implementation MUST NOT back up identity key material to a location outside the trust boundary. Where a platform performs automatic cloud backup, key stores MUST be excluded, and the exclusion MUST survive file replacement.

Restoring application files alone MUST NOT recreate usable identity authority. If it does, a copied backup is a cloned node, and every guarantee on this page follows the key rather than the node.

SSP/1’s posture is that a peer must not be able to stop replication with other peers.

Concretely: out-of-scope events are dropped rather than raised; events with unresolvable row keys are dropped and the watermark advances; a malformed body rejects that exchange only; and the apply loop MUST NOT raise on peer-supplied input.

This is why the error posture distinguishes hold from drop. Every hold is a place a hostile peer could stall progress, so holds are restricted to conditions that resolve without that peer’s cooperation.