Skip to content

Latest commit

 

History

198 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Airlock

Send files between your own devices. Encrypted before they leave.

No accounts. No cloud. No size limit. No public port.

Get started · Screenshots · What it does · FAQ · Security


Airlock runs on one of your own machines and lets your phone, laptop and desktop pass files to each other over Tailscale.

Your files are locked on the sending device before anything is uploaded. The server holds only scrambled data. It never gets the key, so it cannot read your files, their names, or even their thumbnails.

Note

Airlock works end to end today. It is a personal project, and Status is honest about which platforms have been tested on real hardware.

⚡ Get started

Before you begin

You need two things. Both are free and take a few minutes.

  • Tailscale installed on at least two of your devices
  • HTTPS turned on for your Tailscale network. One switch on the DNS page of your admin console
Why does it need HTTPS?

Browsers only allow encryption and offline features on a secure connection. Without a real certificate, Airlock cannot lock your files in the browser at all. Tailscale hands out certificates for free, and Airlock renews them for you.

Three steps

1. Get Airlock. Download the file for your computer from Releases.

Which file do I download?
Your computer File
Windows airlock_..._windows_amd64.exe
Mac (M1 or newer) airlock_..._darwin_arm64
Mac (Intel) airlock_..._darwin_amd64
Linux airlock_..._linux_amd64
Raspberry Pi, ARM server airlock_..._linux_arm64

On Mac and Linux, make it runnable first:

chmod +x airlock_*

2. Run it. Double click it, or from a terminal:

./airlock

It prints one line. That line is your address:

open https://your-computer.your-network.ts.net/ on any device on your tailnet

3. Open that address on your phone, your laptop, anywhere on your Tailscale network.

The first device picks a passphrase. Every other device enters the same one. That passphrase is what unlocks your files, and it never leaves your devices.

That's it. Drop in a file, pick a device, press Send.

Install it as an app

Airlock installs to your home screen or desktop and gets its own icon and window, like a normal app.

  • iPhone / iPad: Share button, then Add to Home Screen
  • Android: menu, then Install app
  • Windows / Mac desktop: the install icon in the address bar (Chrome or Edge)

Where the browser offers it, an Install button also appears on the Send screen, which saves hunting through a menu that moves between browser releases.

Android does not show an install option? Chrome only offers PWA installation when Android's current Home app supports pinned shortcuts. In Settings → Apps → Default apps → Home app, select Pixel Launcher or another launcher that supports pinned shortcuts, then force-stop and reopen Chrome because Chrome caches this capability for the life of its process. If every PWA is missing its install option, the launcher is the likely cause rather than Airlock's manifest.

On iPhone and iPad, install it before entering your passphrase. A browser tab and an installed app keep separate data, so a passphrase typed in the tab will not be there in the app.

Send from the Windows right-click menu

Adds Send with Airlock to the right-click menu, with the Airlock icon. Choosing it opens the app with that file staged and waiting for you to pick a destination. It works for arbitrary extensions—including .mpp and files with no extension—not just the concrete suffixes Chromium allows a PWA to declare.

Install Airlock as an app in Chrome or Edge first. The menu entry points at the launcher the browser creates when you install it, so there is nothing to point at until you have. Then, from the repository:

powershell -ExecutionPolicy Bypass -File .\deploy\windows\install-context-menu.ps1

The installer normally identifies the app's address from the browser profile. If that profile is unavailable, provide it explicitly:

powershell -ExecutionPolicy Bypass -File .\deploy\windows\install-context-menu.ps1 -Origin https://your-airlock-host:8443

Remove it the same way with uninstall-context-menu.ps1.

It needs no administrator. The installer writes one per-user registry key and copies a small PowerShell handoff script under %LOCALAPPDATA%\Airlock\Shell. The helper listens on a random 127.0.0.1 port, serves the selected file once only to your Airlock origin, then exits. It never receives your passphrase and never uploads; the file lands on the normal staging list, and the browser does the existing encryption only after you press Send.

Chrome may ask once whether Airlock can access devices on the local network. Choose Allow. The handoff is loopback-only—it cannot accept a connection from another machine—and denying it prevents the right-clicked file from being added. Airlock offers Try again if the prompt was missed.

On Windows 11 the entry appears under Show more options, which is where classic menu entries live. Shift+F10 opens that menu directly.

There is no ready-made .reg file to double-click: both the browser launcher path and the installed app identifier differ by profile, and the helper also needs the matching Airlock origin.

It says the port is in use

Something else on that machine already uses port 443, often tailscale serve. Pick another one:

./airlock --port 9443

The startup line will show the new address. Nothing else changes.

A device cannot find the server

Almost always Tailscale DNS being switched off on that device.

  • Phone or tablet: open the Tailscale app, Settings, turn on Use Tailscale DNS
  • Computer: run tailscale set --accept-dns=true

Typing the numeric address instead will not work. Airlock's certificate is issued for the name, so only the name connects.

If the name resolves but nothing loads, your Tailscale access rules may not allow that device. Check the ACLs in your admin console.

📸 Screenshots

Send The chunk strip
The Send screen with three files staged. A panel reads 3 files ready to send above green Choose files and Choose a folder buttons, a line confirms the files are sealed on this device and the server stores what it cannot read, and a row of destination chips sits above a green Send 3 files button. A finished send. A green bar is divided into segments of different widths, one per piece of the file, with a byte ruler beneath it and a caption saying the file was sent and how many of its pieces the server already had.
Drop files in, pick where they go, press one button. Nothing is chosen for you: the destination is a decision you make each time. One segment per piece, at the width that piece really occupies. Resend a file you edited and the parts that did not change are already green, which is what deduplication looks like rather than a claim about it.
Inbox History
The Inbox listing received files as cards, each with its size, when it arrived, and buttons to act on it. The History screen listing past transfers with filenames, direction and when each was cleared, ten to a page, with Newer and Older controls under the list reading 1 to 10 of 12.
What has arrived and is waiting. Saving a file clears it from the list, and anything nobody collects clears itself. What passed through, after the files themselves are gone.
On a phone Inbox on a phone Dark mode
Airlock on a phone showing the Send screen, with the drop panel, destination chips and Send button in one column above a floating bar holding Send, Inbox, History and Devices. Airlock on a phone showing the Inbox, with received files as cards above the floating navigation bar. The same Inbox in dark mode, with a near-black ground and the same green accent.
Installed to the home screen, with the switcher as a floating bar where a thumb reaches. Every arrival is a card, and the one thing to do with it is on the card. Airlock follows your system theme, and there is a switch in the bar if you would rather it did not.

📦 What it does

📁 Any size 50 GB video? Fine. Nothing is held in memory.
🔒 Private Locked on your device. The server stores what it cannot read.
Skips what it already has Send the same file twice and the second one is instant.
✏️ Sends only what changed Edit part of a big file, resend, and only that part uploads.
🔁 Survives a dropped connection Picks up where it stopped, not from zero.
📬 Waits for you Files sit on your server until a device collects them, then clear themselves.
🔔 Tells you A notification when something arrives, even with the app closed.
📱 Works everywhere Installs as an app on phone, tablet and desktop.

Why not just use...

Email Stops at 25 MB.
Google Drive, Dropbox Uploads your file to a company that can read it.
AirDrop Apple devices only, same room.
A USB stick A walk across the room, and never with your phone.
Taildrop Genuinely good, and simpler. It has no inbox, no history, and both devices must be awake. Reach for it first for a quick one-off.

❓ FAQ

Can the server read my files?

No. Your files are locked on the device sending them, before anything is uploaded, using a key made from your passphrase. That key is never sent anywhere.

The server only ever holds scrambled data. Filenames, sizes and thumbnails are locked too. This stays true even if the server is a rented VPS, and even if somebody steals its hard drive.

What if I forget my passphrase?

Your files cannot be recovered. There is no reset, because nobody holds a copy of your key, including you after you have forgotten it. That is the trade for the server never being able to read anything.

If it happens, delete Airlock's data folder and start again with a new passphrase.

How long does a file wait to be collected?

Ten minutes by default, then the server deletes it and the sender has to send it again. The point is that your own machine is not a place files pile up: it holds them only long enough to be picked up.

If your devices are not always to hand, give it longer:

./airlock --ttl-minutes 1440   # a day

A file that has been saved on a device leaves the queue immediately, without waiting for the timer.

Do I need to buy a server?

No. Any computer you already own works: a desktop, an old laptop, a Raspberry Pi. It just needs to be switched on when you want to send something.

A rented server only helps if none of your machines are reliably awake.

Does it work on iPhone and Android?

Yes, through the browser, and it installs to your home screen like an app.

For notifications while the app is closed, Chrome is the more reliable choice on Android. Firefox on Android only receives notifications while Firefox itself is running.

Open the Inbox and press Test notification to verify the subscription and Android delivery without waiting for a file. Swiping Airlock away normally still allows push; using Android's Force stop prevents notifications until the app is opened again.

Is my file safe if someone breaks into the server?

Your file contents are. An intruder gets scrambled data and cannot unlock any of it without your passphrase, which never reached that machine.

They would see device names, file sizes and timestamps, and they could delete things. Worth knowing.

Is it peer to peer?

Not any more. There was a direct device-to-device mode and it was removed after measuring it: it was about four times slower than going through the server, and it needed both devices awake at the same moment.

Tailscale already connects your devices directly. Everything Airlock sends is already locked before it leaves, so routing it through your own server costs nothing in privacy and is faster and far more reliable.

Can other people on my Tailscale network see my files?

They would need your passphrase to read anything. But on a shared network, lock it down properly:

./airlock --allow-users you@example.com --require-approval

New devices then wait for approval from a device you have already approved.

🔒 Security

Short version: your files are encrypted on your device with a key made from your passphrase. The server never sees that key.

What How
Not on the internet Only reachable inside your Tailscale network
Only your devices Tailscale proves who each device is
A lost phone Revoke it instantly, no restart needed
The server, its disk, its backups AES-256-GCM encryption
Filenames and thumbnails Encrypted too, not plain text
Tampering Every piece is verified before your file is rebuilt

What it does not protect against

  • Someone holding your unlocked phone. They have your files.
  • A forgotten passphrase. Nothing can recover it.
  • A server you do not control. It still learns who sent how much, and when.
Technical detail

Your passphrase becomes a key with PBKDF2-SHA256 at 600,000 iterations against a per-server salt, held in your browser's origin-private storage and never transmitted.

Files are split with content-defined chunking, so an edit does not shift every later boundary, which is what makes resending a changed file cheap. Each piece gets an id derived from its content and your key, so your own devices agree on ids without anyone else being able to confirm a guess about the contents.

Pieces are encrypted with AES-256-GCM. Filenames, sizes and thumbnails travel as separate encrypted records. Every piece is verified on the way back out, so a substituted or corrupted one fails loudly instead of producing a plausible wrong file.

⚙️ Options

Most people need none of these.

Flag Default What it does
--port 443 Use a different port
--data system folder Where files are stored
--ttl-minutes 10 How long an uncollected file waits before the server deletes it
--require-approval off New devices must be approved first
--allow-users you Which Tailscale accounts may connect
--version Print the version
Keeping it running in the background

Linux (systemd). Airlock needs permission to fetch its certificate:

sudo tailscale set --operator=$USER
# /etc/systemd/system/airlock.service
[Unit]
Description=Airlock
After=network-online.target tailscaled.service
Wants=network-online.target

[Service]
Type=simple
User=airlock
ExecStart=/usr/local/bin/airlock --data /var/lib/airlock
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now airlock

Windows. Create a scheduled task that runs at logon. Data is kept in %LOCALAPPDATA%\Airlock.

Full instructions are in Set up a server. For a rented VPS with Docker, see the detailed guide.

🗺 Status

Working: sending, receiving, notifications, saving, transfer history, thumbnails, device approval, skipping data you already have, resending only what changed, and resuming after a dropped connection.

Tested on real devices: Windows (Chrome, Edge, Firefox), Android (Chrome, Firefox), iPad, and a two-device network.

Not yet tested on hardware: iPhone, macOS Safari, Linux desktop.

Known limit: closing the tab mid-transfer restarts from the last confirmed piece rather than the exact byte.

🛠 For developers

Building and testing
go test ./...              # server
node --test web/*.test.mjs # client, no dependencies to install
go build -o airlock .      # the client is embedded, so this is the whole build

The client is vanilla ES modules and plain CSS. No build step, no bundler, no package.json, no framework, no CDN. Every CSS or JS edit needs go build to take effect, because the client ships inside the binary.

CI runs the full suite on Linux, macOS and Windows for every push.

How a transfer works

A file is split, fingerprinted and locked on the sending device, uploaded to the Airlock server which holds only scrambled data and never has the key, then fetched, verified, unlocked and saved on the receiving device. All of it inside your Tailscale network.

Editable source: docs/assets/transfer-flow.excalidraw, or open it in Excalidraw.

  1. The file is split into pieces along its own content, so an edit does not move every later boundary.
  2. Each piece is fingerprinted using your key.
  3. The server is asked which fingerprints it already has. That one question is what makes deduplication, partial resends and resuming all work.
  4. Only the missing pieces are encrypted and uploaded.
  5. The encrypted name, size and thumbnail land last, and that is what triggers the notification.

Full detail is in the design spec.

Measured performance
Phase Throughput
Encryption ~304 MB/s
Splitting ~1.09 GB/s
Server storage ~550 MB/s
Upload, end to end 43 to 53 MB/s
Download, end to end 66 to 109 MB/s
Rebuilding the file ~104 MB/s

Encryption is not the bottleneck, which is why there is no option to turn it off. Numbers are from one desktop (i9-14900K); phone measurements are still open. Method and caveats in docs/benchmarks.md.

📄 License

MIT. Do what you like with it.

🔗 Links

About

End-to-end encrypted file transfer between your own devices, gated by Tailscale. One Go binary, one installable web app, no native clients.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages