From 9408fef4843ee8500ea608ee1af8576e9a9a7f34 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Jul 2026 16:54:55 +0000 Subject: [PATCH] Add MIT license, CONTRIBUTING, and SECURITY docs for open-sourcing Preparing to open the project up beyond this repo's own use: - LICENSE: MIT, and a "license": "MIT" field on the root and all three workspace package.json files. - CONTRIBUTING.md: dev workflow, the mock-relay testing setup (most sandboxes/CI have no route to public Nostr relays, and registration needs a 2-of-N ack quorum so a single mock relay always fails), the spec-first process for anything touching wire format or crypto (docs/spec.md is canonical; speculative ideas go in their own doc, not the spec), and stricter expectations for crypto/key-handling changes. - SECURITY.md: private vulnerability disclosure via GitHub's advisory flow rather than public issues, given this handles private keys and password-derived secrets client-side; states current audit status plainly (none yet). - README: short "Contributing" section pointing at all three. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01GWJbXXhvTx9wo59jSz57J6 --- CONTRIBUTING.md | 106 +++++++++++++++++++++++++++++++++++ LICENSE | 21 +++++++ README.md | 7 +++ SECURITY.md | 39 +++++++++++++ package.json | 1 + packages/core/package.json | 1 + packages/demo/package.json | 1 + packages/widget/package.json | 1 + 8 files changed, 177 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 SECURITY.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c6dd240 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,106 @@ +# Contributing to BitLogin + +Thanks for taking a look. BitLogin is a small monorepo — read this before your +first PR, it'll save you a round trip. + +## Layout + +See `README.md` for the full package breakdown. In short: `packages/core` is +the framework-free protocol implementation (crypto, capsules, Nostr relay +I/O, account flows), `packages/widget` is the `` custom +element and its crypto Web Worker, and `packages/demo` is the static site +that consumes both. + +## Getting started + +```bash +npm install +npm test # runs @bitlogin/core's vitest suite +npm run typecheck # tsc -b for core, tsc --noEmit for widget +npm run build # builds core, then widget +``` + +If you edit `packages/core` and a downstream typecheck seems stale (TS +happily reports success against old `.d.ts` output), delete the incremental +build cache and rebuild: + +```bash +rm -f packages/core/tsconfig.tsbuildinfo packages/widget/tsconfig.tsbuildinfo +npm run build -w @bitlogin/core && npm run typecheck -w @bitlogin/widget +``` + +## Testing without a real Nostr relay + +Most sandboxes (and CI) have no route to public Nostr relays. Protocol-level +tests instead run against an in-memory mock relay, +`packages/core/src/test-support/mockRelay.ts` — a minimal WebSocket server +implementing enough of NIP-01 (EVENT/REQ/CLOSE/OK, addressable/replaceable +replacement semantics) for real round trips: register → publish → login from +a "clean device," phrase recovery, password rotation, relay-loss → replica +repair, and so on. New account-flow tests should follow the existing pattern +in `packages/core/src/account/account.e2e.test.ts` — spin up 2-3 `MockRelay` +instances in `beforeEach`, close them in `afterEach` (registration/login +require a 2-of-N acknowledgement quorum by default, so a single mock relay +will fail every write). + +For widget/UI changes, there's no equivalent automated browser suite yet — +verify manually against the built widget in a real browser (Chromium is +fine) pointed at a locally started `MockRelay` instance via the +`vault-relays`/`discovery-relays` attributes, since real relays aren't +reachable from most contributor sandboxes either. + +## The spec is canonical + +`docs/spec.md` (currently v0.3) is the source of truth for the protocol +itself — wire formats, KDF parameters, capsule structure, derivation paths, +threat model. Code comments reference it by section (`§11.2`, `§17.4`, …). + +If a change affects anything the spec describes — a new capsule field, a +derivation change, a new recovery path — update `docs/spec.md` in the same +PR, not after the fact. Purely additive widget/UI features that don't touch +wire format or crypto (a new screen, a UX fix) don't need a spec change. +Speculative/future ideas that aren't decided yet belong in a separate doc +(see `docs/second-factor.md` and `docs/future-recovery-options.md` for the +pattern: proposal + pros/cons, explicitly marked as not implemented) rather +than in the spec itself. + +## Working on cryptography or key handling + +This code touches private keys and password-derived secrets, so changes +here get held to a higher bar than typical UI work: + +- Prefer the audited libraries already in use (`@noble/curves`, + `@noble/hashes`, `@noble/ciphers`, `@scure/bip39`, native WebCrypto, + `hash-wasm`) over adding a new dependency or hand-rolled primitive. +- Private keys and passwords must never be logged, persisted in plaintext, + or held in memory longer than the operation needs (`§11.10`). In the + widget, they must never leave the crypto Web Worker — the main thread + only ever sees public keys, signed events, and ciphertext. +- If you're changing KDF parameters, encryption modes, or derivation paths, + explain why in the PR description, not just what — these are exactly the + kind of change that's cheap to review now and expensive to unwind once + real accounts depend on it. +- Add or update test vectors (`packages/core/src/crypto/crypto.test.ts`) for + any primitive-level change. + +## Reporting a security vulnerability + +Don't open a public issue for a suspected vulnerability in the crypto, +capsule handling, or key custody — see `SECURITY.md` for the private +disclosure process. + +## Style + +- TypeScript strict mode; `packages/core` stays framework- and DOM-free so + it can run in Node, a browser, or a worker. +- Comments explain *why*, not *what* — skip a comment if the code's already + clear without it. +- Match the existing code's structure rather than introducing a new + abstraction for something only used once. + +## Pull requests + +- Run `npm test` and `npm run typecheck` before opening a PR; both must + pass. +- Keep the description focused on *why*, not a restatement of the diff. +- Small, focused PRs review faster than one that bundles unrelated changes. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3e92703 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 PR0M3TH3AN + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 2bd3ffa..56dd1ed 100644 --- a/README.md +++ b/README.md @@ -142,3 +142,10 @@ HKDF, ScalarExpand, AES-256-GCM, JCS, fixed padding buckets). - Passphrases are generated from the EFF long Diceware wordlist (`diceware-wordlist-en-eff`), matching the spec's ~12.9-bits/word, six-word/~77-bit default (§9.2). + +## Contributing + +MIT licensed — see `LICENSE`. See `CONTRIBUTING.md` for the dev workflow, +mock-relay testing (no route to public relays in most sandboxes/CI), and +the spec-first process for anything touching wire format or crypto. Found +a security issue? See `SECURITY.md` rather than opening a public issue. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..9ec5325 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,39 @@ +# Security Policy + +BitLogin handles private keys and password-derived secrets client-side — +security issues here can mean account takeover, not just a bug. + +## Reporting a vulnerability + +Please do not open a public GitHub issue for a suspected vulnerability. + +Instead, use GitHub's private reporting flow: go to this repo's **Security** +tab → **Report a vulnerability**. This opens a private advisory visible only +to maintainers until a fix is ready, so details aren't public before users +can update. + +Include, if you can: +- What's affected (crypto primitive, capsule format, key handling, a + specific derivation) and why it's exploitable. +- A minimal reproduction or proof of concept. +- Anything you already tried in `docs/spec.md`'s threat model that this + falls outside of. + +## Scope + +In scope: anything in `packages/core` (crypto, capsule construction/parsing, +Nostr relay I/O, account flows) and `packages/widget` (the crypto Web +Worker, the `window.nostr` provider, key custody boundaries between the +worker and the main thread). + +Out of scope: the demo site's own UI/branding bugs that don't touch account +security — file those as normal public issues instead. + +## Status + +This project has not yet had an independent third-party security audit — +see the README's "What's implemented" section for the current verification +status (protocol-level test suite plus manual real-browser verification). +Treat that as part of the threat model when reporting: we'd rather hear +about a real issue than have it wait for a formal audit that hasn't happened +yet. diff --git a/package.json b/package.json index b7666ac..0597f25 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "bitlogin-monorepo", "version": "0.1.0", "private": true, + "license": "MIT", "description": "BitLogin — static, relay-backed portable Nostr account protocol and embeddable login widget", "workspaces": [ "packages/core", diff --git a/packages/core/package.json b/packages/core/package.json index 1ba6a7b..54d7b2b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -2,6 +2,7 @@ "name": "@bitlogin/core", "version": "0.1.0", "private": true, + "license": "MIT", "type": "module", "description": "BitLogin protocol core: crypto, capsules, Nostr relay I/O, account flows. Framework- and DOM-free.", "main": "./dist/index.js", diff --git a/packages/demo/package.json b/packages/demo/package.json index cb21d54..ff98ca7 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -2,6 +2,7 @@ "name": "@bitlogin/demo", "version": "0.1.0", "private": true, + "license": "MIT", "type": "module", "description": "BitLogin marketing/landing site, integration docs, and account manager — a plain static site consuming @bitlogin/widget via a