# Skipper Privacy Policy

Revision of 22 September 2026. It covers the Skipper application for macOS, the
Skipper Remote application for iOS, and `skipperwow.com`, the relay the two use to
reach each other.

## In short

Skipper is an application that lives on your Mac. It has no account, no sign-in,
no analytics, no crash reporter, and no server that your work is uploaded to.

Three channels — and only three — can carry anything off your Mac. You switch the
first two on yourself; the update check is on from the start:

1. **Remote Control** — your terminals mirrored on your phone. The contents are
   encrypted between the Mac and the phone; the relay sees ciphertext.
2. **A public task-board link** — a page of tasks for whoever you hand the link
   to. This channel is **not** end-to-end encrypted: task text travels through
   the relay inside TLS.
3. **The update check** — an ordinary HTTPS request to the release source. It is
   on from the start and carries only the app's version.

Plus two that do not lead to us: "Server" tabs SSH into machines of your own, and
a webhook posts to an address you typed in yourself.

Everything else — projects, panes, tasks, terminal history, keys — stays on your
Mac's disk.

## Who is responsible

Ivan Chabanenko, a sole trader (Einzelunternehmen) at Lutherstraße 12,
39112 Magdeburg, Germany. He also owns `skipperwow.com` and the machine the
relay runs on. The full legal disclosure is on the Impressum page.

To ask anything about this data — or to exercise your rights under the GDPR to
access, correct, delete or take away what concerns you: <support-skipper@chbnk.one>.
You may also complain to a supervisory authority; the one for this operator is
the Landesbeauftragter für den Datenschutz Sachsen-Anhalt (Art. 77 GDPR).

## What Skipper stores on your Mac

All of it lives in `~/Library/Application Support/Skipper` (or `Skipper-Dev` for
the dev build), never leaves on its own, and is gone when that folder is gone.

- **The structure of your work.** Projects, their pane grids, working
  directories, pane titles, agent bindings — the `state.json` file.
- **Tasks, epics, the schedule, attachments.** An attachment is a copy of the
  file that Skipper made for itself.
- **A tail of each pane's history.** So that after a restart you can still see
  how the last turn ended, Skipper keeps the last lines of each pane's output: at
  most 2000 lines per pane, at most 8 MB for the whole fleet, and no longer than
  seven days.
- **Keys and tokens.** The long-lived X25519 identity for Remote Control, the
  relay room token, the list of paired phones, the board token. Files are `0600`
  inside a `0700` directory.
- **The Remote Control log.** Connection events and errors only — connected,
  dropped, pairing refused. Neither ciphertext nor decrypted content is ever
  written to it. A 2000-entry ring in memory plus a file that rotates past 2 MB.
- **SSH keys.** If you asked Skipper to create a key for a server, it calls the
  system `ssh-keygen` and the pair stays in `~/.ssh`. Only the public half ever
  leaves — into that server's `authorized_keys`, and only when you say so.

None of this is sent anywhere by Skipper on its own.

## What goes over the network

### Remote Control (terminals mirrored on your phone)

Off by default. It works only after you turn it on and pair a phone by matching
the codes shown on both screens.

- **Where to.** `wss://skipperwow.com/v1/ws` — a relay on a rented machine in
  Germany (Hetzner).
- **What travels.** Pane screen contents, the parsed agent conversation, the task
  list, the launch catalog, your keystrokes from the phone — that is, everything
  you see on the phone and everything you type into it.
- **How it is protected.** Every frame is sealed with ChaCha20-Poly1305 under
  keys the Mac and the phone derived themselves (an X25519 exchange during
  pairing). The keys never leave the devices: the relay does not have them and
  never did.
- **What the relay sees.** Ciphertext and routing: the room id, the device id,
  the pane session id, a coarse event class (`activity` / `attention` / `git`),
  a sequence number and the time of receipt. It cannot read a single line of your
  terminal.
- **What it stores.** Those same fields plus the ciphertext itself, in a Postgres
  database on the same machine. Plus SHA-256 hashes of the Mac token and device
  authorization tokens: the bearer values remain unknown to the relay. If
  notifications are enabled, the paired-device row also holds the phone's raw
  APNs token — an opaque Apple delivery address, not a content key. It is deleted
  when the device is revoked.
- **For how long.** Events are swept: the last 500 events of a room **or**
  everything from the last 24 hours are kept, whichever is larger. The rest is
  deleted. None of it survives for weeks.
- **Artifacts.** If you opened a page from the Mac to the phone — a folder on it,
  or a local server on it — its contents travel over the same encrypted channel
  and are visible to the paired device only. Artifacts have no public link, and
  there is no third kind of address: somebody else's host is not one.

### Notifications on your phone

If you allowed notifications, the relay asks Apple (APNs) to wake your phone.

- The notification itself carries a placeholder ("Skipper", "Update") and the
  same encrypted blob as the main channel. The phone decrypts the real message
  locally.
- The relay sees the APNs token so it can address delivery; Apple sees that token,
  the fact of delivery and the time. Neither Apple nor the relay sees the content.
- No more than one notification per two seconds per device is sent.

### The public task-board link

Off by default, switched on per workspace. The link lives until you switch it
off, but tasks are visible through it only while the application is running:
there is deliberately no copy of the board on the relay, and while the Mac is
offline the page shows nothing.

Here is a plain warning rather than fine print: **the board is not end-to-end
encrypted.** The relay copies frame bodies between the Mac and the browser and
neither parses nor stores them — but the connection is protected by TLS alone,
so technically the relay's owner could read the task text. If a task contains
something nobody but you should see, do not publish that board.

- **Where to.** `https://skipperwow.com/b/<id>`.
- **What travels.** Task titles and texts, their statuses, and — if the mode
  allows it — tasks someone created straight on the page. The path to your folder
  never reaches the page: a board has a separate name that you choose.
- **What the relay stores.** Only the link id, a SHA-256 hash of the board token,
  and the build label (`dev` / `live`). It stores no task at all: your Mac is the
  only source of tasks.
- **The password.** In "password" mode the Mac checks the password, not the
  relay. Skipper keeps only a stretched hash of it; the password itself is stored
  nowhere and never written to a log.
- **Revocation.** Changing the mode or the password reissues the link: the old
  one stops working.

### The update check

Skipper asks the release source whether a newer version exists: an ordinary HTTPS
GET. The only thing that travels is a `User-Agent` header of the form
`Skipper/<version>`. No install id, no machine name, nothing about your work is
sent. Downloading the image is just as ordinary a request for a file.

The default source is `https://skipperwow.com/updates/` — the same rented
machine the relay runs on. You can point it elsewhere: the "Откуда узнавать о
выпусках" field in the Updates section of settings.

### "Server" tabs

Skipper runs the system `ssh` to hosts from your `~/.ssh/config`. The connection
goes straight from your Mac to your server; the relay takes no part in it and
knows nothing about it. Skipper owns exactly one file inside your `~/.ssh` —
`config.d/skipper.conf` — and does not rewrite your own `config`.

### The webhook

If you entered a webhook address, Skipper POSTs the outcome there when work
finishes. What ends up in it is your decision, made by choosing what goes into
the outcome; the address is yours too. We do not know that address and the
traffic does not pass through us.

## The phone app (Skipper Remote)

The other half of Remote Control is a separate app for the phone, **Skipper
Remote**. On its own it shows nothing: it displays what a Mac you paired it with
sends, and like the Mac it has no account, no sign-in and no analytics.

What it keeps on the phone:

- **The pairing.** The bearer token and the two session keys, in the phone's
  Keychain, inside the app group the app shares with its notification extension.
  They are readable after the first unlock — that is what lets a notification be
  decrypted while the screen is off — and they never leave the phone.
- **A delivery cursor.** Which frames this device has already seen, so a
  reconnect does not replay output you have read.
- **A device id it makes up for itself** — `d_` and eight characters. Not the
  phone's serial number, not the advertising identifier, nothing the system hands
  out. The Mac and the relay use it to address this device, and that is all it is.
- **A connection log** of the same shape as the Mac's: connected, dropped,
  refused — never a line of terminal output. 2000 entries in memory plus a file
  that rotates past 2 MB.

Deleting the app deletes all of it.

What it sends is what you do with it: the keys you type into a mirrored pane and
the actions you press there. It travels sealed with ChaCha20-Poly1305 to your Mac
through the same relay, which sees ciphertext.

The camera is used for one thing — reading the pairing QR shown on the Mac. The
picture is not stored and not sent anywhere. The app asks for no contacts, no
photos and no location, has no advertising identifier, and carries no third-party
SDK at all: its cryptography is Apple's own (X25519, ChaCha20-Poly1305).

## What Skipper does not do

- It collects no analytics and no usage statistics.
- It sends no crash reports.
- It requires no account and does not know your email address.
- It neither reads nor sends the contents of your project files — other than
  those you opened yourself in a pane that is being mirrored to a paired phone,
  or handed to it yourself as an artifact.
- It does not hand data to third parties, does not sell it, and shows no ads.
- It stores no task and no terminal line on the relay in the clear.

## Who else is involved

- **Hetzner Online GmbH** (Germany) — the rented machine the relay runs on. It
  has physical access to the disk holding the ciphertext and the routing labels.
- **Apple** — notification delivery over APNs, as described above.
- **The release source** — the server Skipper asks about updates sees the fact of
  the request and your IP address, as any website would. By default that is
  `skipperwow.com`: the same owner and the same machine as the relay.

## How to delete everything

- **A paired phone.** Revoke the device in Remote Control settings: the Mac drops
  it from its own list and removes its row at the relay.
- **Remote Control as a whole.** Turning it off with a wipe deletes the local
  keys, the pairing and the device list. Events already accumulated at the relay
  expire on their own by the rule above — no later than 24 hours after the last
  one.
- **The public board.** Switch the link off: it stops working immediately, and
  its row at the relay serves nothing any more.
- **Everything local.** Delete `~/Library/Application Support/Skipper` (and
  `Skipper-Dev`, if you installed the dev build). Skipper holds nothing about you
  anywhere else.

## On being straight about it

Skipper is an application written by one person. Remote Control's encryption is
assembled from audited CryptoKit primitives (X25519, ChaCha20-Poly1305) following
a protocol documented in the repository — but it **has had no external security
audit**. We say so plainly, because "it's encrypted" without that caveat reads as
a promise nobody made.

## Changes

If this policy changes, the date at the top of this file changes with it, and the
file ships with the next release. Earlier revisions stay in the repository's
history.


---

Page: https://skipperwow.com/privacy/ · Markdown: https://skipperwow.com/privacy/index.md
Other languages: Українська: https://skipperwow.com/uk/privacy/ · Deutsch: https://skipperwow.com/de/privacy/
Skipper — https://skipperwow.com/ · Support: support-skipper@chbnk.one
