Wallet Isolation
How Sigil Wallet separates agent reasoning from key management and transaction signing.
Sigil Wallet enforces strict separation between the agent's "brain" and its ability to sign transactions. This is the foundation of Sigil Wallet's security model.
The Three Layers
Implementation Rules
These rules are enforced at the code level — they are not guidelines, they are hard boundaries:
-
The Agent Layer (
/core/src/agent/) produces intents (tool calls). It cannot importkeytaror access@solana/web3.jsKeypair objects. -
The Guardrails Layer (
/core/src/lib/Guardrails.ts) evaluates intents against the guardrails configuration. It returnspassedorfailed. It has no access to keys. -
The Wallet Layer (
/core/src/wallet/) is the only module permitted to:- Import and call
keytar - Retrieve private keys from the OS Keychain
- Build, sign, and submit transactions
- Import and call
Key Storage
Private keys are stored using keytar, which delegates to the operating system's native credential store:
| OS | Backend |
|---|---|
| macOS | Keychain Access |
| Linux | libsecret (GNOME Keyring / KWallet) |
| Windows | Credential Manager |
Keys are never stored in:
- Environment variables
- Configuration files
- The SQLite database
- Application code or memory (except during active signing)
Kill Switch Behavior
When sigil kill is invoked:
config.kill_switch = trueis set in SQLitesystem:killedis broadcast over WebSocket to all clients- All held Keypair references are dropped from application memory
- No further signing is possible until the user explicitly restarts
Killed ≠ Paused. Pausing stops the loop but keeps the key in memory for instant resume. Killing is a hard security halt — the key must be re-retrieved from the Keychain on restart.
Why This Matters
Even if a compromised LLM generates a malicious tool call, the architecture ensures:
- The Guardrails layer blocks actions that violate safety limits
- The Wallet layer only executes validated intents
- The Kill Switch provides an emergency override at any time
- Private keys are never exposed to the reasoning layer
