<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>nSealr Blog</title><description>Release notes, research, tutorials, and news from nSealr.</description><link>https://nsealr.com/</link><item><title>Why a hardware signer for Nostr?</title><link>https://nsealr.com/blog/2026-05-15-why-hardware-signer-for-nostr/</link><guid isPermaLink="true">https://nsealr.com/blog/2026-05-15-why-hardware-signer-for-nostr/</guid><description>Where the private key actually lives is the only honest answer to &quot;is this account safe?&quot;. Hardware signers move that answer to a place where review and approval are explicit.</description><pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A Nostr account is just a keypair. Whoever holds the secret key can speak
as you, forever, with no recovery path. The interesting question is
therefore not “is Nostr secure?” — it is &lt;strong&gt;where does my key live, and
what does it take to use it?&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Soft signers leak the key into too many places&lt;/h2&gt;
&lt;p&gt;When the key lives in a browser extension or a copy-pasted &lt;code&gt;nsec&lt;/code&gt;, the
answer is “everywhere”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;inside every page the extension touches (NIP-07 reads),&lt;/li&gt;
&lt;li&gt;inside every relay-side bridge that asks for a signature (NIP-46
client),&lt;/li&gt;
&lt;li&gt;inside every backup file you forgot you made,&lt;/li&gt;
&lt;li&gt;inside whatever clipboard manager auto-archived the &lt;code&gt;nsec&lt;/code&gt; you typed
once.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of those places is a different attack surface, and most of them
sign without showing you what they are signing. A compromise of any one
of them is a permanent account takeover.&lt;/p&gt;
&lt;h2&gt;Hardware signers move the secret behind a boundary&lt;/h2&gt;
&lt;p&gt;A hardware signer changes the model from &lt;em&gt;“the key is everywhere a
program can read it”&lt;/em&gt; to &lt;em&gt;“the key is inside a device, and to use it
something physical has to happen”&lt;/em&gt;. nSealr makes that boundary explicit
through five solutions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;stateless QR vaults&lt;/strong&gt; (Raspberry/Pi, ESP32) — secret only in RAM for
the current session, no network at all, every signing decision happens
on a trusted display through a physical button;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;USB/NIP-46 signer&lt;/strong&gt; — daily-use connected device with a display,
reviewing every request before signing;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;smartcard&lt;/strong&gt; — persistent secret in a card, where the &lt;em&gt;external&lt;/em&gt;
reviewer acknowledges what is being signed before the APDU goes out;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;custom hardware wallet&lt;/strong&gt; — research line for purpose-built
persistent-secret hardware.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What that actually buys you&lt;/h2&gt;
&lt;p&gt;A hardware boundary is not magic. It does not eliminate trust, it
relocates it. The wins are concrete:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The host can lie, the device cannot be silently bypassed.&lt;/strong&gt; A
compromised companion or client can show you a fake event template,
but the device renders its own review screen bound to the exact bytes
it will sign through &amp;lt;code&amp;gt;approval_digest&amp;lt;/code&amp;gt;. Lying to the screen
would also corrupt the signature.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No automatic signing.&lt;/strong&gt; Every &amp;lt;code&amp;gt;sign_event&amp;lt;/code&amp;gt; requires a
physical approval gesture, distinct from navigation, connection, or
request receipt.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No accidental key extraction.&lt;/strong&gt; The signer exposes
&amp;lt;code&amp;gt;sign_event&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;export_key&amp;lt;/code&amp;gt;. The host never
sees the secret.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;What it does not yet buy you&lt;/h2&gt;
&lt;p&gt;This is pre-production research. &amp;lt;code&amp;gt;signing_disabled&amp;lt;/code&amp;gt; is the
default on every prototype firmware until camera, display, button,
provisioning, and secure-boot gates pass independently. See the
&lt;a href=&quot;/docs/security/trust-boundaries/&quot;&gt;trust boundaries&lt;/a&gt; and the per-solution maturity in
&lt;a href=&quot;/docs/signers/raspberry-qr/&quot;&gt;docs/signers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A hardware signer is not safer because the box is shiny. It is safer
because the trust boundary is documented, reviewable, and the same
across implementations through shared
&lt;a href=&quot;https://github.com/nSealr/specs&quot;&gt;&lt;code&gt;contract_id&lt;/code&gt;&lt;/a&gt;s in
&amp;lt;code&amp;gt;nSealr/specs&amp;lt;/code&amp;gt;.&lt;/p&gt;
&lt;p&gt;That is the whole point.&lt;/p&gt;
</content:encoded><category>research</category><category>nostr</category><category>hardware</category><category>threat-model</category></item><item><title>approval_digest: binding what you reviewed to what you sign</title><link>https://nsealr.com/blog/2026-05-15-approval-digest-bind-review-to-signature/</link><guid isPermaLink="true">https://nsealr.com/blog/2026-05-15-approval-digest-bind-review-to-signature/</guid><description>A hardware signer is only as honest as the link between the screen you read and the bytes the device puts a signature on. approval_digest is the contract that makes that link non-forgeable.</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A trusted display is necessary but not sufficient. If the firmware can
display screen A and sign payload B, the display is worth nothing.
nSealr closes that gap with one specific contract:
&amp;lt;code&amp;gt;approval_digest&amp;lt;/code&amp;gt;.&lt;/p&gt;
&lt;h2&gt;The contract&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;approval_digest&lt;/code&gt; is a deterministic hash over the &lt;strong&gt;exact canonical
material the user reviewed&lt;/strong&gt;: signer pubkey, event kind, &lt;code&gt;created_at&lt;/code&gt;,
the full unmodified content, the complete tag list (including detail
pages for long fields), the request id, and the review context.&lt;/p&gt;
&lt;p&gt;The local approval action — pressing a physical button, completing an
on-card acknowledgement — is bound to that digest. The signer refuses to
emit a signature whose underlying serialization does not reproduce the
same digest. Any drift between “what was shown” and “what gets signed”
fails closed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# companion, when verifying a signed response:
$ nsealr verify --request req.json --response resp.json
✓ event id matches BIP-340 signature
✓ approval_digest matches reviewed material
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the second line fails, the response is rejected even if the BIP-340
signature is mathematically valid. No display, no signature.&lt;/p&gt;
&lt;h2&gt;What it specifically prevents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Host-side template swap.&lt;/strong&gt; A compromised client cannot show you
benign metadata then sneak a different &lt;code&gt;kind&lt;/code&gt; or different tags into
the bytes the device signs — the digest would not match.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unicode look-alikes inside content.&lt;/strong&gt; Long content goes through the
review-detail-page contract; the digest covers the same canonical
bytes the user sees, with explicit &lt;code&gt;Unicode fallback&lt;/code&gt; for codepoints
the display cannot render.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Replay across contexts.&lt;/strong&gt; The digest includes the request id and
review context, so an approval gesture for request A cannot authorize
signing request B.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why it lives in the shared specs and not in each firmware&lt;/h2&gt;
&lt;p&gt;Every signer solution that claims trusted review uses the same
&lt;code&gt;approval-digest-v0&lt;/code&gt; contract from
&lt;a href=&quot;https://github.com/nSealr/specs&quot;&gt;&lt;code&gt;nSealr/specs&lt;/code&gt;&lt;/a&gt;. Raspberry/Pi
QR vault, ESP32 QR vault, ESP32 USB/NIP-46 signer, and (for displayful
hardware) the custom wallet line — they share the contract, so swapping
the hardware does not silently downgrade the safety story.&lt;/p&gt;
&lt;p&gt;Display-less solutions are an exception: a smartcard cannot bind a
review it cannot show. The smartcard line therefore depends on the
&lt;code&gt;external-review-acknowledgement-v0&lt;/code&gt; contract instead — an explicit
external reviewer takes responsibility for binding what was reviewed to
the APDU that gets sent.&lt;/p&gt;
&lt;h2&gt;Status today&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;approval_digest&lt;/code&gt; contract is &lt;strong&gt;implemented&lt;/strong&gt; on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Raspberry/Pi stateless QR vault,&lt;/li&gt;
&lt;li&gt;ESP32 stateless QR vault (host-core review flow),&lt;/li&gt;
&lt;li&gt;ESP32 USB/NIP-46 signer (disabled-signing development firmware).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is &lt;strong&gt;partial&lt;/strong&gt; on smartcard (acknowledgement plumbing under
development) and &lt;strong&gt;planned&lt;/strong&gt; on the custom hardware-wallet line. See
the &lt;a href=&quot;/docs/signers/raspberry-qr/&quot;&gt;feature matrix per solution&lt;/a&gt; for the
exact target/current status.&lt;/p&gt;
&lt;p&gt;The point of writing this down: when someone asks “what does the
hardware actually guarantee?” the answer is not “we promise” — the
answer is a &lt;code&gt;contract_id&lt;/code&gt; you can read, vectors you can run, and a
digest the device refuses to lie about.&lt;/p&gt;
</content:encoded><category>research</category><category>contracts</category><category>security</category><category>approval-digest</category></item></channel></rss>