Podkey 0.0.8: general-signer signing, refreshed docs, popup fit, key icons#23
Merged
jjohare merged 4 commits intoJun 16, 2026
Conversation
…igner)
handleSignEvent gated auto-signing on `trusted && autoSign && isSolidAuth`,
so a trusted origin only signed kind-27235 (Solid auth) silently and
re-prompted for every other event kind. A normal Nostr client — the forum
publishes kind 0 / 10002 / 22242 on every load — therefore raised three
approval popups on each page load, making Podkey unusable as a single
general-purpose signer.
Align signing with the trust model already used by GET_PUBLIC_KEY and
nip44.{encrypt,decrypt}: a trusted origin is sufficient to skip the prompt
(decrypting DMs is strictly more sensitive than signing, and is already
silent for trusted origins). An untrusted origin still ALWAYS prompts, and
approving it establishes revocable trust — no silent first-use.
let shouldSign = trusted && autoSign && isSolidAuth;
-> let shouldSign = trusted;
Tests updated to the general-signer contract (133 pass, lint clean).
Co-Authored-By: jjohare <github@thedreamlab.uk>
…ey icons - README/USAGE/CHANGELOG: rewrite to match the current capability and security model (session-only key, per-origin consent, trusted-origin signing, NIP-98 with fresh nonce + body/URL binding, honest window.nostr surface). UK English. - popup: cap the trusted-sites list and tighten section spacing so the Export / GitHub footer stays within the browser popup height instead of scrolling off; widen to 400px. - icons: add 16/48/128px key icons (icons/icon.svg master) and wire them into manifest icons + action.default_icon so the toolbar shows the Podkey key. Co-Authored-By: jjohare <github@thedreamlab.uk>
PR JavaScriptSolidServer#22's hardening stored the private key only in chrome.storage.session (in-memory), so it was wiped on every browser restart — getPublicKey() then threw the non-intuitive "No keypair found" and the user had to re-import their nsec each time. That is "no at-rest persistence", not "encryption at rest". Add a real encrypted-at-rest vault: - src/vault.js: AES-256-GCM ciphertext in chrome.storage.local, key wrapped by scrypt(passphrase) (N=2^16, r=8, p=1; params sealed in the blob for future upgrade). Pure encrypt/decrypt split from the storage I/O so the crypto is unit-tested off-platform. Wrong passphrase / tamper fail closed via the GCM tag. - Session stays the hot cache: on unlock the decrypted key is held in chrome.storage.session for fast signing; a browser restart clears it and the user re-unlocks. The raw key never touches disk. - background.js: generate/import now take a passphrase and seal the vault; new UNLOCK_VAULT / LOCK_VAULT; GET_KEYPAIR_STATUS reports none|locked|unlocked. A locked vault on getPublicKey/sign/nip44 opens the unlock popup and throws a clear "Podkey is locked — unlock and try again" instead of "No keypair found". - popup: set-passphrase step on generate, passphrase fields on import, an unlock screen (with forget-key/start-over), and a Lock action. Pill reads "Unlocked". Tests: 8 vault crypto tests (round-trip, wrong passphrase, tamper, validation, salt/iv freshness). Full suite 141 pass; eslint src/ clean. Co-Authored-By: jjohare <github@thedreamlab.uk>
Collaborator
Author
|
Added commit PR #22's hardening stored the private key only in
8 new vault crypto tests; full suite 141 pass, |
- PRIVACY.md: repo-hosted privacy policy (local signer; key encrypted at rest; no servers/accounts/telemetry; per-permission rationale incl. <all_urls>). Doubles as the Chrome Web Store privacy disclosure basis. - README/USAGE/CHANGELOG: bring the security model up to date with the encrypted vault (was "session-only"), document the passphrase + unlock/lock/forget flow, bump version 0.0.7 -> 0.0.8, test count 133 -> 141, add vault.js to the file map, and add a "Where Podkey fits" section positioning it against existing NIP-07 signers, the did:nostr ecosystem (github.com/topics/did-nostr), and Solid (solidproject.org) — extends + consolidates rather than reinvents. - site/: a polished, self-contained docs landing (index.html) + hosted privacy page (privacy.html) for a clean Web Store privacy URL. - gh-pages.yml: complete the migration off the legacy gh-pages branch — assemble the docs site + test page and deploy via actions/deploy-pages (the proper GitHub Actions Pages workflow), triggered on site/test-page changes. Co-Authored-By: jjohare <github@thedreamlab.uk>
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.
Brings Podkey to a coherent 0.0.8: the general-signer fix, documentation that matches the current capability and security model, a popup that fits the browser surface, and real extension icons.
Signing — trusted origins sign without a prompt
handleSignEventonly auto-signed kind 27235 (Solid auth) for a trusted origin; every other kind re-prompted on each request. A normal client publishes kind 0 / 10002 / 22242 on each page load, so users saw three approval popups every time. Signing now honours trust likegetPublicKeyandnip44.{encrypt,decrypt}already do:A trusted origin signs any kind with no prompt. An untrusted origin always prompts, and approving it grants revocable per-origin trust. No silent first-use.
Docs
README, USAGE and CHANGELOG rewritten to describe the current behaviour: session-only key storage, per-origin consent, trusted-origin signing, NIP-98 with a fresh nonce and body/URL binding, and the
getPublicKey/signEvent/nip44provider surface. UK English; the removedgetRelaysstub is no longer documented.Popup
The trusted-sites list is capped and section spacing tightened so the Export / GitHub footer stays inside the browser popup height instead of scrolling off; width is 400px.
Icons
16 / 48 / 128px key icons (
icons/icon.svgmaster) wired intomanifest.iconsandaction.default_icon, so the toolbar shows the Podkey key.Verification
npm run build✓ ·npm test→ 133 pass / 0 fail ✓ ·npm run lint→ 0 errors ✓. CI uploads the sideloadablepodkey-extensionzip on every run.🤖 Generated by Claude Code