Skip to content

Normative

Status of this specification

Publishing a specification before an implementation is deliberate — the design benefits from review while it is still cheap to change — but it makes an honest status page mandatory. This is that page, and it is the only place on this site where maturity is stated.

Part Status What that means
The shared substrate Stable One hash, one signature suite, one chained-record schema, one padding function. Nothing here may become optional
SSP/1 — synchronization Complete enough to implement Its open gaps are enumerated, and promotion carries its own eight gates, all open. Not wire-compatible with any prior mesh synchronization protocol, and no interoperability with one is claimed
SOP/1 — object plane Complete, gated The full architecture: ES256 root identity, recorded key protection, receipt durability. Promotion to a normative production protocol is gated on G1–G10 below
SOP/1 blob annex Draft Changes nothing in SOP/1 and carries its own three gates; GB1 is closed, GB2 and GB3 are open
SOVM-SYNC-RT Draft Carries its own three gates; GR1 is closed, GR2 and GR3 are open
SOVM-IROH Draft Carries its own three gates, all closed. Draft is the document’s maturity, not the gates’: closing them retires the reservation on the binding, it does not promote the page

Conformance means agreement with the text plus agreement with the published vectors. Both layers now carry vectors, so independent implementations can be checked against each other on the bytes they exchange, on every refusal the fail-closed inventory requires, and on the state they materialize from the event sets the corpus enumerates — but not yet on convergence as a property over the sets it does not, and SSP/1 §39 names that remainder as the gap that blocks production use.

The following gates MUST pass before SOP/1 becomes a normative production protocol. All ten are open. A gate that fails is information rather than a setback: the size-padding capability in particular is specified to fail closed rather than degrade, so “this cannot be done with current tooling” is a legitimate and useful outcome.

Gate State Verdict
G1 OpenMLS mobile viability open target
G2 Secure hardware identity open target
G3 OpenMLS persistence security open target
G4 Membership/fork behavior open target
G5 PME interoperability open target
G6 PME performance open target
G7 Revocation semantics open target
G8 Metadata leakage review open target
G9 COSE interoperability and misuse resistance open target
G10 Disaster recovery open target

A gate is marked closed here only together with a published verdict naming the evidence it closed on; an open gate’s verdict is a target.

Demonstrate correct operation on:

  • iOS node hardware;
  • Android node hardware;
  • suspend/resume;
  • process death;
  • long offline periods;
  • app upgrade;
  • node restart.

Building for a target is insufficient; integration must be exercised.

The intent of this gate — demonstrate the selected MLS credential/signature integration without silently exporting the SSP root identity private key — cannot be tested as phrased: a gate stated as the absence of a behaviour has no achievable evidence standard, because no finite test run demonstrates that an export never happens. The gate is therefore stated as observable outcomes.

On each target platform, demonstrate that:

  1. a node root key is generated inside the platform keystore, marked non-extractable at generation, and that an extraction attempt fails;
  2. the node identity record carries the key_protection and attestation_kind values that platform actually supports, and the MLS credential binding transcript of Section 5.3 binds them;
  3. a verifier presented with hardware_attested and no evidence, expired evidence, or evidence over a different key treats the node as software (Section 5.2.4);
  4. a policy requiring a minimum level refuses a node below it rather than admitting it;
  5. on an element exposing the atomic sign-verify-or-abort primitive that Section 5.4 requires, the hardware signer’s verify-after-sign check is present and rejects a corrupted signature; on an element exposing none, the implementation’s declaration under that section records that, and the per-platform verdict names the unmitigated fault-injection residual rather than reporting a pass.

Each of these is an observable outcome with a pass and a fail. The verdict MUST be reported per platform and MUST NOT be averaged: an Android StrongBox node reaching hardware_attested and an iOS node reaching hardware_unattested are two different results and G2 records both.

Demonstrate:

  • encrypted durable state;
  • safe deletion behavior;
  • no plaintext key backup;
  • crash consistency;
  • upgrade/migration behavior;
  • iOS Keychain accessibility classes use an appropriate ThisNodeOnly policy for non-migratable key material;
  • iOS key-store/support files are excluded from backup where appropriate. Exclusion is retained at directory granularity as defence in depth and MUST NOT be relied on as the confidentiality control: isExcludedFromBackup is documented as guidance to the system rather than a guarantee, and it is file metadata that the write-temp-then-rename path of any durable store discards. The control is that durable state is ciphertext under a KEK held with a …ThisDeviceOnly Keychain accessibility class, and that Keystore key material never leaves the TEE or StrongBox to be backed up at all;
  • Android backup behavior is explicitly configured, including android:allowBackup, cloud-backup rules, node-transfer rules, and use of no-backup storage for sensitive files;
  • restore/migration tests prove that copied application files alone do not recreate usable SOP/MLS key authority.

Exercise:

  • simultaneous proposals;
  • concurrent commits;
  • stale commits;
  • delayed Welcome;
  • offline member catch-up;
  • removed offline member;
  • blind relay CAS sequencing;
  • simultaneous Commit race with exactly one accepted winner;
  • second-Commit rejection for the same MLS epoch;
  • relay outage with queued membership changes;
  • semantically invalid accepted Commit followed by client rejection and recovery;
  • fork detection/recovery for states created outside the normal sequenced path;
  • sequencer bootstrap for a newly created group;
  • rejection of concurrent dual-sequencer operation and correct epoch transfer on sequencer migration;
  • receipt-based sequencer state-loss recovery: recovery from concordant receipt-chain evidence, fail-closed on divergent valid chains, and genesis-reset fallback when no usable receipt evidence survives;
  • committer death: MLS epoch advanced but the KEK-distribution message never arrives, followed by recovery through a fresh security rotation and voiding of the undistributed generation;
  • sequencer equivocation detection from two valid receipts for the same (group_id, epoch) with different commit hashes, followed by sequencer migration and state audit;
  • receipt-chain continuity verification across sequencer migration.

Demonstrate that SOP-PME-1 files can be:

  • written;
  • transferred unchanged;
  • read by target DuckDB versions;
  • selectively scanned;
  • compacted;
  • verified after corruption tests;
  • shown to reject a module transplanted within an object, or between objects sharing a DEK, by storage_id verification — the empty module AAD (Section 11.3) does not detect either;
  • Padmé-padded to the exact target on every object while remaining byte-for-byte valid PME/Parquet — including an object already at its target, which still carries the reserved sovm:sop-pad-v1 entry with an empty value, and the sizes immediately above each Thrift varint step, which are reachable only by lengthening the key (Section 11.8);
  • written with stable Parquet field IDs on every column;
  • written with an always-present random 16-byte key_ref, in the writer step order of Section 11.12;
  • imported into iroh-blobs with storage_id exactly equal to the returned iroh-blobs hash.

Benchmark representative datasets on:

  • desktop x86-64;
  • Apple Silicon;
  • Android ARM;
  • iPhone/iPad ARM.

Measure:

  • ingestion throughput;
  • encrypted write overhead;
  • selective scan overhead using manifest/catalog-first pruning before PME open;
  • false-positive/open rate from manifest/catalog pruning;
  • APPEND_DELETE delete-filter pruning effectiveness, including optional data-object row-identity filters, their false-positive rates, and manifest/companion-object size impact;
  • full scan overhead;
  • compaction;
  • memory use;
  • battery impact;
  • effect of 16, 32, and 64 MiB object targets;
  • effect of representative Parquet row-group sizes;
  • CPU/platform AES-GCM acceleration availability and impact, including ARMv8 AES/PMULL or equivalent acceleration on minimum supported Android hardware.

Verify through adversarial tests that a removed node cannot:

  • receive current post-removal domain KEK generations;
  • receive unauthorized historical key packages;
  • publish new accepted manifests/access records;
  • decrypt future objects.

Additionally verify through adversarial tests that a FORWARD_ONLY member cannot unwrap or decrypt any object predating its admission boundary, including after arbitrary rewrap and KEK-generation-retirement activity in the domain (Section 7.6).

Also verify documentation clearly states that previously authorized historical data cannot be forcibly forgotten.

Confirm that untrusted infrastructure does not receive semantic:

  • table names;
  • schema names;
  • domain names;
  • plaintext statistics;
  • row keys;
  • key names.

G9. COSE interoperability and misuse resistance

Section titled “G9. COSE interoperability and misuse resistance”

Demonstrate:

  • AccessRecord/wrapped-DEK COSE_Encrypt0 conformance;
  • producer-manifest COSE_Sign1 conformance;
  • access-record issuer-signature and outer COSE_Encrypt0 conformance;
  • historical key-history COSE_Sign1 conformance;
  • deterministic CBOR test vectors;
  • protected-header and algorithm validation;
  • external-AAD context binding;
  • nonce uniqueness under A256GCM;
  • rejection of unknown critical headers;
  • rejection of algorithm downgrade or cross-context replay.

Demonstrate, on representative hardware:

  • periodic catalog checkpoint objects and encrypted+signed RecoveryRoot records are produced and placed on blind replicas under ordinary placement policy;
  • the protected node recovery/key store retains the latest known RecoveryRoot or its content hash without depending on an iroh-local tag;
  • full recovery of a domain dataset from a blind archive plus a bare node recovery/key store only: RecoveryRoot resolved, checkpoint fetched by checkpoint_storage_id, checkpoint access record opened with retained KEK history, catalog restored, objects resolved and queried;
  • recovery from a stale but valid RecoveryRoot produces a consistent older catalog and validates any later root chain supplied by the archive adapter;
  • domain genesis reset end-to-end, including receipt-chain restart and old group retirement;
  • sequencer state-loss recovery succeeds from concordant signed receipt evidence and fails closed on divergent valid receipt chains; and
  • recovery fails closed, with a clear user-facing state, when any of the three required components (ciphertext, manifest/access metadata, KEK history) is absent.

Recorded because a reader evaluating SOVM/1 should know where it is least settled, not only where it is strongest.

Area Risk
Parquet encryption Writer/reader interoperability is unproven
Query path One key per object may conflict with how query engines register decryption keys
MLS on constrained nodes Group state must survive process death, long offline periods and software upgrade, including on mobile platforms
Hardware identity Secure-element integration is platform-specific and may not be available everywhere
Sequencer Correctness under equivocation, migration and state loss is intricate and untested
Performance Encrypted Parquet has non-trivial overhead that has not been benchmarked on target hardware

Reading the specification with this in mind

Section titled “Reading the specification with this in mind”

The specification uses RFC 2119 keywords throughout, which can read as more settled than the situation warrants. A useful convention while the gates are open:

  • MUST / MUST NOT — a design commitment an implementation is expected to honour, and which conformance vectors will eventually test.
  • SHOULD — a considered default, more likely than the rest to move in response to implementation experience.
  • Anything named by a gate above — treat as intent until the gate closes.