• Wallet secrets and merchant records are encrypted locally; StellarKey has no server-side key store or recovery operator.
  • Every signature still depends on a trustworthy device, browser, origin, build, and review by the person authorizing it.
  • Security maintenance is ongoing and the source is public, but no software (including StellarKey) can guarantee absolute security.

Security principles

  • Minimize custody: do not build an application backend that can receive keys.
  • Encrypt by default: keep sensitive local records encrypted at rest.
  • Make authority visible: show the full transaction before signing.
  • Fail closed: reject malformed storage, unsupported signing paths, unsafe callbacks, and network mismatches.
  • Keep recovery independent: a password and tested backup remain available when optional passkey unlock is used.
  • Make releases inspectable: publish source identity, checksums, dependency inventory, and disclosure instructions.

Threat model and limits

The local encryption model is designed to reduce exposure when someone reads a locked browser profile, exported encrypted backup, or encrypted merchant database without the unlock material. Transaction review, endpoint validation, and strict parsing are designed to reduce mistakes and unsafe data crossing a trust boundary. Browser security headers are designed to reduce injection, framing, and unnecessary device access.

These controls cannot protect an already-unlocked wallet on a compromised device; a malicious browser, extension, operating system, keyboard, clipboard, screen recorder, DNS response, hosting origin, dependency, or release artifact; phishing on a lookalike origin; a weak or exposed password; a compromised recovery backup; coerced device verification; or an unsafe transaction the user approves. They also cannot control Stellar consensus, Horizon or RPC operators, asset issuers, market-data services, Trezor infrastructure, or counterparties.

No design review, automated test suite, encryption algorithm, hardware wallet, passkey, or open-source process removes every vulnerability. StellarKey cannot guarantee absolute security. Use a dedicated, maintained device where practical, keep recovery material offline, verify the exact origin and release, and test new workflows with small amounts.

Vault and local data

A new wallet uses a random 256-bit master key. The browser derives a wrapping key from the wallet password using PBKDF2-HMAC-SHA-256 with a unique random salt and 600,000 iterations, then protects the master key with authenticated AES-GCM encryption. Recovery phrases, imported signing keys, contacts, and private notes are encrypted with the master key. Merchant data uses a separate random encryption key wrapped by that master key and is committed transactionally in IndexedDB.

AES-GCM detects an incorrect key or modified ciphertext; it does not make a weak password strong or protect plaintext after a successful unlock. Signing secrets are opened only for the scoped action that needs them, and in-memory byte buffers are cleared where the platform allows. JavaScript and browser memory management cannot guarantee that every temporary copy is immediately or forensically erased.

Locking removes the active vault and merchant keys from application state. It does not encrypt the account index needed to render the lock screen: each account's public key, label, and creation time remain readable to someone who can inspect the locked browser profile. A public key is enough to correlate that account's full public ledger history. Treat access to the browser profile as financially sensitive even though it does not grant signing authority.

Auto-lock reduces an unattended session window but is not a substitute for locking the device. Full backups use the encrypted version 2 envelope; only the current encrypted wallet format is accepted. A backup is useful only if it is stored safely and has been tested.

Signing and transaction safety

StellarKey validates addresses, network identity, amounts, assets, issuers, and supported operations before constructing a transaction. The review surface shows the complete operation list, source, destination, asset identity, amount, memo, fee, and network before a software or hardware signer is invoked. Processing controls prevent accidental duplicate submission while a request is active.

After broadcast, the app exposes the transaction hash and tracks a pending transaction to a confirmed success or failure where possible. Merchant crypto charges additionally match the destination, network, asset, amount, memo, and confirmation state reported by Horizon. Temporary endpoint failure remains possible, so an interface status is not a substitute for checking the authoritative ledger before releasing high-value goods or treating a payment as final.

Private Payments status

Production-hosted builds publish one exact hash-pinned XLM/USDC development pool on Testnet; Mainnet independently refuses Private Payments. The checked-in evidence records its identity, locally selected Wasm hash, deployment and post-registry checkpoints, and read-back configuration; it does not include a deployment transaction hash or an independent on-chain executable-hash check. The single-party development key passes compatibility verification against the circuit and pinned Powers-of-Tau transcript, but that does not make its setup ceremony-secure. Anyone retaining the setup secret could forge proofs. A public multi-party ceremony, independent review, and complete browser payment evidence are required before any real-value or Mainnet promotion. Private payments, explained covers the design and limits.

The implementation derives deployment-bound keys only inside an unlocked supported software-account callback, isolates proof work in a worker, encrypts owned records and pending actions locally, reviews exact contract operations and restoration keys before signing, and reconciles against a canonical on-chain archive. Payments submit directly from the user's account through the selected Stellar RPC. These controls do not cure untrusted proving material and do not hide the submitting account, timing, shared-pool activity, proof, commitments, nullifiers, ciphertext, or network metadata.

Passkeys and hardware wallets

Passkey unlock

On a compatible HTTPS origin, WebAuthn PRF derives an origin-bound secret after the platform authenticator requires user verification. StellarKey uses that result to unwrap the existing local vault master key. It does not receive a biometric template, export the authenticator’s private key, replace Stellar signing authority, or turn the wallet into a passkey smart account. The local passkey wrapper is not included in backups, so retain the wallet password and recovery material.

Trezor

When Trezor is selected, StellarKey sends the supported transaction description through the official Trezor Connect flow and asks the device to sign. Confirm the address and every transaction detail on the hardware display; a compromised browser can still try to present an unsafe request. StellarKey never asks for the Trezor recovery phrase. Trezor Connect is a separately licensed production dependency, loaded lazily for the optional hardware UI, and its services remain an external trust boundary.

Release 1.0.4 uses @trezor/connect-web@9.7.3, the pinned version reviewed for this release. The installed production audit reports ten low-severity vulnerable packages associated with one elliptic advisory through Trezor's Bitcoin/UTXO and browser-crypto dependencies, with no high or critical findings after a reviewed TOML parser override. That override does not rewrite the nested SDK's prebundled browser parser or Trezor's remote popup core; the embedded parser remains vulnerable and the remote core's deployed dependency status has not been verified here. The elliptic advisory lists no patched version and concerns ECDSA signing conditions; it does not establish exposure of Stellar Ed25519 keys. High and critical production advisories remain release-blocking. Audit results do not replace Trezor redistribution authorization, registered-origin approval, or physical-device checks.

Web and release security

Production must be served over HTTPS. The generated host policy applies a build-specific Content Security Policy, blocks framing and MIME sniffing, restricts browser permissions, separates the origin, and permits cross-origin popups needed by Trezor. The app has no dynamic API routes, server sessions, analytics script, advertising script, or cloud database. Its service worker caches the versioned static application shell and verified public proving artifacts, never wallet records or network account responses.

The CSP keeps script-src hash-bound with no unsafe-inline or JavaScript unsafe-eval. It permits wasm-unsafe-eval only so the browser can compile the local, hash-verified WebAssembly used to create Private Payments proofs; this does not enable JavaScript string evaluation. Its connect-src https: wss: and image policy are deliberately broad because user-configurable Stellar endpoints and issuer-chosen metadata or logo hosts cannot be enumerated at build time. This is an outbound-connection privacy boundary, not permission for a remote response to execute as script.

Every production build exposes the full source commit and a machine-readable release manifest. Published releases are expected to include artifact checksums and a CycloneDX software bill of materials. Compare those records with the public source. A matching identifier improves traceability but cannot alone prove that the host, build environment, or device is safe.

Ongoing security maintenance

Security is treated as an ongoing engineering process, not a one-time claim. Maintainers review security-sensitive changes and dependencies as part of release work; run type, unit, integration, browser, accessibility, static-export, dependency-audit, and bundle checks; keep unsafe or incomplete flows disabled; and investigate credible vulnerability reports. Release checks cover desktop Chromium plus iPhone and iPad WebKit profiles, while physical Trezor and installed-device behavior remain manual release checks.

The process is informed by secure-development and verification practices such as NIST’s Secure Software Development Framework and OWASP’s Application Security Verification Standard. This is a statement of direction, not a claim of NIST or OWASP certification, formal compliance, independent audit, penetration-test coverage, or freedom from defects. Public source enables independent inspection, but publication alone is not an audit.

For release 1.0.4, the maintainer explicitly deferred physical iPhone/iPad, VoiceOver/NVDA, passkey and Trezor checks, including Trezor redistribution and registered-origin sign-off. These checks are unperformed or unconfirmed, not passed. Automated browser profiles do not replace them. This release exception does not grant third-party license rights or approve real-value Private Payments.

Responsible disclosure

Report a reproducible issue privately before publishing details. Include the affected route, release or commit, browser and operating-system version, expected behavior, observed behavior, and the smallest safe reproduction. We will acknowledge and triage credible reports, but cannot promise a reward or response deadline unless a separate program says so.

Good-faith testing must use accounts and data you own or are explicitly authorized to use, avoid privacy violations and disruption, stop if sensitive data is encountered, and allow a reasonable opportunity to investigate before disclosure. This policy does not authorize testing Stellar infrastructure, hosting providers, Trezor services, asset issuers, or any other third party. The machine-readable disclosure contact is published at /.well-known/security.txt in the format defined for security.txt.

Supported release

Security fixes target the latest published build, currently StellarKey release 1.0.4, commit 3098ed84293d5da04320311e6696279ff633666b. Confirm an issue against that release when practical and name any older affected release in your report.

Older builds should be treated as unsupported unless a release notice explicitly says otherwise. A support label does not guarantee that an undiscovered vulnerability is absent or that a fix will be available on a particular schedule.

Report securely

Never include a recovery phrase, secret key, wallet password, passkey output, decrypted or encrypted wallet backup, merchant archive, customer record, or real unredacted transaction data in a report. Use a fresh testnet wallet and redact public addresses when they are not essential to the reproduction.

The button below constructs the dedicated security contact only after you activate it, which keeps the complete address out of static page markup and deters basic harvesting.

What is actually protecting you

These are not marketing numbers. Each one is read straight out of the source, and you can check them yourself in the files named beside each figure.

Vault cipherAES-256-GCM
Key derivationPBKDF2-SHA-256, 600,000 iterations
Merchant recordsXChaCha20-Poly1305, 24-byte nonce
Auto-lock15 minutes idle, adjustable
Staff PIN5 wrong tries per open app window, then 30 seconds
Hardware signingTrezor, key never enters the browser

The staff PIN throttle is client-side state in the open app window and resets after a reload or close. At roughly ten attempts per minute it is a local till deterrent, not high-security authentication. The PIN cannot sign a Stellar transaction or move money; the unlocked wallet and reviewed signing flow remain separate.

Everything that leaves this device

There is no StellarKey application server, but direct destinations vary with the network, endpoints, assets, and optional features you choose. These are the request categories and what they can reveal.

goes towhat forwhat it learns
Selected Horizon / RPC endpointOperational balances, fees, simulation, merchant monitoring, and transaction submissionYour IP, requested public accounts, and signed transactions. Never your secret key.
SDF public HorizonWallet activity and historical account operations, regardless of the custom endpoint settingYour IP, requested public account, cursor, and timing.
CoinGeckoOptional market and fiat display pricesYour IP, timing, and requested asset identifiers.
Issuer-chosen metadata / logo hostsOptional stellar.toml details and asset artworkYour IP and the asset being viewed. Loading an issuer logo can therefore disclose interest in that asset to the issuer or its image host.
FriendbotOnly when requesting testnet fundingYour IP and testnet public address.
Trezor ConnectOnly after choosing a Trezor actionConnection metadata and the supported unsigned transaction presented for device approval.
External explorerOnly after opening an explorer linkThe public account or transaction identifier you chose.

No analytics, advertising, application telemetry, or StellarKey API receives these requests. Use the browser network inspector to see the exact destinations for your configuration.

What is kept here, and how to remove it

All of it lives in this browser, on this device. Reset Wallet in Settings deletes every one of these keys, and once it is gone we cannot help you get it back, because we never had it.

Your vaultPassword-wrapped. Holds encrypted signing authority.
Merchant recordsOrders, catalogue, customers, shifts. Encrypted.
ContactsAES-GCM encrypted and available only while unlocked.
Locked account indexPublic key, label, and creation time remain readable locally.
PreferencesNetwork, currency, auto-lock, privacy mode.

How the page itself is locked down

A wallet in a browser is only as safe as the page it runs in. These headers ship with every response, and you can read them in the response yourself.

Content-Security-Policy
Application scripts require this origin and an exact build-time hash; inline and JavaScript string evaluation are disabled. Hash-verified Private Payments proof code may compile as WebAssembly. Outbound HTTPS and images remain broad for configurable endpoints and issuer metadata.
frame-ancestors: none
The app cannot be put inside someone else’s page and used to trick you.
Permissions-Policy
Camera, microphone, location and the payment API are switched off at the browser level.
Strict-Transport-Security
A year of enforced HTTPS, so the app cannot be served to you over a plain connection.
X-Content-Type-Options
The browser will not second-guess a file’s type, which closes off a whole class of trickery.
Referrer-Policy
Links out do not carry the page you came from.

What this protects you from, and what it does not

Anyone who only tells you the first half is selling something. Both halves are true and you should read the second one twice.

Designed to reduce

  • Custody risk: StellarKey does not hold your signing keys or route public payments through its own account
  • Exposure from a central merchant database: operational records stay encrypted in your browser
  • Exposure from a locked profile: sensitive vault contents require the unlock material
  • Accidental authorization: transactions and fees are presented for review before signing
  • Platform charges: StellarKey has no subscription or processing fee; network and third-party costs remain

It cannot protect you from

  • A stolen unlocked device, or a password written on the machine
  • Malware on the computer you are using, or a hostile browser extension
  • You approving a transaction you did not read properly
  • Losing your recovery phrase, which nobody can give back to you
  • A mistake in this software, which is why the source is public

Public Stellar balances and activity remain readable by anyone. Issued assets may retain issuer authorization, freeze or clawback controls. Local encryption and self-custody do not remove those boundaries or guarantee protection against theft.

Five things worth doing today

Self-custody puts the work on you. It is not much work, and it is all front-loaded.

  1. Write the recovery phrase on paperNot in a photo, not in a password manager you also unlock on this device.
  2. Test it before you rely on itRestore into a second browser and confirm the address matches. Ten minutes now.
  3. Export an encrypted backupYour records live in this browser. If it is cleared they are gone, and the phrase does not bring them back.
  4. Keep the lock short if you trade in publicA till on a counter is a device strangers stand next to.
  5. Check the address before every first paymentThe wallet flags an address you have never sent to. Read that flag.