What happens if the hosted server is compromised
A precise, attack-by-attack account of what a fully compromised PolicyVault server can and cannot do to your funds.
This page takes the worst honest case seriously: assume the PolicyVault hosted API server is completely compromised — an attacker has full control of it. What can they actually steal?
The short answer
Nothing, unilaterally. No key material exists on the server in any deployment mode. Every covenant transition requires a signature over the exact frozen transaction bytes, produced inside your own wallet, and Kaspa consensus independently enforces every covenant rule against whatever the server ultimately submits. A compromised server also cannot convert a login (authentication) signature into a spending signature — they use cryptographically distinct signing domains, verified against Kaspa's own reference implementation.
What a fully compromised server can do
- Lie to browsers — push a malicious frontend that misrepresents state or tries to trick you into signing something you didn't intend. This is the central residual risk, addressed below.
- Serve false state — display incorrect vault or request information. Bounded because reconciliation trusts only the Kaspa node's own chain proof, never the application's say-so; a lying app cannot make a false state "stick" once honest infrastructure is restored, because durable receipts and the chain itself remain the ground truth.
- Leak tenancy/application metadata — a real, bounded privacy issue (which vaults exist, labels, organization membership), but not a funds-authority issue.
- Refuse service — deny availability. Annoying, never a loss of funds, and never something that can be worked around by weakening a funds-safety guard.
- Try to get you to sign an attacker-shaped transaction — the actual attack surface worth taking seriously; see below.
Attack-by-attack: what actually stops each attempt
| A compromised server tries to… | What actually stops it |
|---|---|
| Replace the recipient on an agent spend | The covenant's Merkle-committed allowlist rejects any transaction paying an unlisted recipient, regardless of what the server built. |
| Increase the amount | The covenant's per-spend cap, budget, and conservation checks reject it — even with a completely genuine agent signature. |
| Inflate the fee | The covenant computes the actual fee from the transaction's real inputs/outputs and caps fee-reserve consumption independently. |
| Swap the agent | The agent's identity is bound into what the signature must match; a different key fails the covenant's own signature check. |
| Change the approver set or threshold | Requires the owner's actual signature over bytes containing the change — a server cannot forge it. |
| Replay or reuse a signed request | The bound predecessor UTXO is consumed exactly once by consensus; a duplicate submission is rejected. |
| Serve a stale or substituted vault/network | Config, request, manifest, and node network identity must all agree; address prefixes and wallet network binding are separately checked. |
| Trick the browser into signing different bytes than intended | The central residual risk. Your wallet renders its signing popup from the actual bytes it was given, independent of the page's own display; PolicyVault's own pre-sign review independently re-derives the same bytes and refuses to offer a signature action on any mismatch. See Local intent verification and What KasWare signs. |
The one honestly irreducible risk
A user who approves a wallet signing popup without reading it can still be defrauded by a fully compromised frontend — no software control can protect someone who signs without looking. This is the wallet-review trust anchor, and PolicyVault states it plainly rather than implying a false guarantee: read what your wallet shows you before you sign, especially recipient, amount, and fee.
See also: Non-custodial architecture, What the hosted server can and cannot do.