Chapter 2 of 12
How MangoSSH Protects Your Keys & Passwords
The claim this chapter makes precisely, and backs up against the actual source code (not just marketing language): no password, passphrase, PIN, token, or private key that MangoSSH itself manages is ever written to disk unencrypted — in any storage mode, on any platform, with zero setup required. This is verified directly against the code paths described below, and you can re-verify it yourself with the steps at the end of this chapter.
Understanding the Three Layers of Protection
Purpose
See exactly what gets encrypted, with what, and where — so "it's encrypted" is a specific, checkable claim rather than a vague reassurance.
- — Per-secret OS-native encryption.
- Every individual secret — an SSH password, a key passphrase, a PKCS#11 PIN, a TOTP seed, an RD Gateway password, a HashiCorp Vault SSH token — is handed to your operating system's own credential store the moment you check "Save": Windows Credential Manager, macOS Keychain, or the Linux Secret Service (via libsecret), through the same code path every time (a single keyring_save() function, not a different one per feature).
- hosts.json never receives the actual secret value — the code that saves a new host explicitly strips password , passphrase , totpSecret , pkcs11Pin , vaultToken , and gwPassword before anything is written to the metadata file, leaving only a boolean flag (e.g. _hasPwStored ) behind so the UI knows a secret exists without ever holding its value.
- — SSH keys MangoSSH generates for you.
- Settings → SSH Keys → Generate creates a keypair whose private key is immediately encrypted with AES-256-GCM before it touches disk, using the same OS-keychain-backed key as Personal Vault's default mode (below) — deliberately, so the private key is protected in every storage mode , including if you're on legacy plain mode or haven't unlocked vault mode.
- The public key, name, and fingerprint stay in plain text (so the Keys list works without unlocking anything), but the private key material itself is never sent to the frontend in any form, encrypted or not — it stays entirely on the Rust backend side.
- — Your saved host list itself.
- Beyond individual secrets, the hosts.json file — hostnames, usernames, groups, connection settings, and those boolean "has a secret" flags — is itself encrypted at rest by Personal Vault , using AES-256-GCM.
- This is the layer covered in the Vault System chapter, and it's on by default (next use case).
- Secrets you type password / passphrase / PIN / token OS Keychain Windows / macOS / Linux hosts.json metadata names, users, groups, settings Personal Vault AES-256-GCM Disk ciphertext only Two independent paths, one guarantee: whether it's a secret field or the rest of your host list, nothing reaches disk without first passing through an encryption boundary.
Confirming Personal Vault Is On by Default
Purpose
- Verify that a fresh MangoSSH install encrypts your host list from the very first launch, with no setup step required and no way to accidentally end up unprotected.
- The backend's own default for a brand-new install is literally the string "auto" — there is no code path that starts a fresh profile in an unencrypted state.
- "Plain" (unencrypted) storage only exists as a one-time, automatic upgrade path for installs that predate Personal Vault entirely: the very first time such an install launches, its existing plaintext host list is silently encrypted and the plaintext file deleted — logged to the Audit Log as vault_auto_migrate — and it never returns to plain mode afterward.
- There is no setting anywhere in the current UI that lets a host list go back to unencrypted storage.
How to do it
- This requires no action — "auto" mode (Personal Vault, silently encrypting hosts.json with a key held in your OS's own keychain) is already active the moment you add your first host.
- Optionally upgrade from auto to vault mode in Settings → Encrypted Vault if you want an explicit master-password unlock step on top of this default protection — covered in the Vault System chapter.
How to verify
- On a fresh profile with at least one saved host, open Settings → Encrypted Vault.
- Expect every host row to show a Personal Vault badge reading exactly "Encrypted" — this badge is unconditional; there is no state where it reads "Not encrypted" or similar.
- Click Manage password protection… at the top of that pane.
- Expect the modal's status line to read "Encrypted (automatic)" in green with a shield icon, and the description text "Hosts file is AES-256-GCM encrypted by default, using a key held in your OS keychain — no password needed."
- If instead you see a yellow "Plain JSON (unencrypted)" status, that means this is an unmigrated legacy install (see Known Limitations) — close and relaunch MangoSSH once; the migration is automatic and this status should flip to "Encrypted (automatic)" afterward without you doing anything else.
Verifying This Yourself (Don't Just Take Our Word for It)
Purpose
Check the actual files and OS credential store directly — the same claim this chapter makes, confirmed independently of anything MangoSSH's own UI tells you.
How to do it
- Locate your profile's data directory (Settings → Profiles shows the active profile's path) and open hosts.json directly in a plain text editor.
- In auto or vault mode, confirm the file is unreadable binary/base64-looking ciphertext, not JSON at all.
- If you're inspecting a pre-migration legacy install about to self-upgrade, you'd instead confirm the file disappears (replaced by an encrypted vault file) after the app's next launch.
- Open your OS's own credential manager — Credential Manager (Windows: Control Panel → User Accounts → Credential Manager → Windows Credentials), Keychain Access (macOS), or secret-tool /Seahorse (Linux) — and search for entries under the service name MangoSSH .
- Confirm one exists per saved secret, and that its value is only visible through your OS's own authentication (this is your operating system's security boundary, not MangoSSH's).
- Check the Settings → SSH Keys folder on disk (path shown in that Settings page) and confirm each key's .json file holds a privateKeyEnc field (opaque ciphertext) rather than a readable privateKey field.
How to verify
- Open hosts.json in Notepad/TextEdit.
- Expect either a file that fails to open as text (binary garbage) or a short JSON envelope containing only opaque fields like nonce / ct (ciphertext) — you should NOT be able to read a real hostname, username, or IP anywhere in it.
- Open your OS credential manager and search for "MangoSSH".
- Expect at least one entry per host that has a saved password/passphrase — click one (Windows Credential Manager requires re-entering your own Windows login to reveal it; that re-auth step IS the protection working, not a bug).
- Open a key's .json file (path shown on the SSH Keys page) in a text editor.
- Expect to see a privateKeyEnc field whose value is a long opaque hex/base64-looking string — NOT a field literally named privateKey with readable -----BEGIN OPENSSH PRIVATE KEY----- content in it.
- If all three checks above match what's described, the guarantee this chapter claims is confirmed on your own install, independent of anything MangoSSH's UI told you.
Troubleshooting
- hosts.json is readable plain JSON with real values in it — this would mean either you're on an unmigrated legacy install that hasn't been launched since upgrading yet (launch it once, the migration is automatic), or a genuine regression worth reporting immediately given how central this guarantee is.
- A secret's OS-keychain entry is missing even though "Save" was checked — check for a _pwSaveError -style note on that host; a failed keychain write (e.g. a permissions issue on an unusual OS configuration) is surfaced rather than silently treated as success.
What This Does and Doesn't Protect Against
Purpose
- Understand the honest boundary of this protection, so you don't rely on it for something it was never designed to stop.
- What it protects against : someone getting hold of the raw files — a stolen laptop (powered off), a copied disk image, a stray cloud-sync of your app-data folder, malware that scrapes *.json config files looking for credentials, or a backup that ends up somewhere it shouldn't.
- None of these give an attacker anything usable without also having access to your OS account's own keychain.
- What it does NOT protect against : another process already running as your own logged-in OS user account reading the keychain directly, or someone with your unlocked session sitting at your keyboard.
- This is the same trust boundary every credential saved by any desktop app (browsers included) already relies on — MangoSSH applies it consistently to your whole host list and every generated key, rather than only to individual passwords.
- Externally-supplied key files are a distinct case : if you point MangoSSH at a key file already on your disk (e.g. ~/.ssh/id_ed25519 ) rather than generating one inside MangoSSH, only the file path is stored — never the key content.
- That file's own protection is whatever your OS/disk encryption already provides for it, exactly as if you'd pointed any other SSH client at the same file; MangoSSH neither weakens nor strengthens that file's existing protection.