- Rust 57.4%
- Kotlin 31.5%
- Java 9.5%
- CSS 0.5%
- Python 0.5%
- Other 0.5%
|
Some checks are pending
Build Android nightly and check shared core / android (push) Has started running
Reviewed-on: #3 |
||
|---|---|---|
| .cargo | ||
| .forgejo/workflows | ||
| adwaita | ||
| android | ||
| assets/readme | ||
| build-aux | ||
| core | ||
| ffi | ||
| vendor | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CONTEXT.md | ||
| README.md | ||
| rustfmt.toml | ||
| SECURITY.md | ||
Ferry
SSH and SFTP that keep your hosts and keys in a vault you own.
Download • Android • GNOME • Matrix
Community
Discussion happens in #projects:salix.host, which works from any Matrix client. If you do not have an account yet, you can create one on salix.host, my public homeserver: federated, encrypted by default, and no email address required.
Download Ferry
Android
Obtainium is the recommended option because it installs updates directly from Ferry releases. The
APK button opens the latest release for a manual download. The stable release is also published to
the Salix F-Droid repository: add https://salix.host/fdroid/repo/ as a repository in F-Droid or a
compatible client to install host.salix.Ferry and receive updates. The same repository carries
nightly builds as host.salix.Ferry.Devel. Ferry needs Android 8.0 or
newer and is not available through Google Play. Signed nightly builds with the
host.salix.Ferry.Devel ID are produced on every push to main and install beside stable Ferry;
see the Android notes.
Linux
Open the Flatpak repository button with GNOME Software or Discover, then install Ferry from the
new Salix source. The repository is signed and provides updates for the stable app as well as the
separately installable nightly build. These packages currently support x86_64 only. If your
software center does not handle the button, use:
flatpak remote-add --if-not-exists salix https://salix.host/flatpak/salix.flatpakrepo
flatpak install salix host.salix.Ferry
Screenshots
Description
Ferry is a set of native apps for working over SSH. You save each machine once — its address, user, authentication, and observed operating system — and Ferry turns it into one-tap terminal Sessions, SFTP file browsing, Transfers, and a live Docker and Podman fleet, all kept in a vault on hardware you control.
There is an Android app and a GNOME desktop app. They look and feel like the platform they run on, and they share one Rust core so they behave the same way underneath.
Features
- A vault, not an account. Hosts, identities, and known-host keys live in an app-owned KDBX4 vault protected by a master password. Ferry can keep several vaults on one machine — Personal, Work — each with its own file and master password; one vault is open at a time, and switching locks it.
- Your keys, your file. OpenSSH private keys are stored as protected KDBX attachments, and
Ferry reads and writes the
KeeAgent.settingsformat shared with KeePassXC and Strongbox. On Android, an optional biometric unlock wraps the master password and the password remains the recovery path. - Sync with no service in the middle. The encrypted vault copy lives on your own WebDAV server. A copy that was never synced against the local vault is adopted by merging both sides, conflicts are chosen explicitly, and failed requests retry with backoff while the vault is open. Ferry never syncs decrypted records.
- Sessions that come back. A dropped Session reconnects with exponential backoff — five
attempts by default — and persistent tmux terminals keep their programs running through
disconnects, vault locks, and closed windows, including sessions created outside Ferry. At most
one jump host is reached through a
direct-tcpipchannel. - Files and Transfers. Browse remote files, edit permissions, and move uploads and downloads through a background queue, with recursive folder Transfers treated as one job. Remote applications can copy text through OSC 52 — with an explicit allow on desktop — and reads are ignored.
- Containers without agents. Ferry talks to each host's Docker or Podman HTTP API over SSH — no agent, no exposed TCP port — and follows engine events so lists update as containers start, crash, or turn unhealthy. Stacks are edited and deployed Dockge-style, image updates are checked against the registry without pulling, and desktop notifications report crash loops. See containers in the core README.
- Hosts that feel known. Each SavedHost remembers its observed operating system, an automatic or chosen icon, keepalive and reconnect settings, and a startup command. Server public keys are pinned per hostname and port in the vault.
- Native on both platforms. libadwaita and VTE on GNOME, Material 3 on Android with split-screen and foldable postures, and TerminalTheme colour sets shared by both.
Projects
| Project | Best for | Built with | How to get it |
|---|---|---|---|
| Android | Phones, tablets, foldables | Kotlin, Compose, UniFFI | APK on the releases page or via Obtainium |
| GNOME | Linux desktops | Rust, GTK 4, libadwaita, VTE | Flatpak from the signed Salix repository |
| Core | Everything shared | Rust, Tokio, russh, KDBX | Used by the apps above |
This is one Git repository holding independent Cargo and Gradle projects; ffi/ holds the UniFFI
bridge the Android app consumes. Each project README covers install, build, and what is actually
implemented today.
Contributions
I'm not currently accepting contributions, but issues are welcome for bug reports, feature ideas, and other feedback.
Releases
Releases use a shared vMAJOR.MINOR.PATCH tag on a commit named Release Ferry MAJOR.MINOR.PATCH.
Pushing the tag runs .forgejo/workflows/release.yml, which checks the version against Cargo.toml,
Cargo.lock, adwaita/meson.build, the AppStream metainfo, and the Android version, then builds
the signed stable host.salix.Ferry Flatpak for x86_64 and the signed host.salix.Ferry Android
APK, publishes the Flatpak to the signed Salix repository and the APK to the Salix F-Droid
repository, and creates one Forgejo release with both files and their SHA-256 checksums. Stable and
nightly Flatpaks share one OSTree repository, and a workflow lock keeps either channel from
publishing from a snapshot that predates the other.
Between releases, pushes to main build nightlies, skipping the tagged release commit.
build-android.yml produces a signed ferry-android-nightly-<commit> APK artifact with the
host.salix.Ferry.Devel ID that installs beside stable Ferry and publishes that APK to the Salix
F-Droid repository, and build-flatpak.yml publishes the separately installable
host.salix.Ferry.Devel nightly to the repository's nightly branch.
Disclaimer and license status
Ferry is a personal project, built for daily use and experimentation. Ferry, its source code, and all downloadable builds are provided as is, without warranties of any kind, express or implied. You use them entirely at your own risk. To the fullest extent permitted by applicable law, the author will not be liable for any claim, loss, damage, data loss, service interruption, or other consequence resulting from the use, misuse, or inability to use Ferry.
No support commitments, compatibility guarantees, or release schedule are provided. You are responsible for complying with applicable laws and third-party terms when using Ferry. The project is not affiliated with the KeePass Project, KeePassXC, Docker, or Podman.
The code is source available for reading and reference. It is not open source licensed, so unless a license is added later, no permission is granted to reuse, redistribute, or relicense it.









