Skip to content

Normative · Part

Host interface

SOP/1 is specified relative to a host that supplies identity, policy and delivery. SSP/1 is one such host, and this page states the contract precisely so that SOP/1 can also be implemented over a different one.

An implementation satisfying everything on this page is a conforming SOP/1 host, whether or not it implements the rest of SSP/1.

This separation is deliberate. The object plane’s data path — encryption, content addressing, manifests, placement, compaction — depends on none of SSP/1’s wire format, canonical encoding, cursors or merge algebra. It depends on four primitives. Naming them keeps the substitution possible instead of welding the two layers together by accident.

A host MUST provide:

Primitive Requirement
site_id A stable 16-byte identifier, unique within the mesh, rendered as 32 lowercase hex characters. MUST NOT change for the life of the node’s identity key.
mesh_id A stable 16-byte mesh identifier, identical on every node of the mesh.
Signing The ability to produce an ES256 signature under the node’s root identity key over a caller-supplied pre-image, in the fixed-width 64-byte r ‖ s low-S form of the substrate signature profile.
Public-key resolution Given a site_id known to the mesh, return its 33-byte SEC 1 compressed P-256 root identity public key, or report it as untrusted.
Protection level Return the node’s own key_protection and attestation_kind (SOP/1 §5.2), and the recorded level of any site_id it can resolve.
Attestation evidence Where attestation_kind is not none, return the exact evidence bytes the level was verified against.

The signing interface MUST accept a pre-image and return a signature. It MUST NOT require the caller to hold the private key, and a host SHOULD implement it such that the private key is non-extractable — held in a secure element, TPM or platform keystore where available.

That shape is not incidental. SOP/1 binds its MLS credential to this identity, and if a host can only sign by handing out key bytes then the credential binding stops being an assertion about a protected key and becomes an assertion about a copy of one. A host that cannot keep the key non-extractable MUST surface that as an explicit posture rather than degrade silently.

The protection-level and evidence rows are what make the adoption in identity §19.2 mechanically usable. SOP/1 §5.3 binds key_protection, attestation_kind and attestation_evidence_hash into the MLS credential-binding transcript, and SOP/1 obtains node identity from this interface and nowhere else — so a host that cannot report a level cannot host a conforming SOP/1, and a policy that demands a minimum level would be unimplementable against it.

The evidence row returns the exact bytes rather than a parsed structure because the credential binding takes a BLAKE3 hash over them, and a host that re-serialised the evidence would produce a hash the transcript does not match.

A host that supports no protected keystore MUST report software and none rather than omitting the primitives. An absent level is not a level; per SOP/1 §5.2’s gradient, the absence of evidence and the failure of evidence resolve the same way, and neither is better than software.

A host MUST express every admission and removal decision as a signed, hash-chained authorization record. SOP/1 defines the record’s contents and validation rules; the host’s obligation is to produce them, chain them, and make the chain available. In SSP/1 these are COSE_Sign1 records under the shared COSE profile, the same chained shape as role assignments.

Requirements:

  • Each record MUST be signed by a node the mesh’s trust policy authorizes to make the decision, under its root identity key.
  • Each record MUST carry a generation counter and the hash of its predecessor. A generation alone is insufficient: without the predecessor hash a verifier cannot tell which record a given generation supersedes, so two authorized nodes minting conflicting records are distinguished only by whichever downstream operation happened to win. The predecessor hash is also what makes the generation checkable — substrate section 11 requires a record’s generation to be exactly one greater than its predecessor’s.
  • A host MUST surface, not silently reconcile, two records claiming the same predecessor. Because generations are dense, two such records necessarily share a generation, so section 11’s own fork rule discharges this requirement: a host implements it by surfacing the fork, not by carrying a second same-predecessor index.
  • Validation MUST be self-contained: a consumer verifies the signature chain and the density of the generation across each predecessor link without requiring that its own policy replica has already converged. A host that requires policy convergence first creates an availability failure indistinguishable from an attack.

A host MUST NOT require the consumer to trust a transport, a relay or a server for any part of this. The chain is verifiable from the records alone.

A host MUST answer, for a given node and a given table:

may_decrypt(site_id, table) -> yes | no

Requirements:

  • The answer MUST be authoritative for the mesh, not advisory.
  • A host MUST fail closed: absence of an affirmative answer is no.
  • A consumer MUST be able to detect when a cryptographic group grants a node broader access than the scope lookup allows, and MUST treat that mismatch as an error rather than resolving it in favour of either side.

SSP/1’s own implementation of this is described in scope. A different host may derive the answer any way it likes, provided it is deterministic across nodes and fails closed.

A host MUST provide a store-and-forward channel satisfying the mailbox contract — opacity, site_id addressing, durability qualified by recipient trust, a stated finite retention bound, at-least-once delivery, no ordering, and reject-not-drop quota behaviour. The contract is stated once, there; this page restated it for a while, and the two copies had already begun to disagree on quota and on the trust qualifier, which is the argument for not having two copies.

The mailbox exists because a live transport cannot serve peers that are never online simultaneously. It is not a substitute for a live transport and a live transport is not a substitute for it; SOP/1 requires both roles to exist.

Stated so a prospective host knows where its obligation stops:

  • No bulk object transfer. SOP/1 brings its own.
  • No group key management. Where SOP/1 is deployed, MLS handles it.
  • No canonical encoding, cursors, watermarks or merge algebra. Those are SSP/1’s internals, and SOP/1 does not touch them.
  • No transport confidentiality beyond mailbox opacity.
  • No specific pairing ceremony. The host must produce authorization records the consumer can verify; how a human authenticated the decision is the host’s business, subject to the properties in identity.

A host claiming conformance MUST document:

  1. how site_id and mesh_id are derived, and their stability guarantees;
  2. whether the identity key is non-extractable, and on which platforms;
  3. the authorization-record format and its chaining rule;
  4. the scope-lookup semantics and its fail-closed behaviour;
  5. the mailbox retention bound and the operator’s trust position.

An undocumented host is not a conforming host, because a consumer cannot reason about the guarantees it is inheriting.