1231 lines
No EOL
40 KiB
Markdown
1231 lines
No EOL
40 KiB
Markdown
# 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 to `reqs` if 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 to `reqs`.
|
||
- `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 `reqs` for enforcement, `prov` for provenance.
|
||
- Consumers MUST reject Cards if any `reqs` are 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 `reqs` to 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_id` remain bound to that `net_id` forever.
|
||
|
||
## 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)
|
||
```cbor
|
||
{
|
||
"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).
|
||
- `pad` MUST be random bytes ignored by consumers.
|
||
|
||
### 17.4 Roster Secrecy
|
||
- Group rosters MUST NOT appear in plaintext.
|
||
- If included, `roster_encrypted` MUST 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 `rid`s with metadata:
|
||
```cbor
|
||
{
|
||
"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 violation
|
||
- `err_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 `rid`s 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
|
||
- `rid` is 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:
|
||
```bash
|
||
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:
|
||
```cbor
|
||
{
|
||
"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:
|
||
```cbor
|
||
{
|
||
"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_id` is computed as `SHA-256` of 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_id` and 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**:
|
||
```cbor
|
||
{
|
||
"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:
|
||
```cbor
|
||
{
|
||
"err": <error_code>,
|
||
"rid": <card_id>,
|
||
"hint": tstr
|
||
}
|
||
```
|
||
- `hint` is 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/ed25519`
|
||
- `cap:encrypt/xchacha20poly1305`
|
||
- `cap: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_hash` MUST 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:
|
||
- `rid`
|
||
- `cap_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**:
|
||
```cbor
|
||
{
|
||
"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 a `cap_id` MAY 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
|
||
```cbor
|
||
{
|
||
"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
|
||
```cbor
|
||
{
|
||
"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_id`s) 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 `reqs` field listing required capabilities.
|
||
- If `prov` is omitted, verifiers MUST assume `prov = reqs`.
|
||
- This ensures backward compatibility when producers omit `prov`.
|
||
|
||
### 36.3 Prov Optionality
|
||
- The `prov` field MAY list capabilities actually used to generate the Card.
|
||
- If present, `prov` MUST be a subset of `reqs`.
|
||
- Consumers MAY use `prov` for debugging or migration tracking.
|
||
|
||
### 36.4 Breaking Changes
|
||
- A breaking schema change MUST result in a new `cap_id`.
|
||
- Producers MUST NOT reuse `cap_id`s for incompatible updates.
|
||
- Consumers MUST reject Cards that require unknown or deprecated `cap_id`s.
|
||
|
||
### 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
|
||
|
||
```json
|
||
{
|
||
"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)
|
||
|
||
```json
|
||
{
|
||
"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**.
|
||
- `rid` identifies 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)**:
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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).
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"schema": "cap-spec/v1",
|
||
"cap_id": tstr,
|
||
"version": tstr,
|
||
"purpose": tstr,
|
||
"behavior": { * tstr => any },
|
||
"interop": {
|
||
"requires": [ tstr, ... ],
|
||
"supersedes": [ tstr, ... ],
|
||
"conflicts": [ tstr, ... ]
|
||
}
|
||
}
|
||
```
|
||
|
||
**Bundle spec:**
|
||
```cbor
|
||
{
|
||
"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`.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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**.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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.
|
||
|
||
```cbor
|
||
{
|
||
"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 `rid` or `content_hash` and 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. |