Security model
What the platform protects, by which mechanism, and where the boundary ends: for the core and for every plugin that attaches to it. The full statement is the Security Model document and the architecture decision records.
Principles
- Nothing silently trusts the network: no host key is accepted without you.
- A plugin gets what its manifest declares and you approved, nothing more.
- The sync server is assumed hostile.
- Secrets never reach logs, the audit log, plugin logs or the interface after they are saved.
- Where a guarantee does not hold, the documentation says so.
Vault
| Encryption | age with an scrypt-derived key, one file at rest |
| Master password | Minimum 8 characters, 12 with sync. In memory only while unlocking |
| Recovery key | Shown once, replaced after use, separate and stricter attempt counter |
| Unlock attempts | Rate-limited |
| Passphrase cache | Per key, time-limited, cleared on lock and shutdown |
| Schema upgrades | The previous vault is copied aside before migration; an older build refuses a newer vault instead of damaging it |
Host trust
SSH host keys are verified strictly against the vault's known hosts. A new key prompts; a changed key stops the connection and shows the mismatch. There is no setting that accepts silently. Every hop of a jump chain is verified the same way.
Protocols other than SSH use Trusted Peers: a plugin reports the identity it saw, and the application, not the plugin, decides. An unknown or changed identity stops the session with a SHA256: fingerprint. Peer trust is stored apart from known hosts, so no plugin can reach the trust the SSH client reads.
Plugin boundary
Every plugin runs as its own operating-system process and talks to the core only over a JSON-RPC channel. The boundary is enforced in layers.
| Layer | What it enforces |
|---|---|
| Process separation | Per-plugin or per-session processes. Killed on shutdown or crash, restarted with backoff |
| Capability gate | Each call (fs.*, net.dial, vault.getSecret, …) is checked against the manifest. Unmatched calls are denied and audit-logged |
| Version handshake | The core decides compatibility; a version echoed by the plugin is never trusted |
| Resource limits | Job Objects on Windows, rlimits elsewhere. Oversized frames and file operations rejected |
| Ownership checks | Vault and session access scoped to the plugin that owns the session |
| Consent | The install screen lists every grant. Risky capabilities, such as tunnel and auth providers, need separate consent |
| Signatures | New vaults require signed plugins. Changing the trust policy asks for the master password |
Operating-system confinement
The layers above govern what a plugin asks the core to do. On Windows and Linux the operating system also confines what the process can do by itself.
| Platform | Mechanism | What a plugin process can reach |
|---|---|---|
| Windows | AppContainer | Confined Its own files and data directory. No sockets, not even loopback |
| Linux 5.13+ | Landlock | Confined The same, plus system libraries. Network unrestricted below kernel 6.7, TCP-only above it |
| macOS | None | Not confined Everything your account can reach, including ~/.ssh |
Each plugin's row in Settings shows which boundary it actually runs behind. Where confinement is available and fails, the plugin does not start, rather than starting unconfined.
Sync server
Records are encrypted and signed on the device. The server stores ciphertext and coordinates delivery.
A synced change that would weaken a device, such as turning off plugin signature checks, loosening the lockout, or replacing a known host key, waits for that device's master password. In a team, changing a shared connection's address suspends every other member's credential link until they confirm it. More on sync
Local terminal
No capability, host method or API call opens a local shell, so no plugin can reach one. Keystrokes in it are not recorded; the audit log notes only that a shell was opened.
What it does not cover
Installing a plugin is a decision about trusting its author. Confinement narrows what a malicious plugin can do; it does not make one safe.
On macOS there is no plugin sandbox, and none is planned.
A compromised operating system or a keylogger on your machine is outside the model.
Reporting a vulnerability
Follow SECURITY.md instead of opening a public issue. Only the latest release is supported; fixes ship as a new release.