The audit's most important finding was not a doc issue at all. In vaultSetBinding the identifier `origin` resolved to the WORKER GLOBAL self.origin rather than the intended value, so the dashboard's "Revoke app access" REBOUND the record to the calling page instead of clearing it -- the precise cross-origin adoption the binding guard exists to prevent, wearing the label of the button meant to prevent it. It typechecked because the DOM lib declares that global. I introduced this hours ago: a string replace intended for one call site silently matched two. Fixed, with the reasoning written where the next reader will hit it. Relay/account audit fixes: - Phrase recovery permanently tripped the rollback alarm. The mark is keyed by the everyday pubkey (unchanged by recovery) while recovery legitimately restarts at generation 0, and raiseHighWaterMark keeps the maximum -- so anyone who had ever rotated a password met "possibly revoked credentials" on EVERY later login, forever, with no way to clear it. The phrase is the master authority; it now resets the mark. - quorumMet counted TCP connections, not answers: a query timeout RESOLVED, so a connectable-but-silent relay counted as responding and every "not enough relays answered" guard was near-vacuous. Only EOSE is an answer now. - Relay responses were never checked against the address requested, so one junk event from one relay blocked registration, rotation, and recovery for every login name and password a user tried. Events must now match author, kind, and d-tag. Website honesty (the surface a stranger reads first, and the one that had drifted furthest from the spec): - docs.html and llms.txt still carried "private keys never leave the worker" -- false on its face, since the widget ships a reveal-nsec button. Both now state the same limit the README does. - "you revoke" became honest everywhere: removing a connection deletes the stored copy; spending authority is revoked at the wallet. - index.html dropped a pre-softening recovery claim, now says an account lives only while relays retain its capsule, and says "independently unaudited" out loud. - llms.txt gains the two warnings that were missing entirely: losing BOTH password and phrase is permanent, and removal is not revocation. - Stale headers: nwc-connections.md no longer claims "Not implemented", docs/README no longer says the authorization layer is unbuilt, the test count and spec version are current, and the demo domain points at bitlogin.network. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1
BitLogin Documentation
BitLogin is a static, relay-backed portable account protocol that gives users a familiar login name and password while preserving a user-controlled Nostr identity and independent phrase recovery.
This directory contains the core protocol specification, implementation notes, and experimental designs for expanding BitLogin into a portable account layer for compatible applications.
Core protocol
spec.md— canonical BitLogin protocol specificationsecond-factor.md— second-factor design notes
Portable account layer
These documents describe proposed capabilities that build on BitLogin's core identity and recovery model.
account-switching.md— multiple independent accounts on one device, fast switching, locking, logout, and account-aware signer behaviorportable-app-state.md— encrypted, user-owned application settings and lightweight state that follow the account across devicesportable-entitlements.md— discovery, verification, recovery, and presentation of purchases, licenses, memberships, and access rightsrelay-and-messaging-portability.md— relay-role management, DM inbox and outbox synchronization, sent-message recovery, and conversation reconstruction
Connection Vault
The Connection Vault stores portable application credentials outside the core
identity capsules as independently encrypted records. Its protocol layer
(records, key hierarchy, relay sync, migration, tiers) is implemented in
@bitlogin/core's src/vault/; the widget authorization layer shipped 2026-07-30 in REVEAL mode
(requestNwcConnection, offerNwcConnection, and a Wallet-connections
screen). Durable per-origin grants and a Connected-apps page are still to
come; see connection-vault.md §19 for the open limitations.
connection-vault.md— overall vault architecture, key hierarchy, relay storage, authorization, recovery, and deletion; §18 records the implementation-time decisions (tier model, sudo key)vault-ux.md— the agreed user-experience walkthroughs, serving as the authorization layer's acceptance criterianwc-connections.md— Nostr Wallet Connect credential profile (parser/exporter implemented insrc/vault/nwc.ts)s3c-format.md— portables3c1:format for S3-compatible storage connections
How the pieces fit together
BitLogin account
├── Identity and recovery
│ ├── Credential capsule
│ ├── Recovery capsule
│ └── Everyday Nostr identity
│
├── Accounts and sessions
│ └── Multiple-account switching
│
├── Communication
│ ├── Relay preferences
│ ├── DM inbox synchronization
│ ├── DM outbox and sent-message recovery
│ └── Conversation reconstruction
│
├── Portable application experience
│ ├── App settings
│ ├── Saved state
│ └── Per-app authorization
│
├── Ownership
│ ├── Purchases
│ ├── Licenses
│ ├── Memberships
│ └── Access entitlements
│
└── Connection Vault
├── NWC wallet connections
├── S3-compatible storage connections
└── Future service credentials
Status terminology
Documents use these labels:
- Implemented — available in the current codebase
- Partially implemented — some required primitives or flows exist, but the complete user-facing feature does not
- Experimental design — documented for review and future implementation; wire formats and APIs may change
Experimental documents are not part of the stable BitLogin protocol until their schemas, security properties, migrations, and test vectors are finalized.
Recommended product sequence
A practical development sequence is:
- Complete the core account and messaging foundations.
- Add independent multi-account sessions and switching.
- Add relay management, inbox synchronization, and sent-message recovery.
- Add portable application state and per-app permissions.
- Add entitlement discovery and a portable ownership library.
- Implement the Connection Vault and its NWC and S3 profiles.
- Move high-value authorization into stronger extension, native, or cross-origin execution boundaries.
Design principle
BitLogin should coordinate portable identity, state, ownership, and service access without becoming the centralized custodian of the user's identity, money, files, messages, or purchases.