40 KiB
Sharenet Protocol Specification (Draft)
1. Introduction
This document specifies a decentralized protocol for the creation, distribution, and validation of signed and encrypted Cards. Cards are the fundamental unit of communication in the system. They may be public or private, and may carry access control, distribution rules, and revocation semantics. The protocol also defines a system of Capabilities that allow interoperable feature negotiation without central coordination.
This protocol assumes three fundamental building blocks in addition to Cards:
- Passports: User-held identifiers derived from cryptographic seeds.
- Nodes: Servers that maintain membership, relay Cards, and enforce network policies.
- Networks: Collections of nodes and users defined by a shared Genesis Document.
2. Terminology
- Card: A signed object representing a unit of content. Cards may be public or private, and may be encrypted.
- Capability (cap): A content-addressed specification document that describes a feature, schema, or protocol behavior.
- Capability ID (cap_id): The multibase-encoded hash of a capability spec. Immutable.
- Requirements (
reqs): Capabilities that a verifier MUST support in order to process the Card. - Provenance (
prov): Capabilities the producer actually used when generating the Card. Defaults toreqsif omitted. - Bundle (rollup cap): A capability that implies a deterministic set of member capabilities.
- Policy capsule: An encrypted structure that defines the Card’s visibility, distribution, and keying material.
- Visibility: Who may decrypt the Card payload.
- Distribution: Where the Card may be transmitted.
- Permanent public Card: A Card with no encryption and no revocation path. Immutable.
- Passport: A user-held self-sovereign identifier derived from a mnemonic seed.
- Node: A server implementing this protocol and providing membership and relay functions.
- Network: A collection of nodes and users sharing a Genesis Document.
- Genesis Document: Immutable initial configuration defining a network.
3. Cards
3.1 Structure
A Card is a CBOR map wrapped in a COSE_Sign1 envelope. Fields:
ver: Protocol version.type: MUST be"card".net: Network identifier.rid: Unique Card identifier.ts: Creation timestamp.reqs: Array of capability IDs required to interpret the Card.prov: Optional. Array of capabilities actually used. If absent, treated as identical toreqs.policy_hash: Integrity hash of the policy capsule (encrypted for private Cards, plaintext for public Cards).payload_hash: Integrity hash of the payload.payload: The actual payload (ciphertext for private Cards, plaintext for public Cards).policy: The policy capsule (encrypted for private Cards, plaintext for public Cards).dist_tag: Optional opaque routing hint.sig: Producer signature.
3.2 Policy Capsule
The policy capsule is an encrypted CBOR map. Fields:
vis:"public" | "direct" | "node" | "trustset" | "group".dist:"to_recipients_only" | "this_node_only" | "trusted_nodes" | "public".keying: HPKE encapsulations, MLS group material, or gate instructions for CEK recovery.flags: e.g.permanent_public.exp,ttl: Optional expiry or validity constraints.pad: Optional padding to obscure audience size.roster_encrypted: Optional, group roster encrypted under the group secret.
3.3 Payload
- Private Cards:
payload= AEAD(CEK, plaintext_card_body, AAD={net, rid, policy_hash}) - Public Cards:
payload= plaintext_card_body payload_hash= SHA-256(payload)
4. Capabilities
4.1 Capability ID
cap_id = multibase( sha256( canonical_cbor(spec_without_signatures) ) )
4.2 Capability Spec
A capability spec is a signed document:
schema: MUST be"cap-spec/v1".name: Human-friendly name.semver: Version.purpose: Summary of semantics.behavior: Protocol rules.interop:{requires, supersedes, conflicts}.test_vectors: Golden values for conformance.docs_uri: Documentation.signatures: Array of COSE signatures from authors/curators.
4.3 Bundles
A bundle spec lists members (cap IDs). Bundles MUST expand deterministically into their atomic members before enforcement.
4.4 Negotiation
- Nodes advertise supported caps at
/.well-known/node-caps. - Cards include
reqsfor enforcement,provfor provenance. - Consumers MUST reject Cards if any
reqsare unsupported.
5. Visibility Modes
- Public: No encryption. MAY be flagged permanent.
- Direct: Encrypted CEK to a single recipient (HPKE).
- Node: CEK encrypted to a node’s group key or gate.
- Trustset: CEK encrypted to each trusted node’s group key.
- Group: CEK encrypted to an MLS group. Roster MAY remain private.
6. Distribution Modes
- to_recipients_only: Honest nodes forward only to recipients.
- this_node_only: Not gossiped beyond node.
- trusted_nodes: Forwarded only to trustset.
- public: Freely gossiped. Encryption still protects confidentiality.
Distribution policies MAY be encrypted inside the policy capsule.
7. Revocation
- Permanent public cards: Irrevocable.
- Strong revoke (online gate): CEK fetched from gate; revocation = disable at gate. Instant, requires availability.
- Crypto-shred (offline): CEK wrapped under KEK. Revocation = delete KEK. Prevents new decryption, not past.
- Card Revocation List (CRL): Optional signed log of revoked card IDs. Honest clients suppress display.
8. Security Considerations
- All hashes MUST be computed over canonical CBOR.
- Policy capsule MUST bind
{net, rid, payload_hash}in AEAD AAD. - Bundles MUST be expanded before enforcement.
- Unknown required caps MUST cause rejection.
- Distribution enforcement relies on honest nodes; confidentiality relies on crypto.
- Padding SHOULD be used to obscure audience sizes.
9. Extensibility
- New caps define new features, schemas, and crypto suites.
- Specs are content-addressed, so evolution produces new cap IDs.
- Cards MAY carry adapters in
reqsto allow downgrade/interop. - Deprecated caps SHOULD publish signed deprecation notices.
10. Conformance
A conforming implementation MUST:
- Validate COSE signatures and hashes.
- Enforce all capabilities in
reqs. - Expand bundles before enforcement.
- Respect revocation policies.
- Reject unsupported or malformed Cards.
11. Passports
11.1 Definition
A Passport is a user’s self-sovereign identifier. It consists of:
- A 24-word mnemonic seed (BIP-39 style).
- A derived Ed25519 keypair (public/private).
- A DID constructed from the public key.
The seed MUST remain private to the user’s device.
The private key is deterministically derived from the seed.
The public key is used to generate the DID and sign Cards.
11.2 Export and Recovery
- Users MAY export a Passport file: a locally encrypted container for the seed.
- Users MAY recover their Passport from the 24-word mnemonic if the file is lost.
- A password protects the Passport file, separate from the mnemonic.
- Importing from file requires the password; importing from mnemonic requires only the words.
11.3 Usage
- Cards are signed with the Passport’s Ed25519 private key.
- Verification uses the DID → public key mapping.
- Users MAY belong to multiple networks with the same Passport.
12. Nodes
12.1 Definition
A Node is a server implementing the protocol, typically written in Rust.
It provides:
- Membership management (accepting/revoking Passports).
- Card relay and storage.
- Capability advertisement.
- Optional Key Gate services for strong revocation.
12.2 Membership
- A user joins a Node by presenting a signed request with their Passport public DID.
- The Node MAY issue a Verifiable Credential (VC) attesting to membership.
- Users MAY leave a Node by revoking their VC locally.
- Nodes MAY gossip membership VCs to peers.
12.3 Federation
Nodes communicate using Cards.
Distribution policies determine which nodes are eligible to receive a Card.
Nodes MAY maintain trustsets to decide forwarding scopes.
13. Networks
13.1 Genesis Document
Each network begins with a Genesis Document that defines:
net_id: Unique network identifier.genesis_ts: Timestamp of creation.founders: Initial node and user DIDs.bootstrap_caps: Minimal capability set required for participation.initial_policies: Distribution and trust defaults.
The Genesis Document is signed by the founders and distributed to all participants.
It MUST be immutable. Any update creates a new network.
13.2 Participation
- Users MAY join multiple networks.
- Nodes MAY serve one or more networks, but each Card is bound to a single
net_id. - Networks are sovereign: no privileged global operator exists.
13.3 Migration
- Cards and Passports MAY move between networks.
- Migration of state between networks requires new credentials or attestations.
- Cards created under one
net_idremain bound to thatnet_idforever.
14. Security Model & Assumptions
The protocol operates under the following assumptions and goals:
- Honest-but-curious nodes: Nodes may relay Cards faithfully but attempt to learn additional metadata.
- Malicious peers: Adversaries may forge, replay, strip capabilities, or attempt downgrade attacks.
- Passive observers: Adversaries may monitor network traffic but lack access to private keys.
- Compromised devices: If a user’s Passport seed is stolen, their identity is compromised until rotated.
- Goals: Confidentiality of private Cards, authenticity of signatures, integrity of metadata (AAD), forward secrecy when possible, and user ability to revoke non-permanent Cards.
15. Cryptographic Primitives & Parameters
Implementations MUST use the following algorithms unless explicitly negotiated by capabilities:
- AEAD: XChaCha20-Poly1305 with 256-bit keys.
- HPKE: DHKEM(X25519, HKDF-SHA256) with AEAD-CHACHA20POLY1305.
- Signatures: Ed25519 for Passports.
- Hashing: SHA-256 for
content_hash,policy_ref, and capability IDs. - KDFs: HKDF-SHA256 for deriving CEKs and KEKs.
- Randomness: CEKs MUST be generated with a CSPRNG; nonces MUST NOT repeat.
- AAD binding:
{net, rid, content_hash, policy_ref}MUST be included as Additional Authenticated Data in all AEAD operations.
16. Key Management & Rotation
16.1 Hierarchy
- Seed: Root of identity, represented as a 24-word mnemonic.
- Ed25519 keypair: Derived deterministically from the seed. Used for DIDs and signing.
- CEK (Content Encryption Key): Fresh symmetric key per Card.
- KEK (Key Encryption Key): Optional higher-level key wrapping CEKs, enabling revocation by deletion.
16.2 Rotation
- Users MAY rotate Passport keys by generating a new keypair from the seed with a different derivation path.
- DID key rotation certificates MAY be issued: signed by both old and new keys, linking continuity.
- Nodes and verifiers MUST accept a chain of rotation certificates when validating historical Cards.
16.3 Revocation
- Revocation of Cards MAY occur via deletion of KEKs (crypto-shred) or via refusal to release CEKs (online gate).
- Membership credentials (VCs) MUST include status lists or revocation registries to support user exit from nodes.
17. Policy Capsule Wire Format
17.1 Encoding
- The policy capsule is encoded as CBOR, then wrapped in COSE_Encrypt0.
- Key encapsulation MAY use HPKE (per recipient) or MLS (per group).
- The capsule MUST be integrity-protected with AEAD; AAD MUST include
{net, rid, payload_hash}.
17.2 Structure (plaintext before encryption)
{
"vis": "public" | "direct" | "node" | "trustset" | "group",
"dist": "to_recipients_only" | "this_node_only" | "trusted_nodes" | "public",
"keying": {
"hpke": [ { "kid": <recipient_id>, "enc": <hpke_encap> }, ... ],
"mls": { "group_id": bstr, "epoch": int, "welcome": bstr },
"gate": { "uri": tstr, "aud": bstr, "ttl": int }
},
"flags": { "permanent_public": bool, ... },
"exp": int, ; expiry timestamp (optional)
"pad": bstr, ; optional padding
"roster_encrypted": bstr ; optional roster encrypted under group secret
}
17.3 Padding
- To obscure audience size, implementers SHOULD pad the capsule to fixed bucket sizes (e.g. 1kB, 2kB, 4kB).
padMUST be random bytes ignored by consumers.
17.4 Roster Secrecy
- Group rosters MUST NOT appear in plaintext.
- If included,
roster_encryptedMUST be encrypted under the group key.
18. Revocation: Gate API, Crypto-Shred, and Status Lists
18.1 Gate API
An optional HTTP(S) service MAY act as a key gate.
Endpoints:
POST /cek→ returns CEK wrapped for the requester.POST /decrypt→ returns plaintext stream of Card body.
Rules:
- Requests MUST carry an audience binding (
rid,net). - Gates MUST enforce TTL on issued tokens.
- Rate limits and replay protection MUST be applied.
- Revocation = gate refuses further issuance.
18.2 Crypto-Shred
- CEK is wrapped under a KEK stored at a node or device.
- Revocation = securely delete KEK.
- Clients encountering missing KEK MUST treat the Card as revoked.
18.3 Card Revocation Lists (CRL)
- A CRL is a signed CBOR array of revoked
rids with metadata:
{
"net": <net_id>,
"ts": <timestamp>,
"revoked": [ <rid1>, <rid2>, ... ]
}
- CRLs MUST be signed by the issuer (user or node).
- Clients MUST hide revoked Cards even if cached.
- Freshness MUST be enforced (CRL expiry or versioning).
19. Distribution Rules & Relay Behavior
19.1 Enforcement by Honest Nodes
- to_recipients_only: forward only if node is itself a recipient or directly connected to one.
- this_node_only: MUST NOT forward beyond local storage.
- trusted_nodes: MAY forward only to nodes in the local trustset.
- public: MAY forward freely.
19.2 Logging
- Nodes SHOULD log distribution violations (attempts to forward beyond scope).
- Logs MUST contain only hashes (
rid,content_hash), not plaintext.
19.3 Confidentiality Interaction
- Distribution rules are policy, not crypto.
- Confidentiality is preserved by encryption regardless of distribution.
- Even if a Card leaks beyond scope, non-recipients cannot decrypt.
19.4 Error Signaling
- If a node refuses to forward a Card due to distribution rules, it SHOULD return an error code:
err_dist_scope= distribution violationerr_recipient_only= not a recipient
20. Transport & Gossip Protocol
20.1 Discovery
- Nodes MAY be discovered via:
- Static configuration files or bootstrap lists.
- Distributed Hash Table (DHT) lookups.
- Rendezvous services (non-privileged).
20.2 Message Relay
- Cards are propagated between peers using gossip-style replication.
- Implementations SHOULD batch multiple Cards into a single message for efficiency.
- Backoff strategies MUST be applied when peers are overloaded or unresponsive.
20.3 Deduplication and Replay Protection
- Every Card has a unique
rid. - Nodes MUST maintain a deduplication cache to avoid re-processing the same Card.
- Replay attacks MUST be prevented by rejecting Cards with duplicate
rids or stale timestamps.
20.4 Idempotency and Limits
- All Card handling MUST be idempotent: re-processing MUST NOT change system state.
- Maximum Card size SHOULD be capped (e.g. 1 MB).
- Nodes MAY reject or truncate oversized payloads.
21. Identifiers, Timestamps, and Causality
21.1 RIDs
ridis the globally unique identifier for a Card.- Recommended format: UUIDv7 (time-ordered, random component).
- Collisions are cryptographically improbable; nodes MUST treat duplicates as replay attempts.
21.2 Timestamps
- Each Card includes a creation timestamp (
ts). - Verifiers SHOULD accept timestamps within a tolerance window (e.g. ±5 minutes) to handle clock skew.
- Cards outside this window MAY be flagged or rejected.
21.3 Causality and Linking
- Cards MAY include causal references:
prev: previous Card in a sequence.thread: identifier for a conversation thread.
- Verifiers MAY use these references to reconstruct conversations or detect edits.
22. Schema Packages & Module Loading
22.1 Package Format
- Schemas are distributed as content-addressed packages (hash = ID).
- Packages MUST include:
- Schema definition (e.g., JSON Schema or CDDL).
- Version metadata.
- Optional validation logic.
22.2 Signatures and Trust
- Packages SHOULD be signed by their authors.
- Node admins MAY define local trust policies (e.g., trusted keyrings).
- Unsigned or untrusted packages MAY be rejected.
22.3 Module Execution
- Validation logic MAY be provided as WebAssembly (WASM) modules.
- Nodes MUST sandbox modules with:
- CPU, memory, and time limits.
- Deterministic APIs for schema validation and normalization.
22.4 Installation
- Packages MAY be installed automatically from peers or manually by node admins.
- A CLI MAY be provided:
syspm install <package_hash>
- Auto-installed packages MUST be verified by signature and hash.
- Admin-installed packages override peer-provided ones.
23. Capability Specs, Bundles, and Lifecycle
23.1 Capability Specs
- Capabilities are described in signed spec documents, encoded in CBOR.
- Each spec MUST include:
cap_id: multibase-encoded SHA-256 hash of the spec.version: semantic version string.description: human-readable text.deps: optional list of dependent capabilities.
- Specs SHOULD be signed by their authors to establish provenance.
23.2 Bundles
- A bundle is a capability that expands into a fixed set of other capabilities.
- Bundles MAY form a directed acyclic graph (DAG).
- Expansion MUST be canonical (deterministic order by
cap_id). - Consumers MUST fully expand bundles before validation.
23.3 Deprecation
- A deprecated capability MUST include a deprecation notice object:
{
"deprecated": true,
"replacement": [ <cap_id1>, <cap_id2> ],
"reason": tstr
}
- Consumers SHOULD reject deprecated caps unless explicitly whitelisted.
- Producers SHOULD migrate to replacements at earliest opportunity.
24. Node Roles & Trustsets
24.1 Node Roles
Nodes MAY declare one or more roles:
- archive: long-term storage of all Cards.
- relay: ephemeral forwarder, minimal storage.
- light: partial state, relies on peers for history.
Roles MAY be declared in Node metadata and MAY guide peer selection.
24.2 Trustsets
- A trustset is a locally defined list of nodes considered trustworthy by a given node.
- Trustsets MAY be defined by DID, fingerprint, or signed config.
- Trustsets MUST be rotatable without changing the Genesis Document.
- Distribution rules (e.g. “trusted_nodes”) are enforced using trustsets.
24.3 Rotation
- Trustsets SHOULD support rotation via signed update lists.
- Nodes MAY advertise trustset digests to peers.
- Discrepancies MAY be logged for audit.
25. Membership Credentials & Status
25.1 VC Schema
A membership Verifiable Credential (VC) MUST contain:
{
"vc": {
"sub": <user_did>,
"iss": <node_did>,
"claim": "membership",
"net": <net_id>,
"ts": <issued_timestamp>,
"exp": <expiry_timestamp>
},
"sig": <signature_by_node>
}
25.2 Status Lists
- Nodes MAY maintain status lists indicating active, revoked, or suspended memberships.
- Status lists MUST be signed and periodically refreshed.
- Clients MUST check membership status before validating Cards.
25.3 Verification
- To validate a Card:
- Verify the Card signature against the user’s DID.
- Fetch the user’s membership VC for the target node/network.
- Check the VC’s signature, validity window, and status list entry.
- Historical Cards MUST remain valid if the VC was active at the time of creation.
26. Network Genesis, Publication, and Forks
26.1 Canonical Genesis
- The Genesis Document MUST be encoded in canonical CBOR.
- The
net_idis computed asSHA-256of the canonical bytes. - Genesis MUST include:
net_id,genesis_ts, founders (node/user DIDs), bootstrap capabilities, and policies.
- Genesis is immutable. Any change results in a new
net_idand thus a new network.
26.2 Multi-Signature Policy
- Genesis SHOULD be co-signed by multiple founders.
- Minimum signature threshold MUST be specified (e.g., 2-of-3).
- Verifiers MUST reject Genesis docs without sufficient signatures.
26.3 Publication Channels
- Genesis MAY be published via:
- Static files.
- Peer-to-peer distribution.
- Content-addressed storage (IPFS, Git, etc.).
26.4 No-Tombstone Rule
- Once published, a Genesis Document MUST NOT be deleted.
- Networks have permanence; dissolution only occurs if all peers stop participating.
26.5 Fork Handling
- If conflicting successor Genesis docs appear, each creates a distinct new
net_id. - Participants MAY choose which fork to join.
- Forks MUST NOT silently overwrite each other.
27. Passport Storage & Recovery
27.1 Secure Storage Recommendations
- iOS: Secure Enclave + Keychain.
- Android: Keystore with StrongBox if available.
- macOS: Keychain, optionally hardware-backed.
- Windows: DPAPI + TPM if present.
- Linux: Kernel keyrings, Gnome Keyring, or hardware token (e.g., YubiKey).
- Raspberry Pi: Encrypted filesystem or external hardware token.
27.2 Export Format
- Passport file MUST be an envelope:
{
"enc_seed": <seed_encrypted_under_kek>,
"kdf": "HKDF-SHA256",
"cipher": "XChaCha20-Poly1305",
"salt": bstr,
"nonce": bstr
}
- Protected with a KEK derived from a user-chosen password.
27.3 Recovery from Mnemonic
- A 24-word BIP-39 mnemonic MAY recreate the seed if the file is lost.
- No password required unless PBKDF2 passphrase extension is used.
- Users SHOULD be instructed to back up the mnemonic offline in a safe place.
27.4 Password Policies
- Passwords protecting Passport files SHOULD be high-entropy.
- Minimum recommended length: 12 characters.
- Implementations MAY enforce rate limiting to prevent brute-force attacks.
27.5 Device-as-Gate
- Devices MAY serve as ephemeral gates: refusing to release CEKs unless locally approved.
- Useful for preventing silent key misuse if the device is compromised.
28. Privacy Considerations
28.1 Metadata Minimization
- Cleartext MUST be minimized: only
rid,cap_ids, and distribution policies are visible. - Membership VCs SHOULD NOT be included unless necessary.
- Recipient lists MUST remain encrypted when possible.
28.2 Padding
- Implementations SHOULD pad policy capsules and encrypted payloads to fixed sizes.
- Padding helps obscure audience size and plaintext length.
28.3 Cover Traffic
- Nodes MAY generate synthetic Cards with random content to obscure traffic patterns.
- Cover traffic MUST be clearly marked so peers can discard after validation.
28.4 CEK Caching
- Recipients MAY cache CEKs for performance.
- Caches MUST expire after a reasonable TTL (e.g., 24 hours).
- Revoked CEKs MUST be purged immediately if a CRL or gate refusal is received.
28.5 Oblivious HTTP for Gates
- Gates MAY use Oblivious HTTP to conceal requester identity.
- This prevents correlation between user DID and requested Card IDs.
29. Abuse & Resource Controls
29.1 Rate Limits
- Nodes MUST enforce per-peer request limits to prevent denial of service.
- Suggested baseline: 100 requests/minute per peer, adjustable by implementation.
29.2 Proof-of-Work or Postage
- Networks MAY require lightweight proof-of-work or postage tokens.
- This mitigates spam and incentivizes responsible use of resources.
29.3 Object Size Limits
- Maximum Card size SHOULD be capped (e.g., 1 MB).
- Oversized Cards MAY be rejected with
err_size_exceeded.
29.4 Sandbox Budgets
- WASM modules used for schema validation MUST run in strict sandboxes.
- Execution MUST be limited to:
- CPU time (e.g., 100ms).
- Memory (e.g., 16 MB).
- Modules exceeding budgets MUST be terminated.
29.5 Signature Verification Quotas
- Nodes SHOULD limit the number of signature verifications per peer per unit time.
- Helps protect against CPU exhaustion attacks.
29.6 Ban Lists
- Nodes MAY maintain local ban lists of misbehaving peers.
- Ban lists SHOULD be rotatable and MAY be shared among trusted peers.
30. Errors & Diagnostics
30.1 Error Codes
Implementations MUST support the following error codes for interoperability:
err_req_missing: Required field missing.err_schema_unsupported: Schema not recognized.err_cap_unknown: Capability not recognized.err_revoked: Card has been revoked.err_gate_denied: Gate refused to provide CEK.err_dist_scope: Distribution rule violation.err_recipient_only: Node not an intended recipient.err_size_exceeded: Payload too large.
30.2 Error Format
Errors MUST be encoded as CBOR objects:
{
"err": <error_code>,
"rid": <card_id>,
"hint": tstr
}
hintis an optional human-readable remediation suggestion.
30.3 Logging
- Errors SHOULD be logged locally for diagnostics.
- Logs MUST redact sensitive payload data.
31. Conformance Profiles & Test Vectors
31.1 Profiles
-
Baseline Profile: MUST implement
- Ed25519 signatures.
- XChaCha20-Poly1305 AEAD.
- Direct HPKE.
- Public and direct private Cards.
-
Extended Profile: MUST additionally implement
- MLS groups.
- Gate-based revocation.
- Cover traffic.
- Schema packages with WASM validation.
31.2 Mandatory-to-Implement Capabilities
cap:sign/ed25519cap:encrypt/xchacha20poly1305cap:hpke/x25519-sha256
31.3 Test Vectors
The specification MUST include canonical CBOR + COSE test vectors for:
- Public Card.
- Direct HPKE-encrypted Card.
- MLS group-encrypted Card.
- Gate token retrieval.
- CRL with revoked Cards.
Implementations MUST validate against these vectors to ensure interoperability.
32. Content Addressing & Storage
32.1 Hash Algorithms
- Content hashes MUST use SHA-256 by default.
- Alternative hash functions MAY be advertised via capability IDs.
- The
content_hashMUST uniquely identify the payload of a Card.
32.2 URIs
- Content MAY be referenced via URIs:
ipfs://<cid>https://<host>/<path>s3://<bucket>/<object>
- Implementations MUST verify integrity by recomputing the hash.
32.3 Chunking and Range Fetch
- Large payloads MAY be split into chunks.
- Chunks MUST each carry their own
content_hash. - Range fetch MUST allow partial retrieval and recombination.
32.4 Retention and Garbage Collection
- Nodes MAY garbage-collect old payloads not recently requested.
- Garbage collection policies MUST NOT break integrity: missing payloads must be detectable via hashes.
- Permanent public Cards SHOULD be retained indefinitely.
33. Observability & Audit
33.1 Minimal Logging
- Nodes SHOULD log only:
ridcap_ids- error codes
- Payloads and policy capsules MUST NOT be logged in plaintext.
33.2 Redaction Rules
- Logs MUST redact personally identifiable information (PII).
- Only hashed identifiers may be retained for correlation.
33.3 Migration Receipts
- When a Card is re-issued due to schema or protocol migration, nodes MAY attach a signed migration receipt:
{
"old_rid": <rid>,
"new_rid": <rid>,
"ts": <timestamp>,
"sig": <signature_by_node>
}
- Receipts provide an auditable trail for backward compatibility.
33.4 Telemetry
- Aggregate, privacy-preserving telemetry MAY be published (e.g., number of Cards relayed).
- Telemetry MUST NOT expose user identifiers or Card contents.
34. Human Aliases & I18N
34.1 Aliases for Capabilities
- Capabilities MAY have human-readable aliases.
- Aliases are non-authoritative and for UI purposes only.
- Each alias MUST map to a single
cap_id, but acap_idMAY have multiple aliases.
34.2 Localization
- Aliases MAY be localized into different languages.
- Localization data MUST be distributed separately from the canonical spec.
34.3 Collision Handling
- If two aliases collide:
- Node admins MAY configure preferred mappings.
- UIs SHOULD disambiguate by showing both alias and
cap_id.
34.4 Example
{
"alias": "en:signatures/ed25519",
"cap_id": "zQm..."
}
35. Security Bulletins
35.1 Purpose
- Security bulletins provide a mechanism to urgently disable compromised capabilities, algorithms, or schema packages.
- Bulletins are signed notices distributed across the network.
35.2 Structure
{
"bulletin": "disable",
"cap_id": <capability_id>,
"reason": tstr,
"ts": <timestamp>,
"sig": <signature_by_issuer>
}
35.3 Issuers
- Bulletins MAY be issued by capability authors, network founders, or node operators.
- Clients MUST verify the issuer’s signature against a trusted keyring.
35.4 Client Behavior
- Upon receiving a valid bulletin:
- Clients MUST immediately reject any Card requiring the disabled capability.
- Historical Cards MAY remain valid unless otherwise specified.
- Warnings SHOULD be logged for operator review.
35.5 Distribution
- Bulletins MAY be distributed via gossip, CRLs, or dedicated feeds.
- Clients SHOULD retain bulletins for audit purposes.
36. Evolution Without Epochs
36.1 Approach
- This protocol evolves without centralized epochs.
- Capabilities (
cap_ids) are the atomic unit of evolution. - Each new schema or feature is expressed as a new capability.
36.2 Reqs Defaulting
- Cards MUST include a
reqsfield listing required capabilities. - If
provis omitted, verifiers MUST assumeprov = reqs. - This ensures backward compatibility when producers omit
prov.
36.3 Prov Optionality
- The
provfield MAY list capabilities actually used to generate the Card. - If present,
provMUST be a subset ofreqs. - Consumers MAY use
provfor debugging or migration tracking.
36.4 Breaking Changes
- A breaking schema change MUST result in a new
cap_id. - Producers MUST NOT reuse
cap_ids for incompatible updates. - Consumers MUST reject Cards that require unknown or deprecated
cap_ids.
36.5 Adapters
- Nodes MAY provide adapters to transform Cards from older schema versions to newer ones.
- Adapters MUST be deterministic and SHOULD be distributed as signed schema packages.
- Consumers MUST record the use of adapters in audit logs.
Appendix A. Example Public Card
{
"ver": 1,
"type": "card",
"net": "net:prod:z9…",
"rid": "0x12b…",
"ts": 1738123456,
"reqs": ["cap:card/v1@…"],
"policy_hash": "sha256:…",
"payload_hash": "sha256:…",
"payload": { "msg": "hello world" },
"policy": {
"vis": "public",
"dist": "public",
"flags": { "permanent_public": true }
}
}
Appendix B. Example Private Card (Direct)
{
"ver": 1,
"type": "card",
"net": "net:prod:z9…",
"rid": "0x44a…",
"ts": 1738126789,
"reqs": ["cap:card/v2@…","cap:hpke-x25519-xc20p@…"],
"policy_hash": "sha256:7f…",
"payload_hash": "sha256:aa…",
"payload": "<ciphertext>",
"policy": "<encrypted_policy_capsule>"
}
Status of this Document
This is a working draft. It is subject to change as the protocol evolves. Implementers SHOULD anticipate breaking changes and support migration strategies.
Object Taxonomy & Wire Types (Draft Addendum)
This addendum enumerates object types beyond Cards that a compliant implementation SHOULD/MUST support. It groups them by plane (data, control, governance/ops) and specifies wire shapes, minimal required fields, and security properties. Language follows the style of W3C specs used in the main document.
1. Conventions
- All objects are encoded as CBOR.
- Signed objects use COSE_Sign1 (envelope outside the CBOR map).
- Encrypted objects use COSE_Encrypt0; HPKE/MLS may be used to deliver content keys.
- Hashes MUST be over canonical CBOR.
rididentifies a Card; non-Card objects have their own identifiers as noted.- Capability IDs (
cap_id) are multibase-encoded SHA-256 of the canonical spec bytes.
2. Data-Plane Objects
2.1 Media / Blob Chunks
Purpose: Large attachments referenced from Cards.
Integrity: content_hash (SHA-256) over the chunk bytes.
Encryption: OPTIONAL; if used, reference ciphertext hash.
Shape (meta, unsigned or signed):
{
"schema": "blob-meta/v1",
"content_uri": tstr,
"content_hash": bstr, ; sha256 digest
"size": uint,
"mime": tstr
}
2.2 Search / Index Hints (Optional)
Purpose: Precomputed, normalized views to aid indexing/search.
Security: MUST be signed by the producer.
{
"schema": "index-hint/v1",
"rid": bstr,
"view": { * tstr => any } ; normalized fields per schema module
}
3. Control-Plane Objects
3.1 Schema Packages
Purpose: Define fields & validation for schema-specific payloads.
Security: MUST be signed by author/curators.
Fetch: Content-addressed by schema_id (hash of canonical package bytes).
{
"schema": "schema-package/v1",
"schema_id": tstr, ; cap:schema:<family>/<major>@<hash>
"defs": { ... }, ; CDDL/JSON Schema/CUE
"module": { ; OPTIONAL WASM validator/normalizer
"type": "wasm",
"hash": bstr,
"size": uint
},
"test_vectors": [ bstr, ... ],
"docs_uri": tstr
}
3.2 Schema Descriptors
Purpose: Operator-friendly pointer to install a module out-of-band.
Security: MUST be signed. Node validates artifact hash before load.
{
"schema": "schema-desc/v1",
"schema_id": tstr,
"module": {
"id": tstr,
"version": tstr,
"artifact_hash": bstr,
"size": uint,
"signatures": [ bstr, ... ]
}
}
3.3 Capability Specs & Bundles
Purpose: Advertise features/algorithms/behaviors. Bundles roll up sets.
Security: MUST be signed.
Bundle rule: MUST expand deterministically to atomic caps before enforcement.
{
"schema": "cap-spec/v1",
"cap_id": tstr,
"version": tstr,
"purpose": tstr,
"behavior": { * tstr => any },
"interop": {
"requires": [ tstr, ... ],
"supersedes": [ tstr, ... ],
"conflicts": [ tstr, ... ]
}
}
Bundle spec:
{
"schema": "cap-bundle/v1",
"cap_id": tstr,
"members": [ tstr, ... ] ; ordered, canonical
}
3.4 Node Capability Manifests
Purpose: What a node supports (caps, roles).
Security: SHOULD be signed and available at /.well-known/node-caps.
{
"schema": "node-caps/v1",
"net": tstr,
"caps_supported": [ tstr, ... ],
"roles": [ "relay", "archive", "light" ]
}
3.5 Membership Credentials (VC)
Purpose: “Alice @ Node B” assertion for a given network.
Security: MUST be signed by the issuing node.
{
"schema": "membership-vc/v1",
"vc": {
"sub": tstr, ; user DID
"iss": tstr, ; node DID
"net": tstr,
"claim": "membership",
"ts": uint,
"exp": uint
}
}
3.6 Membership Status Lists
Purpose: Revocation/suspension state for membership VCs.
Security: MUST be signed and time-bounded.
{
"schema": "vc-status/v1",
"net": tstr,
"ts": uint,
"entries": [ { "did": tstr, "status": "active" | "revoked" | "suspended", "exp": uint } ]
}
3.7 Key Rotation Certificates
Purpose: Link old→new public key for a DID.
Security: MUST be countersigned by both old and new keys.
{
"schema": "key-rotate/v1",
"did": tstr,
"prev": bstr, ; old public key
"next": bstr ; new public key
}
3.8 Group/MLS Control
Purpose: Group add/remove, epoch updates.
Security: MLS-native + optional outer signature if wrapped for uniform transport.
{
"schema": "mls-control/v1",
"group_id": bstr,
"epoch": uint,
"msg": bstr ; MLS-encoded frame
}
3.9 Gate Tokens / Requests (Optional)
Purpose: Short-lived authorization to retrieve CEKs or stream decrypts.
Security: MUST be signed, bound to {rid, net}, have short TTL.
{
"schema": "gate-token/v1",
"rid": bstr,
"net": tstr,
"aud": bstr,
"exp": uint
}
3.10 Trustset Updates
Purpose: Rotate which nodes are considered trusted for forwarding.
Security: MUST be signed by local operator key.
{
"schema": "trustset/v1",
"version": uint,
"entries": [ { "node": tstr, "op": "add" | "remove" } ]
}
3.11 DID Resolution Hints (Optional)
Purpose: Cache pointers to DID docs/keys when using non-self-certifying DIDs.
Security: SHOULD be signed; TOFU acceptable per policy.
{
"schema": "did-hint/v1",
"did": tstr,
"endpoints": [ tstr, ... ]
}
4. Governance & Ops-Plane Objects
4.1 Capability Deprecation Notices
Purpose: Announce deprecation and recommended replacements.
Security: MUST be signed.
{
"schema": "cap-deprecate/v1",
"cap_id": tstr,
"replacement": [ tstr, ... ],
"reason": tstr
}
4.2 Security Bulletins
Purpose: Urgently disable compromised capabilities or modules.
Security: MUST be signed by a trusted issuer.
{
"schema": "sec-bulletin/v1",
"action": "disable",
"cap_id": tstr,
"reason": tstr,
"ts": uint
}
4.3 Card Revocation Lists (CRL)
Purpose: Hide/invalidate Cards after intentional revocation.
Security: MUST be signed; freshness enforced.
{
"schema": "crl/v1",
"net": tstr,
"ts": uint,
"revoked": [ bstr, ... ] ; list of rid
}
4.4 Migration Receipts
Purpose: Show lineage when a Card is re-issued under new schema/keys.
Security: MUST be signed by the re-issuer.
{
"schema": "migrate-receipt/v1",
"old_rid": bstr,
"new_rid": bstr,
"ts": uint
}
4.5 Error Objects
Purpose: Interoperable failure signaling across peers.
Security: MAY be unsigned; MAY be signed for audit chains.
{
"schema": "error/v1",
"err": "err_schema_unsupported" | "err_req_missing" | "err_dist_scope" | "err_gate_denied" | "err_revoked" | "err_size_exceeded",
"rid": bstr,
"hint": tstr
}
4.6 Observability / Audit Events
Purpose: Privacy-preserving telemetry and diagnostics.
Security: MUST NOT include plaintext payloads or PII.
{
"schema": "audit-event/v1",
"ts": uint,
"event": tstr,
"rid": bstr,
"caps": [ tstr, ... ],
"code": tstr
}
5. Transport Considerations
- All control-plane and governance objects MAY be gossiped like Cards or fetched on demand by ID (content-addressed).
- Nodes SHOULD cache verified specs/packages and bulletins.
- Deduplicate by
(schema, primary id field)to avoid reprocessing. - Objects MUST be small (typically <64KB), except blob metadata.
6. Security & Validation Rules (Normative)
- Signature verification: Required for all objects that change validation or trust (schema packages, caps, VCs, status lists, deprecations, bulletins, trustsets).
- Determinism: Validators/normalizers MUST be pure and deterministic; no network/file I/O.
- Sandboxing: Any executable validation logic MUST run in a WASM sandbox under strict CPU/mem/time budgets.
- Hash binding: Where objects reference Cards or payloads, they MUST use
ridorcontent_hashand verify before acting. - Policy precedence: Security Bulletins override Deprecation Notices; both override local caches.
- Fail closed: If a required control object is missing or unverifiable, verifiers MUST reject dependent Cards.
7. IANA-Like Registries (Non-Normative)
This ecosystem is intentionally registry-free. Names are content-addressed and self-describing. Communities MAY publish curated alias lists for human UX; implementations MUST NOT rely on aliases for security decisions.