@le-space/orbitdb-identity-provider-webauthn-did 0.3.1 → 0.4.0

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,205 @@
1
+ # Changes
2
+
3
+ ## Unreleased
4
+
5
+ ## 0.4.0
6
+
7
+ ### Breaking
8
+
9
+ - WebAuthn credentials now yield the authenticator's actual public key, so the
10
+ derived `did:key` **changes** for anyone who registered against 0.3.x or
11
+ earlier. Existing OrbitDB identities keyed on the old DID will not match, and
12
+ databases gated on it become unwritable under the new DID. `extractPublicKey()`
13
+ never took its intended path: `cbor-web` returns byte strings as views into
14
+ the enclosing buffer, so reading `credentialIdLength` through `authData.buffer`
15
+ without honouring `byteOffset` read bytes from inside `rpIdHash` and yielded
16
+ 43690 for every credential. The COSE slice was then empty, `cbor` threw
17
+ `Insufficient data`, and the `catch` silently returned a synthetic key derived
18
+ from `SHA-256(credentialId)`.
19
+
20
+ ### Fixed
21
+
22
+ - Keep the identity document stable across reloads. `signIdentity()` reuses the
23
+ proof it already produced instead of running a fresh WebAuthn assertion, which
24
+ changed `signatures.publicKey` — and therefore the content address of the
25
+ identity document — on every page load. Peers then dropped entries:
26
+ `verifiedIdentitiesCache` in `@orbitdb/core` is keyed on the deterministic
27
+ `signatures.id`, so two documents from one keystore collide on a single cache
28
+ entry and `isEqual()` rejects whichever was not verified first. The symptom was
29
+ a database replicating some entries and silently never receiving the rest.
30
+ - Remove the `timestamp` field from the proof envelope and the 24-hour expiry
31
+ check that read it. Both were wrong for a value embedded in content-addressed,
32
+ permanent history: the timestamp changed the document hash on every call, and
33
+ the expiry would have invalidated the identity behind every entry ever signed
34
+ under it. Compatible in both directions — proofs that still carry a timestamp
35
+ verify fine, and 0.3.1 verifying a proof without one computes `NaN`, which
36
+ fails its `> maxAge` test.
37
+ - Prefer `response.getPublicKey()` (WebAuthn L2) over parsing the attestation
38
+ object, and correct the parser: honour `byteOffset`, validate the AT flag,
39
+ bounds-check `credentialIdLength`, and decode only the first CBOR item so
40
+ trailing extension data (the ED flag, set when PRF is requested) no longer
41
+ throws. The synthetic fallback is now marked `synthetic: true`.
42
+ - Fix an ambiguous locator in `ed25519-keystore-did`: `getByLabel` matches
43
+ substrings, and the demo's worker toggle is labelled
44
+ "Use worker-backed Ed25519 keystore".
45
+
46
+ ### Added
47
+
48
+ - Two-peer OrbitDB replication tests: real libp2p over loopback TCP, Helia with
49
+ bitswap, gossipsub, two OrbitDB instances, driven by a software WebAuthn
50
+ authenticator with a real P-256 keypair, an incrementing signature counter and
51
+ randomised signatures. Covers identity-document stability across reloads,
52
+ replication of entries written before and after a reload, and that two devices
53
+ sharing a passkey keep distinct, independently valid identities.
54
+ - Attestation-parsing unit tests: credential ID lengths 16/20/32/64/128,
55
+ trailing extension data, missing AT flag, non-P-256 COSE keys and truncated
56
+ coordinates. 13 of the 14 fail against 0.3.1.
57
+
58
+ ### Changed
59
+
60
+ - CI now runs all eleven test files. Five never ran: `webauthn-unit`,
61
+ `webauthn-verification`, `standalone-toolkit`, `ed25519-keystore-did` and
62
+ `simple-encryption-integration`. `webauthn-unit` imports through Vite's `/@fs`
63
+ endpoint, which only the dev server exposes, so its step runs against `dev`
64
+ rather than the `preview` build CI otherwise uses.
65
+ - Publishing moves into CI. A `v*` tag runs the full suite and then publishes
66
+ via npm Trusted Publishing (OIDC), with provenance. A manual run defaults to a
67
+ check mode that verifies tag/version agreement and packaging without
68
+ publishing.
69
+ - `test:ci`, which `preversion` and `prepublishOnly` run, now points at the
70
+ Node-context suites via `playwright.node.config.js` — 32 tests in about ten
71
+ seconds. It previously ran `webauthn-verification` alone: five tests that check
72
+ regexes against hardcoded DID literals and one fully mocked database object,
73
+ none of which creates a credential, touches the keystore or opens an OrbitDB.
74
+ - Restore the `security-audit`, `package-validation` and `notify` jobs. The
75
+ enforced audit gate is `--prod --audit-level=critical`; auditing the full tree
76
+ at `moderate` reports 86 advisories from the helia and libp2p dev tree, and
77
+ even `--prod` reports 5 through `iso-web > iso-kv > conf > ajv`, so both wider
78
+ audits run informational until that chain is bumped.
79
+
80
+ ### Also shipping in this release
81
+
82
+ Entries that had accumulated under Unreleased since 0.3.1:
83
+
84
+ - Add `SECURITY.md` with vulnerability reporting and supported-version policy.
85
+ - Rename `changes.md` to `CHANGELOG.md` and include it in the published package.
86
+ - Add public TypeScript declarations for the root, standalone, verification,
87
+ and keystore package entrypoints.
88
+ - Add `docs/API.md` and expose `@le-space/orbitdb-identity-provider-webauthn-did/keystore`
89
+ as a typed package subpath.
90
+ - Remove the Vite node polyfill plugin from production dependencies, update
91
+ the varsig support stack to `iso-web@^3.1.2`, and verify
92
+ `npm audit --omit=dev` reports zero production advisories.
93
+ - Re-enable the CI lint step and verify `pnpm run lint` passes.
94
+ - Add shared public constants and catchable error classes for WebAuthn,
95
+ keystore, and varsig flows.
96
+ - Add root Prettier scripts, ignore rules, and a CI formatting check.
97
+ - Add `CODE_OF_CONDUCT.md` and include it in the published package.
98
+
99
+ ## 0.3.1
100
+
101
+ - Bump package metadata to `0.3.1` and create the clean release tag after
102
+ the post-`0.3.0` CI fixes landed.
103
+ - Update example lockfiles so all demos install successfully with
104
+ `pnpm install --frozen-lockfile`.
105
+ - Fix Playwright web server startup by passing Vite `preview`/`dev` arguments
106
+ directly, avoiding CI timeouts waiting for the wrong port.
107
+ - Update GitHub Actions to current action majors:
108
+ `actions/checkout@v7`, `pnpm/action-setup@v6`, `actions/setup-node@v6`,
109
+ and `actions/upload-artifact@v7`.
110
+ - Verify the release commit with GitHub Actions:
111
+ root frozen install, all three example frozen installs, all three example
112
+ builds, WebAuthn focused tests, logging E2E, integration E2E, varsig E2E,
113
+ encrypted-keystore tests, and Ed25519 encrypted-keystore E2E.
114
+ - Verify the package tarball with `npm pack --dry-run`; the package reports
115
+ `@le-space/orbitdb-identity-provider-webauthn-did@0.3.1` with 27 published
116
+ files.
117
+
118
+ ## 0.3.0
119
+
120
+ - Upgrade the OrbitDB stack to `@orbitdb/core@^4.0.0`.
121
+ - Upgrade Helia to `helia@^7.0.1` and add the current Helia service packages:
122
+ `@helia/libp2p`, `@helia/http`, and `@helia/bitswap`.
123
+ - Upgrade libp2p to `libp2p@^3.3.4` and the current scoped packages,
124
+ including `@libp2p/gossipsub@^16.0.3`, `@libp2p/identify@^4.1.8`,
125
+ `@libp2p/websockets@^10.1.15`, `@chainsafe/libp2p-noise@^17.0.0`,
126
+ and `@chainsafe/libp2p-yamux@^8.0.1`.
127
+ - Confirm the gossipsub stream-registry fix from
128
+ `libp2p/js-libp2p#3531` is included via `@libp2p/gossipsub@16.0.3`.
129
+ - Port all Svelte examples to the OrbitDB 4, Helia 7, and libp2p 3 stack:
130
+ `webauthn-todo-demo`, `ed25519-encrypted-keystore-demo`, and
131
+ `webauthn-varsig-demo`.
132
+ - Update example libp2p configuration for the v3 `connectionEncrypters`
133
+ option and current `withLibp2p`, `withHTTP`, and `withBitswap` Helia setup.
134
+ - Update OrbitDB identity and keystore integration for the current OrbitDB 4
135
+ public APIs, including keystore key generation/storage.
136
+ - Replace older dynamic codec/hash imports with static multiformats imports
137
+ where needed.
138
+ - Remove obsolete local OrbitDB patches.
139
+ - Clean up known Vite/polyfill build warnings in the examples.
140
+ - Fix varsig verification edge cases for replicated entries, mixed
141
+ worker/hardware verification, and Node relay default exports.
142
+
143
+ ## 0.2.10
144
+
145
+ - Release metadata update after varsig verification and worker/hardware
146
+ compatibility fixes.
147
+
148
+ ## 0.2.9
149
+
150
+ - Version metadata update after discoverable passkey recovery work.
151
+
152
+ ## 0.2.8
153
+
154
+ - Add discoverable passkey recovery flows.
155
+ - Add worker-backed keystore demo coverage and fix the worker keystore demo
156
+ build.
157
+ - Export varsig verification, identity storage, and
158
+ `wrapWithVarsigVerification`.
159
+ - Stabilize Chromium E2E/unit coverage and align Ed25519 keystore tests.
160
+ - Sync docs, format the codebase, and restrict CI Playwright runs to Chromium.
161
+
162
+ ## 0.2.6
163
+
164
+ - Release metadata update for the standalone compatibility series.
165
+
166
+ ## 0.2.5
167
+
168
+ - Add standalone compatibility fallback release.
169
+
170
+ ## 0.2.4
171
+
172
+ - Re-enable encrypted-keystore CI and stabilize demo checks.
173
+ - Sync pnpm lockfile with package dependencies.
174
+ - Run CI on pushes to all branches.
175
+ - Merge the standalone WebAuthn toolkit feature branch.
176
+
177
+ ## 0.2.3
178
+
179
+ - Add reusable standalone WebAuthn worker and varsig toolkit exports.
180
+ - Restore ucanto signer metadata and add issuance regression coverage.
181
+ - Stabilize WebAuthn unit harness and mock credentials.
182
+ - Finalize standalone toolkit integration and README updates.
183
+ - Refresh pnpm lockfile.
184
+
185
+ ## 0.2.2
186
+
187
+ - Ship patch-package in dependencies so postinstall works for consumers.
188
+
189
+ ## 0.2.1
190
+
191
+ - Add WebAuthn varsig demo E2E coverage and test-mode stubs for CI.
192
+ - Update CI to focus on Chromium-only runs and disable failing encrypted keystore tests.
193
+ - Add @libp2p/crypto dependency and update lockfile.
194
+ - Publish varsig demo build to Storacha and link in README.
195
+
196
+ ## 0.2.0
197
+
198
+ - Switch iso dependencies to the published `@le-space` fork and pin `@le-space/iso-did@2.1.2`.
199
+ - Restore unscoped `iso-web` from npm to satisfy `iso-did` runtime deps.
200
+ - Document forked iso packages used for WebAuthn varsig support.
201
+ - Clarify Varsig vs keystore-based DID paths and reference the example demos.
202
+
203
+ ## 0.1.0 (preview)
204
+
205
+ - Initial preview release with WebAuthn DID and varsig provider.
@@ -0,0 +1,52 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We are committed to making this project a welcoming, respectful, and
6
+ harassment-free space for everyone who contributes, reports issues, reviews
7
+ code, writes documentation, or participates in project discussions.
8
+
9
+ ## Expected Behavior
10
+
11
+ - Use welcoming and inclusive language.
12
+ - Be respectful of differing viewpoints and experience levels.
13
+ - Give and receive constructive feedback with care.
14
+ - Focus criticism on ideas, code, and project outcomes, not on people.
15
+ - Respect privacy, security boundaries, and responsible disclosure processes.
16
+
17
+ ## Unacceptable Behavior
18
+
19
+ Unacceptable behavior includes harassment, discriminatory language, personal
20
+ attacks, intimidation, unwanted attention, publishing private information
21
+ without consent, or any behavior that would reasonably make participation feel
22
+ unsafe or hostile.
23
+
24
+ Because this project touches identity, cryptography, WebAuthn, and local-first
25
+ security flows, do not pressure others to disclose private credentials, seeds,
26
+ keys, vulnerability details, or personal identity information in public
27
+ channels.
28
+
29
+ ## Reporting
30
+
31
+ If you experience or witness unacceptable behavior, please contact the project
32
+ maintainers through GitHub. For security-sensitive issues, follow the reporting
33
+ process in `SECURITY.md` instead of posting details publicly.
34
+
35
+ Reports should include enough context for maintainers to understand what
36
+ happened, while avoiding unnecessary disclosure of private information.
37
+ Maintainers will review reports in good faith and handle them as confidentially
38
+ as practical.
39
+
40
+ ## Enforcement
41
+
42
+ Maintainers may take action they consider appropriate, including clarification,
43
+ moderation, temporary limits on participation, removal from project spaces, or
44
+ permanent bans for repeated or severe violations.
45
+
46
+ Anyone asked to stop unacceptable behavior is expected to comply immediately.
47
+
48
+ ## Scope
49
+
50
+ This code of conduct applies in project spaces, including GitHub issues, pull
51
+ requests, discussions, documentation, examples, and any other official project
52
+ collaboration channels.
package/README.md CHANGED
@@ -8,6 +8,7 @@ This package provides:
8
8
 
9
9
  - Two WebAuthn-based OrbitDB identity providers.
10
10
  - A standalone WebAuthn toolkit export (`@le-space/orbitdb-identity-provider-webauthn-did/standalone`) for reuse outside OrbitDB identity wiring.
11
+ - A keystore helper export (`@le-space/orbitdb-identity-provider-webauthn-did/keystore`) for encrypted keystore utilities and provider wiring.
11
12
  - **WebAuthn-Varsig**: No insecure OrbitDB keystore at all. Each entry is signed by WebAuthn (varsig envelope), so keys never leave the authenticator, one Passkey (WebAuthn) prompt per write.
12
13
  - **Keystore-based DID**: Generates an Ed25519/secp256k1 keystore keypair for OrbitDB signing in browser memory. When `encryptKeystore` is enabled, the private key is encrypted with AES-GCM and only rehydrated in memory after a WebAuthn unlock (PRF, largeBlob, or hmac-secret).
13
14
 
@@ -262,9 +263,10 @@ sequenceDiagram
262
263
 
263
264
  Svelte demos:
264
265
 
265
- - `examples/webauthn-todo-demo/` - WebAuthn DID (no keystore signing; identity-only). Includes discoverable credential diagnostics, `Use Existing Passkey`, `largeBlob` identity metadata recovery, and local fallback recovery.
266
- - `examples/ed25519-encrypted-keystore-demo/` - Ed25519 keystore DID; keystore encrypted at rest with WebAuthn (PRF when available, otherwise largeBlob/hmac-secret).
267
- - `examples/webauthn-varsig-demo/` - Varsig provider with passkey signing for each entry. Includes discoverable credential diagnostics, `Use Existing Passkey`, `largeBlob` varsig metadata recovery, and local fallback recovery. Live demo: https://dweb.link/ipfs/bafybeib6tpwiby7pik67ufb3lxpr3j4by2l7r3ov3zzk6hjbzjzgsvckhy
266
+ - Live demo directory: https://le-space.github.io/orbitdb-identity-provider-webauthn-did/
267
+ - `examples/ed25519-encrypted-keystore-demo/` - Ed25519 keystore DID; keystore encrypted at rest with WebAuthn (PRF when available, otherwise largeBlob/hmac-secret). Live demo: https://le-space.github.io/orbitdb-identity-provider-webauthn-did/ed25519-encrypted-keystore-demo/
268
+ - `examples/webauthn-varsig-demo/` - Varsig provider with passkey signing for each entry. Includes discoverable credential diagnostics, `Use Existing Passkey`, `largeBlob` varsig metadata recovery, and local fallback recovery. Live demo: https://le-space.github.io/orbitdb-identity-provider-webauthn-did/webauthn-varsig-demo/
269
+ - `examples/webauthn-todo-demo/` - WebAuthn DID (no keystore signing; identity-only). Includes discoverable credential diagnostics, `Use Existing Passkey`, `largeBlob` identity metadata recovery, and local fallback recovery. Live demo: https://le-space.github.io/orbitdb-identity-provider-webauthn-did/webauthn-todo-demo/
268
270
 
269
271
  Scripted examples:
270
272
 
@@ -278,12 +280,15 @@ Mermaid sequences for scripts:
278
280
 
279
281
  ## Documentation
280
282
 
283
+ - `docs/API.md`
281
284
  - `docs/ED25519-KEYSTORE-DID.md`
282
285
  - `docs/WEBAUTHN-ENCRYPTED-KEYSTORE-INTEGRATION.md`
283
286
  - `docs/WEBAUTHN-DID-AND-ORBITDB-IDENTITY.md`
284
287
  - `docs/STANDALONE-API-PLAN.md`
285
288
  - `docs/EXAMPLE-SEQUENCES.md`
286
289
  - `docs/E2E-TEST-SUMMARY.md`
290
+ - `SECURITY.md`
291
+ - `CODE_OF_CONDUCT.md`
287
292
 
288
293
  ## Identity Recovery Summary
289
294
 
package/SECURITY.md ADDED
@@ -0,0 +1,88 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Security fixes are provided for the current `0.3.x` release line.
6
+
7
+ | Version | Supported |
8
+ | ------- | --------- |
9
+ | 0.3.x | Yes |
10
+ | < 0.3 | No |
11
+
12
+ ## Reporting a Vulnerability
13
+
14
+ Please do not report security vulnerabilities through public GitHub issues.
15
+
16
+ Report suspected vulnerabilities by email:
17
+
18
+ security@le-space.de
19
+
20
+ Please include as much detail as you can:
21
+
22
+ - affected package version, commit, or tag
23
+ - affected browser, runtime, or operating system
24
+ - steps to reproduce
25
+ - expected and actual behavior
26
+ - proof of concept, logs, screenshots, or traces if available
27
+ - your assessment of impact
28
+
29
+ We aim to acknowledge reports within 48 hours and coordinate fixes before
30
+ public disclosure.
31
+
32
+ ## Security Model
33
+
34
+ This package provides WebAuthn-based identity providers and helper APIs for
35
+ OrbitDB. It handles sensitive identity material and should be reviewed in the
36
+ context of the application that embeds it.
37
+
38
+ ### Varsig Provider
39
+
40
+ The varsig provider is the preferred security model when available. Entry
41
+ signing is performed through WebAuthn assertions, so the private key remains
42
+ inside the authenticator and is not exported to application memory.
43
+
44
+ ### Keystore Provider
45
+
46
+ The keystore provider can generate browser-side Ed25519 or secp256k1 keys for
47
+ OrbitDB signing. When encrypted keystore mode is enabled, key material is
48
+ encrypted at rest with AES-GCM and unlocked through WebAuthn-supported secret
49
+ recovery mechanisms such as PRF, largeBlob, or hmac-secret.
50
+
51
+ During an unlocked session, private key material may exist in browser memory.
52
+ Applications with stricter requirements should prefer the varsig provider or
53
+ keep keystore sessions short.
54
+
55
+ ### Identity Metadata Recovery
56
+
57
+ Discoverable passkeys can identify a credential during authentication, but
58
+ WebAuthn assertions do not reliably return the public key after registration.
59
+ This package therefore needs identity metadata persistence for recovery.
60
+
61
+ The example applications use:
62
+
63
+ - WebAuthn largeBlob metadata as the preferred recovery path
64
+ - browser localStorage as a fallback when largeBlob is unavailable or empty
65
+
66
+ Applications should treat localStorage metadata as recoverability metadata, not
67
+ as a replacement for authenticator-backed key protection.
68
+
69
+ ## Operational Guidance
70
+
71
+ - Serve production applications over HTTPS.
72
+ - Configure WebAuthn relying party IDs and origins deliberately.
73
+ - Prefer the varsig provider for hardware-backed signing on every write.
74
+ - Enable encrypted keystore mode if using the keystore provider in production.
75
+ - Keep dependencies updated and review `npm audit --omit=dev` output before
76
+ production deployments.
77
+ - Do not log private keys, PRF seeds, decrypted keystore archives, or raw secret
78
+ key material.
79
+ - Review browser storage behavior for your deployment, especially if using
80
+ localStorage fallback recovery.
81
+
82
+ ## Disclosure Process
83
+
84
+ 1. A vulnerability report is received privately.
85
+ 2. We acknowledge the report and investigate impact.
86
+ 3. We prepare and test a fix.
87
+ 4. We publish a patched release.
88
+ 5. We coordinate public disclosure with the reporter where appropriate.