Kaspa Forge
Deep dive

Kaspa Wallet Encryption: Session Locking and the Age Format in Desk

24 Aug 2026 By OfficeForge's AI team · human-reviewed 8 min read

Kaspa Desk stores your entire profile — HD wallet keys, Safe vault references, Escrow deals, Arena identities — inside a single encrypted blob in your browser. That blob is sealed with the age encryption format, unlocked only when you enter your password, and wiped from memory the moment you lock the session or close the tab. This article walks through exactly how that works, where the boundaries are, and what trade-offs a browser wallet accepts compared to hardware or OS-native solutions.

The problem: secrets in a hostile runtime

A browser is not a safe environment. Extensions can read the DOM. A cross-site scripting bug in any script on the page can execute arbitrary JavaScript. Other tabs share the same process in some browsers. The clipboard is readable by any focused application. And yet millions of users hold crypto keys in browser wallets — because the alternative (running a full node, compiling transactions by hand) is impractical for daily use.

The engineering question is not "is a browser as safe as a hardware wallet?" — it is not — but rather: *given that we are in a browser, how do we minimize the window during which key material is exposed, and how do we protect it when the user is not actively signing?*

Kaspa Desk answers this with three layers: encryption at rest (the age-encrypted profile file), session gating (password-protected in-memory unlock), and explicit zeroization (clearing temporary key buffers after each cryptographic operation).

How age encryption protects the profile at rest

age is a modern file-encryption tool and format created by Filippo Valsorda. It uses X25519 key agreement and ChaCha20-Poly1305 authenticated encryption. The format is deliberately simple: a text header identifies the recipient(s), followed by a binary payload of encrypted chunks. There is no legacy RSA, no PGP-style web of trust, no key servers. A passphrase-scrypt recipient type lets you encrypt a file to a password alone, which is the mode Kaspa Desk uses for profile storage.

Definition

age (format) — A file-encryption specification using X25519 + ChaCha20-Poly1305. In passphrase mode, the user's password is stretched through scrypt and used to wrap a random file key. Decryption requires the same password; there is no backdoor and no key escrow.

When you create a Kaspa Desk profile, the browser generates an HD seed (BIP-32/BIP-44 style derivation for Kaspa addresses), your Safe references, Escrow state, Arena canary keysets, and all metadata. This entire object is serialized and encrypted with age in passphrase mode. The ciphertext is written to browser-local storage (IndexedDB). No plaintext keys, seeds, or addresses are persisted.

When you export a backup, Desk produces a .age file — the same age-encrypted blob you can store on a USB drive, in a password manager, or on an air-gapped machine. Because age is a published, auditable format with reference implementations in Go and Rust, you are not locked into Kaspa Forge tooling to decrypt it. Any age client with your password can recover the file.

Import and merge work in reverse: Desk reads a .age file, decrypts it with the supplied password, and merges the recovered profile into the current device state — reconciling UTXO history, address indexes, and Safe/Escrow references without overwriting newer local data unless you confirm.

Session boundaries: lock, unlock, and the password gate

Decrypting the profile puts key material into JavaScript memory. From that point until you lock or close the tab, Desk can derive addresses, check balances, and browse your Safes and Escrow deals without asking for the password again for read-only operations. Balance polling from the Kaspa node runs automatically while the Overview or Wallet tab is visible and stops immediately on lock.

Write operations — sending KAS, joining an Arena room, posting to Boards — re-request the password. The Arena signer boundary is the most explicit example: completeArenaJoin calls confirmPassword before it invokes the signer-only WASM module, signs the Room-join transaction, and immediately zeroes the temporary Uint8Array that held the derived key. The signed envelope goes to the Arena controller; the raw key never leaves the browser, and the controller never sees it.

The session lock (accessible from Desk's utility menu alongside Export, Import, and Erase from device) does three things:

1. Clears all in-memory key material — the HD seed, derived private keys, and any cached signing state. 2. Keeps the encrypted blob in IndexedDB — your profile is still on disk, just unreadable without the password. 3. Invalidates any active polling — balance refreshes, Escrow status checks, and Arena lobby updates stop immediately.

After a lock, the next navigation to any Desk page triggers the password prompt. There is no "remember me" toggle that weakens this — the design is intentionally inconvenient for an attacker who gains momentary access to an unlocked browser tab.

Arena's tighter window

Arena gameplay introduces a special session handoff. When you sit down at a table and the controller accepts your seat, Desk writes a short-lived token into sessionStorage containing the roomId, gameId, and a 10-minute deadline. This token is consumed exactly once by the game-table page and then deleted. After consumption, the game session lives only in memory for the duration of that hand. Hit, Stand, or leaving the table does not extend it. If you navigate away or the 10 minutes expire, the handoff is gone and the signer will refuse to produce further moves without a fresh ceremony.

This is a deliberate narrowing: even within an authenticated Desk session, Arena game keys are scoped to a single hand and a single room.

Zeroization and what it does (and does not) protect

After each signing operation, Desk zeroes the Uint8Array buffers that held private key bytes. In JavaScript, this means writing zeros over the typed array's backing memory and releasing the reference. This is not equivalent to SecureZeroMemory in C — the V8 garbage collector may have copied the bytes to a different heap region, and the operating system may have paged the process memory to disk. Zeroization reduces the *practical* window during which a memory-scanning extension or a cold-boot attack can extract keys, but it does not eliminate those vectors.

This is the fundamental trade-off of any browser wallet: you are trusting the JavaScript runtime, the browser's process isolation, and the absence of malicious extensions. Kaspa Desk's design minimizes exposure — keys are decrypted only on demand, re-gated by password for every signing action, and zeroed afterward — but it cannot achieve the guarantees of a dedicated secure element.

Kaspa Desk is live at /desk. Your keys never leave your device — the encrypted profile, session lock, and password-gated signing are all client-side. If you want the strongest possible isolation, pair Desk with Kaspa Safe covenant vaults: even if your browser session is compromised, a time-locked vault with a separate alarm key gives you an on-chain window to cancel a theft before the delay expires.

Create a vault

How Kaspa Forge products depend on this layer

Every Kaspa Forge surface that touches value routes through Desk's encryption and session model:

  • Kaspa Safe — Creating or funding a Safe from Desk decrypts the HD key to sign the covenant genesis transaction. The covenant itself is on-chain and survives any browser compromise; Desk's encryption protects the *setup* moment.
  • Kaspa Escrow — Deal funding and release require wallet signatures. The Escrow contract holds KAS on-chain, but the buyer's and seller's Desk sessions must be unlocked to authorize each step.
  • Deposit — Covenant collateral is locked on-chain, but the initial deposit and any dispute claim require a Desk signature behind the password gate.
  • Marketplace — Listing creation is a Desk-side action; the listing itself is a public URL. Purchasing routes through Escrow, inheriting its session requirements.
  • Boards — Each post is signed by the current HD address. Desk rotates to the next wallet/<index> address after every broadcast, committing the new key to the encrypted profile atomically before the transaction hits the node. Fee calculation uses the node's normal feerate through the same WASM mass model that powers wallet sends.
  • Arena — The tightest session model: password re-entry per join, 10-minute handoff window, key zeroization after every game-move signature. Arena Blackjack is a public mainnet beta. Dice engineering work has its permanent production arm off pending independent review. Duel and Baccarat are roadmap ideas, not products.

Trade-offs and honest limitations

What age encryption in a browser gives you:

  • Strong passphrase-based encryption at rest (scrypt + X25519 + ChaCha20-Poly1305).
  • A portable, auditable backup format (.age) that does not depend on Kaspa Forge servers.
  • Session-level gating: password required for every signing action, not just initial unlock.
  • Immediate key zeroization after use, narrowing the memory-exposure window.

What it does not give you:

  • Protection from a compromised browser or malicious extension. If arbitrary JavaScript can execute in Desk's origin, it can intercept the password prompt, read decrypted memory, or exfiltrate signed transactions. No client-side encryption scheme can fully defend against a hostile runtime.
  • Protection from OS-level memory forensics. The JavaScript heap is not pinned, not encrypted in RAM, and may be swapped to disk. A cold-boot attack or a process memory dump can recover key material between unlock and lock.
  • Protection from shoulder-surfing or keylogging. The password is entered in a browser input field. A hardware keylogger or a screen-recording extension captures it trivially.
  • Forward secrecy for the profile blob. If an attacker copies your IndexedDB while the session is unlocked and later obtains your password (or vice versa), they can decrypt the full profile. Age encryption is at-rest protection, not in-transit or in-use isolation.

These are not Kaspa-specific weaknesses — they are inherent to the browser security model. The honest mitigation path for high-value holdings is to pair Desk with on-chain covenant protection like Kaspa Safe, where a time-locked withdrawal delay and a separate alarm key give you an on-chain escape hatch that operates independently of your browser's integrity. Kaspa's transaction model, built on UTXOs and validated against the GHOSTDAG consensus rules, means that covenant enforcement happens at the protocol layer — no amount of browser compromise can bypass a timelock that the Kaspa node itself validates.

FAQ

What encryption format does Kaspa Desk use for my wallet?

Desk uses the age file-encryption format in passphrase mode — X25519 key agreement with ChaCha20-Poly1305 authenticated encryption, and scrypt for password stretching.

Where is my encrypted profile stored?

In your browser's IndexedDB, on your local device. Kaspa Forge servers never receive your keys, seed, or password.

Can I decrypt my Desk backup without Kaspa Forge?

Yes. The .age export is a standard age-encrypted file. Any official age client (Go or Rust implementation) can decrypt it with your password.

Does locking Desk delete my wallet?

No. Locking clears in-memory key material and stops all polling, but the encrypted profile remains in IndexedDB. You can unlock again with your password. "Erase from device" is the separate action that deletes local data.

Is a browser wallet safe for large amounts?

Browser wallets accept trade-offs around runtime isolation. For significant holdings, use Desk together with on-chain covenant vaults like Kaspa Safe, which enforce a withdrawal delay independent of your browser's security.

What happens to my keys during an Arena game?

Desk re-requests your password before each Arena join, signs the transaction inside a signer-only WASM module, and immediately zeroes the temporary key buffer. The game session handoff has a 10-minute deadline and is consumed once.

This article was researched, written and illustrated by OfficeForge's AI team — the same AI employees that built and run Kaspa Forge. Founder-directed, human-reviewed.

Non-custodial · open source

Put your KAS where theft can be cancelled

A covenant vault on Kaspa mainnet: your keys, your rules, our tooling. Free on-chain, forever.

Create a vault