@metalabel/dfos-protocol 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,107 @@
1
+ # DFOS Content Model
2
+
3
+ Standard content schemas for documents committed to DFOS content chains. JSON Schema (draft 2020-12) definitions for what goes inside the document envelope's `content` field.
4
+
5
+ These schemas are conventions, not protocol requirements. The DFOS Protocol commits to documents by CID without inspecting their contents — any valid JSON object with a `$schema` field can be committed. The content model defines the vocabulary that DFOS uses internally, provided as a starting point for applications built on the protocol.
6
+
7
+ [Protocol Specification](https://protocol.dfos.com/spec) · [schemas.dfos.com](https://schemas.dfos.com) · [Source](https://github.com/metalabel/dfos/tree/main/packages/dfos-protocol/schemas)
8
+
9
+ ---
10
+
11
+ ## Schema Convention
12
+
13
+ Every document committed to a content chain is wrapped in a [document envelope](https://protocol.dfos.com/spec#document-envelope). The envelope's `content` field holds the application-defined payload. The protocol requires one thing of this payload: it must include a `$schema` property identifying its content type.
14
+
15
+ ```json
16
+ {
17
+ "$schema": "https://schemas.dfos.com/post/v1",
18
+ "format": "short-post",
19
+ "body": "Hello world."
20
+ }
21
+ ```
22
+
23
+ Because `$schema` is part of the document, it is behind the `documentCID` — cryptographically committed in the content chain. Any verifier can resolve the document, read `$schema`, and validate against the schema. Documents are self-describing.
24
+
25
+ ---
26
+
27
+ ## Schema Evolution
28
+
29
+ Schemas are versioned via the URI path (`/post/v1`, `/post/v2`). Evolution rules:
30
+
31
+ - **Strictly additive within a version** — new optional fields can be added to an existing version at any time without breaking existing documents
32
+ - **Breaking changes require a new version** — removing fields, changing types, or adding new required fields means a new version URI
33
+ - **Implementations declare which versions they understand** — a registry or application can accept `post/v1` and `post/v2` simultaneously, or only `post/v1`
34
+
35
+ ---
36
+
37
+ ## Standard Schemas
38
+
39
+ Schema files live in [`schemas/`](https://github.com/metalabel/dfos/tree/main/packages/dfos-protocol/schemas) in the protocol package. Each is a standalone JSON Schema (draft 2020-12) definition, served at `https://schemas.dfos.com`.
40
+
41
+ ### Post (`https://schemas.dfos.com/post/v1`)
42
+
43
+ The primary content type. Covers short posts, long-form posts, comments, and replies via the `format` discriminator.
44
+
45
+ | Field | Type | Required | Description |
46
+ | ------------- | -------- | -------- | ---------------------------------------------------------------------------------- |
47
+ | `$schema` | string | yes | `"https://schemas.dfos.com/post/v1"` |
48
+ | `format` | enum | yes | `"short-post"`, `"long-post"`, `"comment"`, `"reply"` — immutable, set at creation |
49
+ | `title` | string | no | Post title (typically for long-post format) |
50
+ | `body` | string | no | Post body content |
51
+ | `cover` | media | no | Cover image |
52
+ | `attachments` | media[] | no | Attached media objects |
53
+ | `topics` | string[] | no | Topic names (stored as names for portability) |
54
+
55
+ ### Profile (`https://schemas.dfos.com/profile/v1`)
56
+
57
+ The displayable identity for any agent, person, group, or space.
58
+
59
+ | Field | Type | Required | Description |
60
+ | ------------- | ------ | -------- | --------------------------------------- |
61
+ | `$schema` | string | yes | `"https://schemas.dfos.com/profile/v1"` |
62
+ | `name` | string | no | Display name |
63
+ | `description` | string | no | Short bio or description |
64
+ | `avatar` | media | no | Avatar image |
65
+ | `banner` | media | no | Banner image |
66
+ | `background` | media | no | Background image |
67
+
68
+ ### Media Object
69
+
70
+ Several schemas reference media objects. The standard representation:
71
+
72
+ ```json
73
+ {
74
+ "id": "media_abc123",
75
+ "uri": "https://cdn.example.com/media/abc123.jpg"
76
+ }
77
+ ```
78
+
79
+ `id` is required (opaque identifier). `uri` is optional.
80
+
81
+ ---
82
+
83
+ ## Chain Interpretation
84
+
85
+ A content chain is a signed append-only log. The protocol enforces ordering, authorship, and integrity. It does not prescribe what the chain _means_. How an application interprets a content chain depends on the content types committed to it.
86
+
87
+ ### Living Document
88
+
89
+ The chain represents a single evolving thing — a profile, a post, a policy document. Each operation is a **revision**. The resolved state is the latest `documentCID`. History is audit trail. The content _is_ the current version.
90
+
91
+ This is the default interpretation for the standard schemas. The document envelope's `baseDocumentCID` field supports edit lineage — each new document version can point back to the one it replaced.
92
+
93
+ ### Stream
94
+
95
+ The chain represents a sequence — a feed, a journal, a log. Each operation is a discrete emission, not a revision. There is no single "current state" — the chain _is_ the content. Previous documents aren't superseded, they're siblings in a series.
96
+
97
+ ### Other Patterns
98
+
99
+ The protocol cannot distinguish these patterns — the operation schema is identical in both cases. The difference is a reading convention, signaled by the `$schema` of the documents. Future content types could define event-sourcing patterns, append-only collections, or interpretations not yet imagined.
100
+
101
+ ---
102
+
103
+ ## Custom Schemas
104
+
105
+ Any implementation can define custom document schemas following the same pattern — a JSON Schema with a `$schema` const field pointing to a unique URI. The protocol will commit to the document via CID regardless of what's inside. The standard schemas are conventions, not constraints.
106
+
107
+ Custom schema URIs should use a namespace you control (e.g., `https://schemas.example.com/my-type/v1`) to avoid collisions with the standard library.
package/DID-METHOD.md ADDED
@@ -0,0 +1,326 @@
1
+ # DID Method: `did:dfos`
2
+
3
+ W3C DID Method specification for DFOS identity chains. Self-certifying, transport-agnostic, Ed25519-based decentralized identifiers.
4
+
5
+ This spec is under active review. Discuss it in the [clear.txt](https://clear.dfos.com) space on DFOS.
6
+
7
+ [Source](https://github.com/metalabel/dfos/tree/main/packages/dfos-protocol) · [Protocol Specification](https://protocol.dfos.com/spec) · [npm](https://www.npmjs.com/package/@metalabel/dfos-protocol)
8
+
9
+ ---
10
+
11
+ ## Abstract
12
+
13
+ This document defines the `did:dfos` DID method in conformance with the [W3C Decentralized Identifiers (DIDs) v1.0](https://www.w3.org/TR/did-core/) specification. A `did:dfos` identifier is derived deterministically from the genesis operation of a cryptographically signed identity chain. Resolution is verification-first and transport-agnostic — the identifier itself is the trust anchor, not any particular registry or consensus layer.
14
+
15
+ ---
16
+
17
+ ## Status
18
+
19
+ This specification is under active development. It has not been submitted to any formal standards body.
20
+
21
+ ---
22
+
23
+ ## Conformance
24
+
25
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).
26
+
27
+ ---
28
+
29
+ ## 1. Introduction
30
+
31
+ DFOS is a protocol for verifiable identity and content chains using Ed25519 signatures and content-addressed CIDs. Every identity in DFOS is an append-only chain of signed operations — a self-sovereign log of key management events. The DID for an identity is derived deterministically from the hash of the chain's genesis operation, making `did:dfos` identifiers **self-certifying**: given the chain, anyone can independently verify the DID without trusting the source.
32
+
33
+ This property makes `did:dfos` fundamentally transport-agnostic. There is no privileged registry, blockchain, or consensus layer. The chain can be obtained from any source — an HTTP API, a peer-to-peer exchange, a local file, a USB drive — and the verifier can independently confirm the chain belongs to the claimed DID.
34
+
35
+ For full protocol details including cryptographic primitives, chain mechanics, and test vectors, see the [DFOS Protocol Specification](https://protocol.dfos.com/spec).
36
+
37
+ ### 1.1 Design Goals
38
+
39
+ - **Self-certifying** — The DID is a deterministic derivation of the genesis content. No external authority is needed to verify the binding between identifier and chain.
40
+ - **Transport-agnostic** — Resolution requires obtaining and verifying a chain, not querying a specific endpoint. Any system that stores and serves identity chains is a valid source.
41
+ - **Key rotation** — Identity chains support full key rotation via signed update operations. Keys can be added, removed, and replaced without changing the DID.
42
+ - **Deactivation** — Identities can be permanently deactivated via a signed delete operation.
43
+ - **Minimal** — The method defines identifiers and verification. It deliberately does not define discovery, gossip, or consensus mechanisms.
44
+
45
+ ---
46
+
47
+ ## 2. DID Method Name
48
+
49
+ The method name is `dfos`. A DID using this method MUST begin with the prefix `did:dfos:`.
50
+
51
+ ---
52
+
53
+ ## 3. Method-Specific Identifier
54
+
55
+ The method-specific identifier is a 22-character string derived from the genesis operation CID of an identity chain.
56
+
57
+ ### 3.1 ABNF
58
+
59
+ ```abnf
60
+ dfos-did = "did:dfos:" dfos-id
61
+ dfos-id = 22dfos-char
62
+ dfos-char = "2" / "3" / "4" / "6" / "7" / "8" / "9" /
63
+ "a" / "c" / "d" / "e" / "f" / "h" / "k" /
64
+ "n" / "r" / "t" / "v" / "z"
65
+ ```
66
+
67
+ The alphabet is 19 characters: `2346789acdefhknrtvz`. The identifier is exactly 22 characters, providing ~93.4 bits of entropy.
68
+
69
+ ### 3.2 Derivation
70
+
71
+ The method-specific identifier is derived deterministically from the genesis identity operation:
72
+
73
+ ```
74
+ 1. Construct the genesis identity operation payload (type: "create")
75
+ 2. Canonical-encode the payload as dag-cbor → CBOR bytes
76
+ 3. Hash: SHA-256(CBOR bytes) → 32-byte digest
77
+ 4. Construct CIDv1: [0x01, 0x71, 0x12, 0x20, ...32 digest bytes] → CID bytes
78
+ 5. Hash the CID: SHA-256(CID bytes) → 32-byte digest
79
+ 6. Encode: for each of the first 22 bytes → alphabet[byte % 19]
80
+ ```
81
+
82
+ The resulting 22-character string is the method-specific identifier. The full DID is `did:dfos:` prepended to this string.
83
+
84
+ ### 3.3 Example
85
+
86
+ ```
87
+ Genesis CID bytes (hex): 01711220206a5e6140a5114f1e49f3ca4b339fb2cb8e70bbb34968b23156fd0e3237b486
88
+ SHA-256 of CID bytes: 4360cfbcbbb3f1614c8e02dbfe8d55935e1195cd2129820ab8aef94bde12ea8a
89
+ First 22 bytes encoded: e3vvtck42d4eacdnzvtrn6
90
+ DID: did:dfos:e3vvtck42d4eacdnzvtrn6
91
+ ```
92
+
93
+ See the [DFOS Protocol Specification](https://protocol.dfos.com/spec) for the complete worked example with key material, CBOR encoding, and CID construction.
94
+
95
+ ---
96
+
97
+ ## 4. DID Document
98
+
99
+ A resolved `did:dfos` DID Document is constructed from the current state of the identity chain — specifically, the key sets declared in the most recent non-terminal operation.
100
+
101
+ ### 4.1 DID Document Structure
102
+
103
+ ```json
104
+ {
105
+ "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1"],
106
+ "id": "did:dfos:e3vvtck42d4eacdnzvtrn6",
107
+ "controller": "did:dfos:e3vvtck42d4eacdnzvtrn6",
108
+ "verificationMethod": [
109
+ {
110
+ "id": "did:dfos:e3vvtck42d4eacdnzvtrn6#key_r9ev34fvc23z999veaaft8",
111
+ "type": "Multikey",
112
+ "controller": "did:dfos:e3vvtck42d4eacdnzvtrn6",
113
+ "publicKeyMultibase": "z6MkrzLMNwoJSV4P3YccWcbtk8vd9LtgMKnLeaDLUqLuASjb"
114
+ }
115
+ ],
116
+ "authentication": ["did:dfos:e3vvtck42d4eacdnzvtrn6#key_r9ev34fvc23z999veaaft8"],
117
+ "assertionMethod": ["did:dfos:e3vvtck42d4eacdnzvtrn6#key_r9ev34fvc23z999veaaft8"],
118
+ "capabilityInvocation": ["did:dfos:e3vvtck42d4eacdnzvtrn6#key_r9ev34fvc23z999veaaft8"]
119
+ }
120
+ ```
121
+
122
+ ### 4.2 Verification Method Mapping
123
+
124
+ Identity chain operations declare three key sets. These map to W3C verification relationships as follows:
125
+
126
+ | Identity Chain Key Set | W3C Verification Relationship | Purpose |
127
+ | ---------------------- | ----------------------------- | -------------------------------------------------------------------- |
128
+ | `authKeys` | `authentication` | Prove control of the DID (e.g., login, session establishment) |
129
+ | `assertKeys` | `assertionMethod` | Issue verifiable assertions (e.g., sign content chain operations) |
130
+ | `controllerKeys` | `capabilityInvocation` | Manage the DID itself (sign identity chain update/delete operations) |
131
+
132
+ Each key in the identity chain state becomes a `verificationMethod` entry. The `id` is constructed as a DID URL: `did:dfos:<id>#<keyId>`. The `type` is `Multikey`. The `publicKeyMultibase` is the W3C Multikey encoding (multicodec `0xed01` prefix + base58btc + `z` multibase prefix).
133
+
134
+ ### 4.3 Controller
135
+
136
+ `did:dfos` identities are self-sovereign. The `controller` property of the DID Document is always the DID itself. Only keys within the identity chain's `controllerKeys` set can sign operations that modify the chain.
137
+
138
+ ### 4.4 Key Rotation
139
+
140
+ When an identity chain includes `update` operations that change the key sets, the DID Document reflects the **current state** — the key sets from the most recent operation. Previous keys are not included in the resolved DID Document. Historical key states can be recovered by walking the chain.
141
+
142
+ ### 4.5 Services
143
+
144
+ The core `did:dfos` method does not define any `service` entries in the DID Document. Applications MAY extend the DID Document with service endpoints through application-layer conventions.
145
+
146
+ ---
147
+
148
+ ## 5. Operations
149
+
150
+ ### 5.1 Create
151
+
152
+ Creating a `did:dfos` identifier means constructing and signing a genesis identity chain operation.
153
+
154
+ 1. Generate one or more Ed25519 key pairs.
155
+ 2. Construct the genesis operation payload with `type: "create"`, populating `authKeys`, `assertKeys`, and `controllerKeys`. At least one `controllerKeys` entry is REQUIRED.
156
+ 3. Canonical-encode the payload as dag-cbor, derive the CID, and include it in the JWS protected header as `cid`.
157
+ 4. Sign the operation as a JWS Compact Serialization token using one of the controller keys. The `kid` in the protected header is the bare key ID (not a DID URL, since the DID does not yet exist).
158
+ 5. The DID is derived from the genesis CID as described in [Section 3.2](#32-derivation).
159
+
160
+ The identity chain now exists as a single-operation chain. It can be stored in any system that serves identity chains.
161
+
162
+ ### 5.2 Read (Resolve)
163
+
164
+ Resolving a `did:dfos` DID means obtaining the identity chain and constructing a DID Document from its current state.
165
+
166
+ #### 5.2.1 Resolution Algorithm
167
+
168
+ Given a DID `did:dfos:<id>`:
169
+
170
+ 1. **Obtain** the identity chain from any available source. The method does not prescribe how chains are discovered or transported.
171
+ 2. **Verify** the chain:
172
+ a. Decode each JWS token and parse the operation payload.
173
+ b. The first operation MUST be `type: "create"`.
174
+ c. Derive the genesis operation CID via dag-cbor canonical encoding.
175
+ d. Verify that `SHA-256(genesis CID bytes)` encoded with the ID alphabet produces `<id>`. If it does not match, the chain does not belong to this DID — reject it.
176
+ e. For each operation, verify the JWS EdDSA signature against the appropriate key (controller key from current chain state).
177
+ f. Verify `previousOperationCID` linkage, `createdAt` ordering, and `header.cid` consistency.
178
+ g. See the [DFOS Protocol Specification](https://protocol.dfos.com/spec) for complete verification rules.
179
+ 3. **Construct** the DID Document from the terminal chain state using the mapping in [Section 4.2](#42-verification-method-mapping).
180
+
181
+ #### 5.2.2 Resolution Metadata
182
+
183
+ | Property | Value |
184
+ | ---------------- | ------------------------------------------------------------ |
185
+ | `contentType` | `application/did+ld+json` |
186
+ | `created` | `createdAt` from the genesis operation |
187
+ | `updated` | `createdAt` from the most recent operation |
188
+ | `deactivated` | `true` if the chain's terminal operation is `type: "delete"` |
189
+ | `operationCount` | Number of operations in the chain |
190
+
191
+ #### 5.2.3 Self-Certification
192
+
193
+ The critical property of `did:dfos` resolution: **the DID is verified against the chain, not the source.** Step 2d above is the self-certification check — it proves the chain belongs to the claimed DID using only the chain content and a hash function. This means:
194
+
195
+ - A resolver does not need to trust the registry, server, or peer that provided the chain.
196
+ - The same chain can be served by multiple independent sources with identical results.
197
+ - Chains can be cached, replicated, and redistributed without loss of verifiability.
198
+ - Offline resolution is possible if the chain is available locally.
199
+
200
+ #### 5.2.4 Transport Bindings (Non-Normative)
201
+
202
+ The `did:dfos` method is transport-agnostic. Any system that can deliver an ordered sequence of JWS tokens (the identity chain) is a valid transport. Examples include:
203
+
204
+ - **HTTP API** — The DFOS Registry API ([OpenAPI spec](https://github.com/metalabel/dfos/blob/main/packages/dfos-protocol/openapi.yaml)) provides a REST interface for chain storage and retrieval.
205
+ - **Peer-to-peer exchange** — Chains can be exchanged directly between parties.
206
+ - **Local storage** — Chains can be stored in local files, databases, or key-value stores.
207
+ - **Bundle export** — Applications can export chains as portable bundles (e.g., JSON arrays of JWS tokens).
208
+
209
+ ### 5.3 Update
210
+
211
+ Updating a `did:dfos` DID means appending a signed `update` operation to the identity chain.
212
+
213
+ 1. Construct an update operation payload with `type: "update"`, the new key sets, and `previousOperationCID` set to the CID of the current chain tip.
214
+ 2. Sign the operation using a key from the **current** `controllerKeys` set. The `kid` is a DID URL: `did:dfos:<id>#<keyId>`.
215
+ 3. Append the signed JWS token to the chain.
216
+
217
+ The DID does not change. The resolved DID Document now reflects the new key sets.
218
+
219
+ ### 5.4 Deactivate (Delete)
220
+
221
+ Deactivating a `did:dfos` DID means appending a signed `delete` operation to the identity chain.
222
+
223
+ 1. Construct a delete operation payload with `type: "delete"` and `previousOperationCID` set to the CID of the current chain tip.
224
+ 2. Sign the operation using a key from the current `controllerKeys` set. The `kid` is a DID URL.
225
+ 3. Append the signed JWS token to the chain.
226
+
227
+ After deactivation:
228
+
229
+ - The chain is in a **terminal state**. No further operations can be appended.
230
+ - Resolution MUST return a DID Document with `deactivated: true` in the resolution metadata.
231
+ - The DID Document SHOULD contain an empty set of verification methods, as the identity no longer has active keys.
232
+
233
+ Deactivation is **permanent and irreversible**. The DID cannot be reactivated.
234
+
235
+ ---
236
+
237
+ ## 6. Security Considerations
238
+
239
+ ### 6.1 Self-Certifying Identifiers
240
+
241
+ `did:dfos` identifiers are derived from a cryptographic hash of the genesis operation content. This binding is verified during resolution (Section 5.2.1, step 2d). An attacker cannot present a forged chain for a given DID — the genesis content would hash to a different identifier.
242
+
243
+ ### 6.2 Key Compromise
244
+
245
+ If a controller key is compromised, the legitimate holder should immediately sign a key rotation (`update`) operation removing the compromised key. The protocol does not support key pre-rotation — there is no mechanism to pre-commit to a future key. The window of vulnerability exists between compromise and rotation.
246
+
247
+ ### 6.3 Equivocation
248
+
249
+ Because `did:dfos` has no global consensus layer, an identity holder could theoretically sign two different operations at the same chain position (same `previousOperationCID`, different payloads). This creates a **fork** — two valid chain branches.
250
+
251
+ Equivocation is **detectable**: a verifier who encounters two valid operations sharing a `previousOperationCID` can identify the conflict. Resolution policy for equivocation (reject both branches, prefer one, flag for human review) is an application-level concern and is deliberately outside the scope of this method specification.
252
+
253
+ In practice, equivocation requires the identity holder to act against themselves — no external party can extend an identity chain, since all operations must be signed by a current controller key.
254
+
255
+ ### 6.4 Transport Security
256
+
257
+ The `did:dfos` method does not mandate any specific transport security. Because resolution is verification-first (the chain is validated against the DID, not the source), transport-layer attacks (MITM, DNS hijacking) cannot produce a valid chain for a targeted DID. An attacker who intercepts a chain request can:
258
+
259
+ - **Withhold** the chain (denial of service) — the resolver gets no result
260
+ - **Serve a stale chain** — the resolver gets a valid but outdated DID Document
261
+ - **Serve a completely different chain** — the self-certification check fails, the resolver rejects it
262
+
263
+ An attacker **cannot** serve a modified or forged chain that passes the self-certification check.
264
+
265
+ ### 6.5 Denial of Service
266
+
267
+ A resolver that depends on a single source for chain retrieval is vulnerable to denial of service. Applications SHOULD support multiple chain sources and MAY cache verified chains locally to mitigate this.
268
+
269
+ ### 6.6 Cryptographic Agility
270
+
271
+ The current specification uses Ed25519 exclusively. The protocol does not currently support multiple signature algorithms. Future versions MAY introduce additional algorithms via new multicodec identifiers and verification method types. Implementations MUST reject operations signed with unrecognized algorithms.
272
+
273
+ ---
274
+
275
+ ## 7. Privacy Considerations
276
+
277
+ ### 7.1 Correlation
278
+
279
+ `did:dfos` identifiers are persistent and globally unique. Any content chain signed by a DID can be correlated to the same identity. Users who require unlinkability across contexts should use distinct identities (distinct identity chains and DIDs) for each context.
280
+
281
+ ### 7.2 Key Material
282
+
283
+ Identity chains contain only public keys. Private key material is never included in the chain and MUST NOT be transmitted during resolution.
284
+
285
+ ### 7.3 Chain History
286
+
287
+ The full identity chain is available to any resolver. This reveals the history of key rotations, including timestamps (`createdAt`). Applications that consider key rotation history sensitive should be aware that this metadata is inherently public as part of the chain.
288
+
289
+ ### 7.4 Herd Privacy
290
+
291
+ Because `did:dfos` resolution can happen through any transport (including local storage), a resolver does not necessarily reveal which DIDs it is interested in. However, when using a shared registry API, the registry operator can observe resolution patterns. Applications with strong privacy requirements SHOULD resolve chains through privacy-preserving transports or maintain local chain caches.
292
+
293
+ ---
294
+
295
+ ## 8. Reference Implementation
296
+
297
+ A complete reference implementation is available as the `@metalabel/dfos-protocol` npm package:
298
+
299
+ - **npm**: [@metalabel/dfos-protocol](https://www.npmjs.com/package/@metalabel/dfos-protocol)
300
+ - **Source**: [github.com/metalabel/dfos](https://github.com/metalabel/dfos)
301
+ - **Cross-language verification**: Go, Python, Rust, and Swift implementations verify the same deterministic test vectors
302
+
303
+ ---
304
+
305
+ ## 9. References
306
+
307
+ ### 9.1 Normative References
308
+
309
+ | Reference | URI |
310
+ | --------------------------- | --------------------------------------------------- |
311
+ | W3C DID Core 1.0 | https://www.w3.org/TR/did-core/ |
312
+ | W3C Multikey | https://www.w3.org/TR/controller-document/#multikey |
313
+ | RFC 2119 (Key Words) | https://www.rfc-editor.org/rfc/rfc2119 |
314
+ | RFC 7515 (JWS) | https://www.rfc-editor.org/rfc/rfc7515 |
315
+ | RFC 8032 (Ed25519) | https://www.rfc-editor.org/rfc/rfc8032 |
316
+ | DFOS Protocol Specification | https://protocol.dfos.com/spec |
317
+
318
+ ### 9.2 Informative References
319
+
320
+ | Reference | URI |
321
+ | ----------------------- | ------------------------------------------------------------------------------- |
322
+ | W3C DID Spec Registries | https://w3c.github.io/did-spec-registries/ |
323
+ | Multicodec Table | https://github.com/multiformats/multicodec |
324
+ | CIDv1 Specification | https://github.com/multiformats/cid |
325
+ | dag-cbor Codec | https://ipld.io/specs/codecs/dag-cbor/spec/ |
326
+ | DFOS Registry OpenAPI | https://github.com/metalabel/dfos/blob/main/packages/dfos-protocol/openapi.yaml |