feat(chat): sign user messages with device ed25519 keypair - #35
Merged
Conversation
Every user bubble in the chat now carries a small "Signed · FING ERP"
chip. The chip is a visible bridge to the on-device identity: clicking
it opens a details panel with pubkey, signature, timestamp, active
team_id, and a live re-verification banner. Assistant replies remain
unsigned — the QVAC bridge does not sign, so the demo does not fake it.
- demo/chat-signing.js: WebCrypto ed25519 keypair, persisted in
IndexedDB as a non-extractable CryptoKey; pubkey mirrored to
localStorage for display. Deterministic canonical payload
({alg, ts, team_id, text}) matches the on-wire shape of
src/identity/keypair.js. MutationObserver decorates every user
bubble; assistant bubbles are ignored.
- demo/styles.css: badge chip + 320px popover styles, ok/fail states
- demo/index.html: script + preload wired, ?v=33 cache-bust
- demo/sw.js: CACHE_VERSION → v33, chat-signing.js precached
Graceful degradation: browsers without ed25519 (older Safari) render
a muted "Unsigned" chip instead of failing the send.
Verified end-to-end: pubkey/sig hex lengths (64/128), verify(same)=true,
verify(tampered)=false, verify(wrong-pub)=false, badge attaches to user
bubbles only, panel shows verified label.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every user bubble in the chat now carries a small Signed · FING ERP chip. Clicking opens a 320px panel with pubkey / signature / timestamp / team_id and a live re-verification banner (green tick or red fail).
Keypair is generated once via WebCrypto ed25519, stored in IndexedDB as a non-extractable
CryptoKey, and the raw 32-byte public key is mirrored tolocalStoragefor display. Signed envelope matches the on-wire shape ofsrc/identity/keypair.js:{ "alg": "ed25519", "ts": "…", "team_id": "…", "text": "…" }Assistant replies stay unsigned — the QVAC bridge does not sign, so the demo does not fake it.
Graceful degradation: older browsers without ed25519 render a muted "Unsigned" chip. Verified end-to-end: verify(same)=true, verify(tampered)=false, verify(wrong-pub)=false, badges attach to user bubbles only, panel shows verified label.