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.
1. Node identity
Section titled “1. Node identity”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.
2. Admission and removal
Section titled “2. Admission and removal”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.
3. Scope lookup
Section titled “3. Scope lookup”A host MUST answer, for a given node and a given table:
may_decrypt(site_id, table) -> yes | noRequirements:
- 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.
4. Asynchronous mailbox
Section titled “4. Asynchronous mailbox”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.
5. What the host does NOT have to provide
Section titled “5. What the host does NOT have to provide”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.
6. Conformance
Section titled “6. Conformance”A host claiming conformance MUST document:
- how
site_idandmesh_idare derived, and their stability guarantees; - whether the identity key is non-extractable, and on which platforms;
- the authorization-record format and its chaining rule;
- the scope-lookup semantics and its fail-closed behaviour;
- 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.