Skip to content

Security briefing

This page is the canonical operator-facing trust model for PiWalletSV. The companion app at app.dev.piwalletsv.com links here from its first-load disclaimer, its terms-of-service modal, and from the "Why is this safe?" affordances on the Send flow — there's one source of truth instead of a copy embedded in the app bundle that slowly drifts out of sync.

The complete disclosure / reporting policy lives in the project's SECURITY.md, which is embedded verbatim at the bottom of this page.

1. The companion website is static

  • There is no server. The companion is a stack of HTML, CSS and JavaScript files. Once your browser has downloaded them, everything runs locally.
  • Nothing about your wallet is sent back to the site. No login, no telemetry, no analytics, no "sync" anywhere. Paired-wallet metadata (xpub, fingerprint, label, derivation path, cached UTXO snapshots) lives in your browser's IndexedDB and stays there.
  • The only outbound calls the companion makes are to WhatsOnChain for UTXO discovery, Merkle proofs, and broadcasting signed transactions. Those are public-blockchain reads and writes — they do not leak your seed.
  • Losing the browser profile is not a loss of funds. The companion only holds public material; spending still requires the Pi (and ultimately your seed phrase).

2. The PIN protects an encrypted vault, not magic

  • The Pi's vault file (~/.piwallet/vault.bin) is AES-GCM encrypted. The key is derived from your PIN with scrypt, which is intentionally slow and memory-hard. That makes brute-forcing a long PIN very expensive — but it is not impossible.
  • PIN length matters. A 6-digit PIN has only a million combinations; a determined attacker with the vault file and a GPU farm can chew through that. Use a long PIN — ideally 12+ digits — if you treat your seed as a high-value secret.
  • Six wrong PIN attempts in a row wipe the vault from the Pi. This is a circuit breaker, not a guarantee: if someone copies vault.bin off the device they can retry forever offline. Your seed phrase backup is what protects you in that scenario.
  • The seed itself is never persisted. It only exists in transient memory long enough to derive the master xprv and is then zeroed.

3. Treat the device like the seed phrase itself

  • Keep the Pi in a vault, not a desk drawer. Anyone with extended physical access can copy the encrypted vault file and attack it offline at their leisure. There is no secure element, no tamper mesh, no anti-rollback fuse. It is a Raspberry Pi.
  • PiWalletSV is for cold storage, not daily transactions. It is designed for long-term, infrequent signing of larger amounts. If you need to move funds every day, use a hot wallet on a phone or laptop and keep PiWalletSV for the savings stack.
  • Your seed phrase is the source of truth, not the Pi. Back it up on something durable (steel plates, multiple geographic locations) and store it the way you would store the deed to a house. Losing the Pi is annoying; losing the seed is permanent.
  • Air-gap discipline still applies. Don't plug the Pi into the internet, don't type the seed into anything online, and don't let cameras or screen-recorders see the disclaimer-revealed phrase during initial setup or recovery.

Reporting a vulnerability

Found a security-relevant bug? Please report it privately first — the disclosure process is documented at the bottom of this page (the embedded SECURITY.md).


SECURITY.md (embedded)

Security Policy

Supported Versions

PiWalletSV is currently pre-release / alpha software. Only the main branch and the latest tagged release receive security fixes. There is no LTS commitment yet.

Version Supported
main (alpha) ✅
any pre-v0.1.0 ❌

Reporting a Vulnerability

If you believe you have found a security-relevant issue in PiWalletSV (any code in this repository, on the Pi signer, in the companion web app, or in the documented operational procedures), please report it privately before disclosing it publicly.

Preferred channel

GitHub private vulnerability reporting:

  1. Open https://github.com/<owner>/PiWallet/security/advisories/new (replace <owner> with the org / user this repo lives under).
  2. Fill in a clear title, a reproduction, the impact, and what versions / configurations are affected.
  3. We will respond on the advisory thread.

If you cannot use GitHub's private reporting:

  • Email: security@piwalletsv.invalid (placeholder — replace with your real address before publishing the v0.1 release).
  • PGP key: see docs/security/piwalletsv-disclosure.asc (placeholder; fingerprint will be published alongside the v0.1 release).

What to include

  • Affected component (Pi piwallet CLI, vault, envelope codec, companion proposal builder, broadcast path, …).
  • Reproduction steps. A failing test case in tests/ is ideal but not required.
  • Estimated severity / impact in your own words (we will independently triage).
  • Whether you have already disclosed this to anyone else.

What we'll do

  • Acknowledge receipt within 5 business days.
  • Triage within 14 days. If we cannot reproduce, we will ask you for more detail rather than silently close the report.
  • Coordinate a fix. We aim to ship a patch + advisory within 90 days of a confirmed report, sooner for critical issues.
  • Credit you in the published advisory (CVE if applicable), unless you ask to remain anonymous.

Out of scope

The following are not considered security vulnerabilities for this project at the alpha stage:

  • Bugs that require the user to type their seed phrase into something that has network access. The user instructions explicitly forbid this, and the disclaimer reiterates it.
  • Bugs in upstream dependencies (bsv-sdk, @bsv/sdk, @scure/bip32, @noble/hashes, cryptography, etc.) — report those upstream. If the bug affects PiWalletSV specifically, please mention us in your upstream report or open a follow-up advisory here.
  • Bugs in WhatsOnChain or any other third-party service this project consumes. Report those to the operator.
  • Issues that require physical possession of the Pi for arbitrary amounts of time. We rely on operational tamper-evidence (see the docs/security.md chapter — coming in v0.1) plus the PIN-attempts vault-wipe; we do not claim that a determined adversary with unlimited physical access cannot extract the encrypted vault file.

Public disclosure

Please give us a reasonable window to ship a fix before publishing details. Coordinated disclosure protects other PiWalletSV users.

Hardening Notes

Brief, non-exhaustive hardening notes for operators. The full security chapter will live in docs/security.md once mkdocs-material is set up.

  • The Pi should be air-gapped. Verify that Wi-Fi and Bluetooth are disabled (/boot/firmware/config.txt has dtoverlay=disable-wifi and dtoverlay=disable-bt). Do not plug in an Ethernet adapter.
  • Boot integrity: pin the SHA-256 of /boot/cmdline.txt, of the piwallet Python package, and of /etc/piwallet/version. Compare on each boot before unlocking the vault.
  • Vault file at ~/.piwallet/vault.bin: AES-GCM, scrypt-derived KEK from the user PIN, per-wallet random DEK. Six wrong PIN attempts in a row wipe the vault. The seed is never persisted; it lives only in transient memory long enough to derive the master xprv.
  • The companion app's IndexedDB store contains only public material (xpubs, fingerprints, cached UTXO snapshots). Loss of the companion browser profile is not a loss of funds.
  • All envelopes are versioned (v1); when we change the wire format we will increment the version byte and refuse to decode older envelopes from the trusted side.

Thank you for helping keep PiWalletSV safe.