Contents
Using SpectaShell

Security and privacy

Last updated: 2026-10-31

SpectaShell has no account of its own. It reaches your hosts over your own SSH login, syncs through your own iCloud, and runs no network service on your device or your hosts. Its one server is a relay for notifications from hosts, used only by the devices you turn them on for and your hosts that notify them, and it cannot read them. This page says what stays on your device, what goes where, and what SpectaShell does on your hosts, so you can decide what to trust it with.

What never leaves your device#

  • This device's keys. The device key and the listing key are made on the device. On an iPhone, an iPad and a Mac with Apple silicon or a T2 chip they are made in the Secure Enclave, and their private halves cannot leave the chip; on a Mac without one they stay in this Mac's keychain, marked never to sync. Their private halves are never exported or uploaded, and SpectaShell imports no keys.
  • Passwords, passphrases and one-time codes. They are never stored anywhere (see Passwords and passphrases).
  • Your own SSH files on the Mac. ~/.ssh/config, your keys in ~/.ssh, your SSH agent and ~/.ssh/known_hosts are read on the Mac and never changed or uploaded. A host you copy from ~/.ssh/config into your hosts syncs like any other.
  • Command history. The commands your shells ran, kept for 30 days on this device only: a command line can hold a token.
  • Where the device key went, the host keys refused, the settings that are this device's own (the text size, the key row, Notify This Device), and your windows and tabs.

SpectaShell's own files on the device, such as its history and what it last synced, can be read by you alone (mode 0600).

What iCloud holds#

What syncs goes to the private database of your Apple Account in iCloud, in SpectaShell's own container: your hosts and groups, snippets, triggers, saved port forwards, favourite folders, the clouds you added (without their credentials), the host keys you trust, your devices' public keys, the terminal's fonts and themes with those you add, and your notification rules with the public keys your hosts' notifications use. The full list is in What syncs and what stays.

  • What syncs goes to iCloud and nowhere else; SpectaShell's relay never holds any of it.
  • A group you share with a team is shared with the people you invite, and with no one else unless you choose to open its link (see Teams).
  • Nothing secret syncs: public keys only, never a private key or a password.
  • To keep everything on the device, turn off Sync Through iCloud in Settings (see Sync settings).

A cloud's credentials (a DigitalOcean token, an AWS key) are kept in the Keychain, never in SpectaShell's sync. With On All Devices on, iCloud Keychain brings them to your other devices.

Passwords and passphrases#

When a host asks for a password, a passphrase or a code, SpectaShell asks you, passes your answer to the login, and forgets it. The dialogs say so: "Not stored anywhere." A host's own questions are shown as the host sends them.

After a password login, SpectaShell offers to add this device's key to the host, so you need not type the password again (see Putting the key on a host).

Host keys#

SpectaShell checks each host's key, as OpenSSH does.

  • The first connection to a host shows its key's type and fingerprint and asks Trust host?. If you can, compare the fingerprint with the one the host shows for itself (ssh-keygen -lf on its /etc/ssh/ssh_host_*_key.pub) before you choose Trust and Connect.
  • A key you trusted syncs to your other devices, which then do not ask again.
  • A key that changed is refused, on every device. SpectaShell says "host's host key changed", with the key presented and the one you trusted. Someone between you and the host could be presenting a different key, or the host was reinstalled. If you did not expect it, do not connect; ask whoever runs the host for its fingerprint.
  • To accept a new key on purpose, choose Forget Old Key…, then Forget Key. The old key is forgotten on all your devices, and the next connection asks you to trust the new one.

On the Mac, a host already in your ~/.ssh/known_hosts is trusted as it is there. Known Hosts lists the keys SpectaShell trusts, with when and on which device each was trusted (see Known Hosts and When a host's key changes).

Your device's keys#

Each device logs in with its own key, which asks for Face ID, Touch ID or your device's password each time a host accepts it, so someone holding your unlocked device cannot log in with it. Its listing key lets a host do one thing, list its kept shells, and the host enforces that. See Your devices, keys and iCloud.

Your devices put a new device's listing key on your hosts only once one of them approves it, so someone signed in to your Apple Account on a device of theirs cannot list the shells on your hosts without logging in to them (see Approving a new device).

With Agent Forwarding on for a host, that host can ask your device's key to sign — to log in elsewhere, or to sign a git commit — but never without you: each request asks Face ID, Touch ID or your password on its own, naming the host and what the signature is for, and is never approved by an answer you gave for something else. Cancel one and that connection asks no more. The host cannot add or remove keys through the forwarded agent. The keys of your Mac's SSH agent are forwarded as ssh forwards them: they sign without asking (see Hosts and connections).

What SpectaShell puts on a host#

The keeper#

On a host where you choose Keep Shells Running, SpectaShell puts a small program, spectashell-keeper, which keeps your shells running when the connection drops. On a host where you choose Plain Shells, it puts no program.

The keeper:

  • Runs as you. It is started over your own SSH login, as the account you log in as. It never asks for root and never uses sudo.
  • Lives in your home folder, in ~/.local/share/spectashell, one folder per build. An earlier build's folder is removed once nothing runs from it.
  • Keeps its sockets in a folder only you can reach. On Linux it is /tmp/spectashell-<your user id>/keepers, on a Mac ~/Library/Application Support/SpectaShell/keepers. Before using the folder, the keeper checks that it is a real folder owned by you with mode 0700, and refuses one that is not, since anyone who reaches a keeper's socket can type into its shell. The sockets themselves are mode 0600.
  • Opens no network port. It is reached only through its sockets, over your SSH connection. It sends nothing anywhere else, except, once a device of yours has notifications on, a sealed notification to SpectaShell's relay when a program needs you and none of your devices is in front (see Notifications from hosts).
  • Keeps your shell's output in memory. On disk, beside its socket, it writes only a short description of the shell, with its last few lines, readable by you alone.
  • Changes none of your shell files. Shell integration, which marks prompts and commands in bash, zsh and fish, is loaded by how the keeper starts the shell, from scripts in its own folder. Your .bashrc, .zshrc and fish configuration are not edited.

Lines in authorized_keys#

On any host, kept shells or not, SpectaShell adds lines to ~/.ssh/authorized_keys only in these cases:

  • this device's key, when you choose Add Key after a password login;
  • the listing keys of this device and of your approved devices, each restricted by the host to listing the kept shells (see The listing key);
  • your teammates' keys, when you let them in with Who May Log In…: see Letting people log in to a host.

It takes lines out only in these cases: this device's earlier keys, when its new key is added; the keys of a device you took off your hosts; and the lines of teammates you let out with Who May Log In…. A device's line is found by its key, never by the name in its comment, and only lines tagged for a team are taken off for that team.

A shell's environment#

A shell on the Mac, or one a keeper keeps on a host, starts from your login session, not from whatever started SpectaShell or the keeper. It is given only the variables a login session has — who you are, your home, the path, the locale and time zone, the temporary folder, the SSH agent's socket, the display — and your shell's profile adds your own. SpectaShell then sets TERM=xterm-256color, COLORTERM=truecolor and TERM_PROGRAM=sdTerm.

Any other variable is another program's and is not passed on: another terminal's names and session ids, a multiplexer's (TMUX), or a coding agent's marks on its child processes. So the Mac app opened from a shell — with open in a Claude Code session, say — starts its shells the same as when it is opened from the Dock.

What SpectaShell connects to#

  • Your hosts, over SSH, directly or through the jump hosts you set.
  • iCloud, for sync and teams, while sync is on.
  • A cloud's API, DigitalOcean's or AWS's, with the credentials you gave, to list its machines, only when you added that cloud.
  • The web pages you open in a page beside a shell or in the browser.
  • SpectaShell's relay (push.calidalab.ai), only from a device you turned notifications on for and the hosts that notify it (see Notifications from hosts).

A port forward you start listens on your device's own address (127.0.0.1), so other machines on your network cannot use it. SpectaShell sends no usage data.

Notifications from hosts#

Settings ▸ Notifications ▸ Notify This Device lets your hosts tell this device that a program needs you while none of your devices is in front. Apple delivers a notification to an app only from the holder of the app's push key, which cannot be on your hosts, so a relay of Calida Lab's stands between them.

  • The relay cannot read a notification. Each host seals what it sends to a key your device made, whose public half it publishes in your iCloud so any of your devices can write it on a host; only your device can open it. The relay passes the sealed bytes to Apple and keeps none of them.
  • It does not know your hosts' names. What a notification says about its host is your device's own record, never the host's word.
  • What it knows: your device's notification token, the public keys of the hosts that notify it (so how many there are), and when and how often each sends. It sees each request's address, as any server does, and writes none down. Cloudflare, in front of it, sees the same.
  • What it never knows: what a notification says, which host it is, any file, any key that signs or opens.
  • On the host, a file per receiving device in ~/.local/share/spectashell-push, readable by you alone, holds the key the host signs with, made there and never leaving it, and the device's key it seals with. Any of your devices that opens a shell there writes it, over your login. The keeper sends only over HTTPS, only when something happened, and still listens on nothing.
  • On your device, the keys that open them stay on this device. A key that can only turn notifications off syncs through your iCloud Keychain, so another of your devices can turn off a lost one's.
  • The lock screen shows a notification's text only as your iPhone's Show Previews setting allows: with When Unlocked, a locked phone shows "SpectaShell" alone.

Turning it off in Settings stops them all at once for that device; each host deletes its file the next time it tries to send, or when one of your devices next opens a shell there.

Pages and coding agents#

Once you add SpectaShell to a coding agent (Settings, Agents), the agent in a kept shell can use the page beside its shell: open the page of a server it started, read it, click and type in it, and see its console and a picture of it. It reaches the page over the shell's own connection; nothing listens on a port. To keep a host's agents off this device's pages, choose Keep Agents Off Pages in the host's menu. See Files, ports and pages.

Teams#

Sharing a group shares its hosts' names and addresses, never keys or passwords, and lets no one log in. Who may log in is decided host by host, by the keys in its authorized_keys.

A teammate you let in on a host logs in as that host's account: they can see and control every shell of that account there, yours too, and do anything the account may. To keep people apart, give each person an account of their own. See What a member can do on a host.

A lost device#

On another of your devices, open Keys and choose Remove from Every Host… beside the lost device, under Your Other Devices. Its keys come off every host in your book, and every later login of your devices takes them off any other host. Its keys never go on a host again, and its notifications from hosts stop. Also erase it in Find My and remove it from your Apple Account. See A lost or sold device.

How SpectaShell is distributed#

  • The Mac app is distributed directly, signed with Apple's Developer ID and notarized by Apple, as other terminals for the Mac are. It is not sandboxed: a shell on your Mac has to reach your own files, which a sandboxed app's shells cannot.
  • The iPad and iPhone app comes from the App Store, sandboxed as every app there is. It opens no local shells: its shells run on your hosts.

Good to know#

  • Everything SpectaShell puts on a host is in ~/.local/share/spectashell, the keepers' socket folder, ~/.local/share/spectashell-push once a device of yours has notifications on, and the lines in ~/.ssh/authorized_keys whose comments start with "SpectaShell" (or "sdTerm", from early builds).
  • Someone who can log in to a host as you, or as root, can reach your kept shells there, as with tmux or screen: a keeper keeps its shells from the host's other users, not from your own account.
  • Your synced data is as safe as your Apple Account. Anyone signed in to it gets your synced hosts and snippets, but no key and no password, and your devices put no listing key of theirs on your hosts until you approve their device. Keep no password in a snippet.
Back toOverview → Get notified at launch