Skip to content

Security model

Security is the point of SSH Ache, not a feature bolted on. Two layers matter: how the desktop app protects things locally, and how Teams / the cloud vault stay zero-knowledge.

On your machine

  • Secrets outside your config. Passwords, key passphrases, and private keys are written to ~/.ssh-ache/secrets.json, a file created with mode 0600 — owner read/write only, the same access posture as ~/.ssh/id_rsa — and mirrored to the platform keychain (Keychain / Credential Manager / Secret Service) where that works. They are never in the config file and never uploaded, but they are not encrypted at rest: anything running as your user account can read them, so full-disk encryption is what protects them on a lost machine. (The file is the primary store because keychain access is tied to an app's code signature and is unreliable on unsigned builds.)
  • Host-key verification. First-connect fingerprint confirmation, pinned in a local known_hosts store. A changed host key refuses the connection.
  • No account, no upload. Using the app requires no sign-in. Local-only hosts never leave your machine.

Zero-knowledge cloud

When you opt into Teams or the personal vault, the server is designed so it cannot read your data — it stores ciphertext and wrapped keys, nothing more.

  • Team key. Each team (and each personal vault) has a symmetric team key. Connections are encrypted ("sealed") under it before they leave your device.
  • Wrapped to members. The team key itself is sealed to each member's public key (X25519). Only a member's device can unwrap it. Adding a member means an existing member wraps the key to the newcomer's key — the server never handles it in the clear.
  • What the server stores. Ciphertext connections, per-member wrapped keys, and metadata needed to route sync. Not your credentials, not your session output.
  • Removing a member. Their wrapped copy of the team key is deleted server-side and the team key is rotated: a remaining member generates a new one, re-seals every connection under it, and wraps it to the members who are left. The removed device's copy stops opening anything sealed after that point. It cannot un-see what it already decrypted while it was a member — no end-to-end system can do that — so rotate credentials on hosts a departing member could reach.
  • What you have to trust. The server never sees plaintext, but you are trusting the client build that does the sealing and key-wrapping. That client's source is public (SSH-Ache/ssh-ache-teams), and the wire format is shared with the web client and pinned by known-answer tests, so a build that wrapped a key to an extra recipient would be a visible change in public source rather than an invisible one in a binary. Reproducible builds are not there yet.

Cryptography

SSH Ache uses audited @noble primitives:

  • XChaCha20-Poly1305 for authenticated symmetric encryption,
  • X25519 for key agreement and sealing keys to recipients,
  • Ed25519 for signatures,
  • Argon2id for deriving keys from your password.

Live view & audit

Live view is read-only and never silent — the watched session shows a watcher count. The Auditor role can review session history and presence for oversight without the ability to decrypt connection secrets.

Live-view mirroring

Watching a teammate's desktop session doesn't route their SSH through the cloud. The desktop keeps the SSH connection local and mirrors only the terminal output to the relay, which fans it out to viewers. The relay never sees the SSH secret or the typist's keystrokes — strictly less than the web-terminal path, where the relay opens the SSH session itself. Viewers are read-only; input is dropped. The relay's egress is also restricted to public targets (private, loopback, link-local and cloud-metadata addresses are refused) so it can't be pointed at internal infrastructure.

Reporting a vulnerability

Found something? Email security@sshache.com — please don't open a public issue for a vulnerability. Responsible disclosure is appreciated, and we'll acknowledge your report. The client source is public in SSH-Ache/ssh-ache-teams if you'd like to check these claims yourself.

Community edition: open source (Apache-2.0), individual use. Teams app: source-available, free for noncommercial use. Zero-knowledge by design.