From 9586a9d948396950f74f31d56313e4fc6174a734 Mon Sep 17 00:00:00 2001 From: continuist Date: Tue, 30 Sep 2025 15:59:52 -0400 Subject: [PATCH] Upload files to "/" --- decentralized_cards_primer.md | 136 +++++++++++++++++++++++++++ decentralized_cards_spec.md | 172 ++++++++++++++++++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 decentralized_cards_primer.md create mode 100644 decentralized_cards_spec.md diff --git a/decentralized_cards_primer.md b/decentralized_cards_primer.md new file mode 100644 index 0000000..277395e --- /dev/null +++ b/decentralized_cards_primer.md @@ -0,0 +1,136 @@ +# Primer: Decentralized Card & Capability Protocol + +This primer introduces the main ideas of the Decentralized Card & Capability Protocol in a simplified, narrative form with examples and diagrams. It complements the full specification. + +--- + +## 1. What is a Card? + +A **Card** is a small digital envelope that carries a piece of content (a message, credential, or document). Every Card is: + +- **Signed** → you know who made it +- **Optional encrypted** → you can restrict who can read it +- **Policy-bound** → it carries rules for visibility, distribution, and revocation + +Think of a Card as a "post" that can be **public** or **private**, and can move around the network. + +--- + +## 2. Capabilities + +Capabilities (caps) describe *features* in the system. Each cap has a unique ID (a hash of its definition). + +Examples: +- `cap:card/v1` → basic card format +- `cap:hpke-x25519-xc20p` → encryption using HPKE +- `cap:vc-staple` → attach verifiable credentials + +Cards declare: +- **Requirements (`reqs`)** → features a reader MUST support +- **Provenance (`prov`)** → features the sender’s software actually used (optional) + +### Bundles (Rollups) +Sometimes a set of caps is used together often. These can be rolled into a **bundle cap**. Expanding the bundle reveals all the atomic caps inside. + +--- + +## 3. Anatomy of a Card + +``` ++-------------------------------+ +| Signed Envelope (COSE_Sign1) | +|-------------------------------| +| ver, type, net, rid, ts | +| reqs, prov | +| policy_ref (hash) | +| content_uri + content_hash | ++-------------------------------+ +``` + +- **Envelope**: signed by the creator +- **Policy capsule**: encrypted blob describing visibility & distribution +- **Content**: ciphertext payload (or plaintext for public cards) + +--- + +## 4. Visibility Modes + +- **Public**: anyone can read +- **Direct**: private to one user +- **Node**: private to members of a node +- **Trustset**: private to nodes your node trusts +- **Group**: private to a specific group of users + +Recipient lists are hidden inside the encrypted policy capsule. Outsiders can’t even see who the recipients are. + +--- + +## 5. Distribution Modes + +Distribution is about **where the Card is allowed to go** (not who can read it): + +- `to_recipients_only` → only to recipients +- `this_node_only` → never leaves a node +- `trusted_nodes` → shared with trusted peers +- `public` → gossip freely + +Distribution rules can also be encrypted so outsiders can’t guess your intent. + +--- + +## 6. Revocation + +Cards that are not permanent can be **invalidated** later: + +1. **Strong revoke (online gate)** + - Card points to a key gate. + - Gate can refuse further key requests → instant revoke. + +2. **Crypto-shred (offline)** + - Keys are wrapped under a KEK. + - Delete the KEK → new readers can’t decrypt. + +⚠️ If someone already decrypted before revocation, they still have the plaintext. + +--- + +## 7. Example Flows + +### Public Post +Alice publishes a permanent public Card: +- No encryption +- Flags `permanent_public=true` +- Anyone can read forever + +### Private Message +Alice sends Bob a direct Card: +- Policy capsule contains an HPKE entry for Bob’s key +- Bob decrypts → gets the content +- Outsiders can’t see Bob is the recipient + +### Group Message +Carol posts to her study group: +- Policy capsule carries MLS group state +- Only members can open it +- Outsiders can’t see who’s in the group + +--- + +## 8. Why This Matters + +- **Privacy**: Audience lists are hidden +- **Control**: Users can revoke their Cards (unless marked permanent public) +- **Flexibility**: Supports nodes, trust sets, and groups without central control +- **Interoperability**: Capabilities make it possible to evolve without breaking old Cards + +--- + +## 9. Next Steps + +- Developers should first implement **public cards** + **direct cards** +- Then add **node/trustset/group encryption** +- Finally add **revocation strategies** and **bundle caps** + +--- + +**This primer is non-normative.** For authoritative details, see the [full specification](./decentralized_cards_spec.md). diff --git a/decentralized_cards_spec.md b/decentralized_cards_spec.md new file mode 100644 index 0000000..e9426cc --- /dev/null +++ b/decentralized_cards_spec.md @@ -0,0 +1,172 @@ +# Decentralized Card & Capability Protocol (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 specification is written in the style of the [W3C ActivityPub Recommendation](https://www.w3.org/TR/activitypub/). + +## 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. + +## 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_ref`: Hash of the encrypted policy capsule. +- `content_uri`: URI of the ciphertext payload. +- `content_hash`: Integrity hash of the payload. +- `dist_tag`: Optional opaque routing hint. +- `sig`: Producer signature. + +### 3.2 Policy Capsule + +The policy capsule is an encrypted CBOR map. Fields: + +- `visibility`: `"public" | "direct" | "node" | "trustset" | "group"`. +- `distribution`: `"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 + +- `payload_ciphertext` = AEAD(CEK, plaintext_card_body, AAD={net, rid, policy_ref}) +- Public cards MAY inline plaintext content. + +## 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, content_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. + +## Appendix A. Example Public Card + +```json +{ + "ver": 1, + "type": "card", + "net": "net:prod:z9…", + "rid": "0x12b…", + "ts": 1738123456, + "reqs": ["cap:card/v1@…"], + "body": { "schema": "card/v1", "payload_hash": "…", "content": { "msg": "hello world" } } +} +``` + +## 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_ref": "sha256:7f…", + "content_uri": "ipfs://bafy…", + "content_hash": "sha256:aa…" +} +``` + +--- + +**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.