No description
  • Rust 57.4%
  • Kotlin 31.5%
  • Java 9.5%
  • CSS 0.5%
  • Python 0.5%
  • Other 0.5%
Find a file
salix ea9e5423f1
Some checks are pending
Build Android nightly and check shared core / android (push) Has started running
Merge pull request 'Submit SSH authentication prompts with the keyboard's Enter' (#3) from fix/keyboard-enter-key into main
Reviewed-on: #3
2026-10-19 09:47:54 +02:00
.cargo Relax build limits to use 10 CPUs and 20 GiB RAM 2026-10-09 23:15:05 +02:00
.forgejo/workflows Ship release APKs through F-Droid and Forgejo releases 2026-10-11 02:01:08 +02:00
adwaita Drop the transfers list from the Files view 2026-10-17 02:24:51 +02:00
android Submit SSH authentication prompts with the keyboard's Enter 2026-10-19 09:11:26 +02:00
assets/readme Rework README with download, screenshots, and project docs 2026-10-10 16:28:37 +02:00
build-aux Ship the keyring crates in the Flatpak source list 2026-10-17 17:31:27 +02:00
core Add quick unlock with the keyring and a PIN 2026-10-17 02:24:51 +02:00
ffi Record last used on Android connects and mirror desktop vault notices 2026-10-17 15:40:05 +02:00
vendor Vendor russh-sftp with receive, reply-size, and listing bounds 2026-09-20 16:24:40 +02:00
.gitignore Reorganize apps and shared core into platform directories 2026-09-06 01:50:21 +02:00
Cargo.lock Add quick unlock with the keyring and a PIN 2026-10-17 02:24:51 +02:00
Cargo.toml Vendor russh-sftp with receive, reply-size, and listing bounds 2026-09-20 16:24:40 +02:00
CONTEXT.md Add the Recycle Bin term to the glossary 2026-09-07 19:42:12 +02:00
README.md Document the F-Droid repository for stable and nightly Android builds 2026-10-11 02:01:11 +02:00
rustfmt.toml Initial Ferry workspace: GTK 4 shell, KDBX vault, domain types. 2026-09-02 20:47:47 +02:00
SECURITY.md Offer to allow blocked remote clipboard writes from a toast 2026-09-30 22:56:07 +02:00

Ferry

SSH and SFTP that keep your hosts and keys in a vault you own.

Download • Android • GNOME • Matrix


Community

Chat in #projects:salix.host on Matrix

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

Add Ferry to Obtainium Download the latest Android APK

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

Add the Salix Flatpak repository

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.settings format 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-tcpip channel.
  • 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.