How Kaspa Forge protects your private keys
Kaspa Forge is non-custodial: private keys are generated, decrypted and used to sign inside your browser. The primary Desk profile is encrypted locally with your password. Nothing is copied to the Sync server unless you explicitly enable Forge Sync for convenience — and even then the server receives only a separately encrypted, signed blob it cannot read.
The short answer
Your readable keys stay in the browser. At rest, the profile is password-encrypted. Transactions are signed locally. Forge Sync is off by default; when enabled with your consent, it uploads only a double-encrypted safe projection and signed metadata.
Sync: Safe projection → age → AES-256-GCM → Ed25519-signed ciphertext → mirror server
1. The profile is encrypted before it reaches storage
The Desk keeps one Profile v3 containing the wallet, master seed, derivation counters and the working records for vaults, deals, listings, chats and transaction history. Before it is written to browser localStorage, the profile is serialized and encrypted by the Kaspa Forge WASM core using the standard age passphrase format.
Encryption happens before persistence: when an older plaintext profile is migrated, the encrypted profile is written first and legacy plaintext storage is removed afterwards. The password is not sent to Kaspa Forge and cannot be reset by support.
2. Unlocking is a temporary browser session
When you unlock the Desk, WASM decrypts the age ciphertext locally. The readable profile is held by a DOM-free session module in an in-memory closure; it is not placed in React state, global application state or a server session. The tab keeps the password in its own sessionStorage only so navigation between Kaspa Forge pages does not ask again immediately.
- Per-tab boundary. The unlock session is not shared with another browser tab and disappears when the tab closes.
- 15-minute idle lock. Inactivity clears the readable profile, password and tab session. The Lock button does the same immediately.
- Password re-confirmation. Sending funds, funding a Safe or deal, exporting or importing keys and other sensitive actions ask for the password again, with the amount and destination shown where applicable.
- Local signing. Transaction builders and signing functions run in browser WASM. The server receives a completed signed transaction for broadcast, not the private key used to sign it.
3. Not every private key is allowed in the same place
The safer default separates convenience keys from independent protection keys. Shared alarm-key storage is available as an explicit convenience trade-off, but Forge Sync still excludes protection keys from every uploaded projection.
The master seed derives future working keys locally using domain-separated paths. That is why an early independent key-file backup can rediscover later entities. A separate-storage alarm key is independent of the seed. An alarm key kept in the full profile still remains deliberately excluded from Forge Sync.
4. How encrypted Forge Sync works
Forge Sync is optional, manual and off by default. The Desk starts it only after you open Settings, choose Enable Sync, confirm the password and accept a clear consent message. There is no silent upload and no background sync. After opt-in, you press Sync when you want profile copies to exchange changes.
- Build a safe projection. The browser copies the working profile without mutating the local original, then recursively removes alarm_sk, heir_sk and arbiter_sk. A fail-closed gate rejects the upload if any forbidden private field remains.
- Encrypt with the Desk password. The safe projection becomes an age-encrypted armored blob using the current device password — the same local protection as the key file.
- Derive separate Sync credentials. WASM uses domain-separated HMAC-SHA512 from the original wallet anchor to derive a profile ID, a 256-bit Sync secret and a separate Ed25519 authentication seed. Copies made before Forge Sync derive the same identity, and receive-address rotation does not change the anchor. The raw wallet key never leaves the browser and never signs the API request.
- Encrypt a second time. WebCrypto wraps the age blob with AES-256-GCM using a fresh 96-bit nonce, authenticated metadata and a 128-bit authentication tag.
- Sign and chain the version. The browser hashes the ciphertext with SHA-256, links it to the previous version and signs the manifest with the separate Ed25519 Sync key.
- Upload only ciphertext. The mirror service accepts a new version only if the signature, hash and compare-and-swap version chain are valid. It cannot decrypt the outer AES layer or the inner age layer.
- Verify before merge. On download, the browser checks the signature, actual blob hash, previous-version link and its local checkpoint before decrypting. Rollbacks, forks, missing history and tampering are rejected. Divergent local and remote profiles require an explicit merge; nothing silently overwrites the device.
Consent is part of the security boundary
Without your Enable Sync action, the encrypted profile remains local. With consent, the server stores an unreadable mirror only to make your own profile copies easier to keep in step.
5. What the Sync server receives — and what it does not
API reads and writes are signed with the dedicated Sync key and include fresh nonces and timestamps to resist replay. The service keeps a bounded version history so the browser can verify continuity. These controls protect integrity and rollback detection; confidentiality comes from the two client-side encryption layers.
6. Recovery rules and honest limits
- Forge Sync is not an independent backup. Keep an offline .age export and its password separately. A new empty browser cannot find or decrypt the mirror from the password alone.
- Forge Sync never transfers a vault alarm key. This also applies when you chose to keep that key in the shared encrypted profile. The Safe can sync to another device, but you cannot cancel a withdrawal on that device until you import a full .age copy exported from the device where the Safe was created (or provide the separate alarm card). Export a fresh copy after creating such a Safe.
- Copies must use the same Desk password. If a remote age snapshot was encrypted under a different password, the Desk refuses it and leaves local data unchanged.
- Device-level revoke is not available in this beta. Copies of one profile share Sync credentials. A lost device that held a recoverable profile is a key-security incident; Sync cannot remotely erase or lock it.
- Browser security still matters. Malware, a malicious extension, a keylogger or injected code running while the Desk is unlocked may read what the legitimate page can read. Encryption at rest does not make a compromised active device safe.
- Phishing bypasses good cryptography. Enter the Desk password only on kaspaforge.org. Kaspa Forge support will never ask for the password, seed, private key or complete key file.
- No password reset exists. We cannot recover a forgotten password because we do not hold it or a decryption key. Test your offline recovery before storing meaningful funds.
Practical key-safety checklist
- Use a unique, strong Desk password and store it separately from the .age file.
- Export the key file, then test an import or the offline decryptor before funding.
- For separate storage, keep each Safe alarm card apart from the profile. For shared storage, export a fresh full .age copy after creating the Safe; Forge Sync will not carry its alarm key.
- Enable Forge Sync only on devices you control; press Sync manually when you want continuity.
- Lock the Desk or close the tab when finished, and keep the browser and operating system updated.
Frequently asked questions
Can Kaspa Forge read my private keys?
No. Readable keys and the password stay in the browser. The normal platform receives public data and signed transactions. If you explicitly enable Forge Sync, its separate server receives only a signed, double-encrypted safe projection and does not receive either decryption secret.
Is Forge Sync automatic?
No. It is off by default and has no background sync. You unlock the Desk, confirm the password, accept the consent message and manually press Enable or Sync. This is a convenience feature for your own profile copies, not a hidden account backup.
Why encrypt twice during Sync?
The inner age layer preserves the same password-protected profile format used locally and in exports. The outer AES-256-GCM layer uses a separate domain-derived Sync secret and authenticates each version's context. The server has neither secret, while signed manifests protect integrity and history.
Does Forge Sync replace my key file?
No. Keep the offline .age backup. It is portable, independently recoverable and does not depend on the Sync service. It is also the only way to move an alarm key stored in the full profile to another device: Forge Sync strips that key before upload. A password by itself is not enough to discover the encrypted mirror on a brand-new empty device.
Verify the implementation
Kaspa Forge is open source. You can inspect the browser session, age wrapper, mirror projection, AES-GCM/Ed25519 protocol and server code in the public repository. For covenant hashes, test coverage, known limitations and vulnerability reporting, see the separate Security Center.
Next: the Desk and master key file · offline recovery · how Kaspa Safe protects funds