Secure large-file handoff
Secure Handoff
Healthcare offices often can only fax, so moving a large imaging scan from one provider to another is slow and clunky. I built a small, secure service that lets one office upload a large file with no account, and lets me pass it to the next provider behind a password, with links that expire and files that delete themselves.
It runs in production on my own server. Below is a safe, sandboxed walkthrough (nothing you do here is stored) and a short writeup of how it works. This product has no runtime AI; it was built with AI assistance, and the engineering is the point.
The handoff, step by step
How it really works
The engineering behind it
The problem
Moving a large file between two organizations is still surprisingly hard. Many offices fall back on fax or refuse attachments over a few megabytes, and a multi-gigabyte imaging scan does not fit either. Consumer file-sharing tools mean accounts, logins, and handing sensitive data to a third party. The job is narrow: let one side drop a big file with no account, and let the other side collect it behind a password, without anything lingering afterwards.
Build versus buy
A heavier off-the-shelf platform wanted more memory and moving parts than a small (1 GB) server should give to one feature. A small custom service in TypeScript on Fastify was the right call: it reuses the web server already running, streams files straight to disk so it never buffers a whole upload in memory, and keeps the security model small enough to reason about. Less to run, less to patch, less to break.
The architecture, end to end
1. Link
A high-entropy, unguessable token becomes a one-off upload link with an expiry baked in.
2. Upload
Bytes stream straight to disk in fixed-size chunks, written atomically, so a tiny server can take a huge file.
3. Notify
The owner gets a short email that a new file landed, with no sensitive detail in the message itself.
4. Download
A separate tokenized link sits behind a password gate that hides every detail until it is unlocked.
5. Expire
A background sweeper deletes links and their files on expiry, so nothing outlives its purpose.
Security decisions
- key High-entropy tokens.Upload and download links use long random tokens, so a link cannot be guessed or walked by incrementing an ID.
- password Hidden metadata until unlocked.The download view reveals the file name, size, and notes only after the password is entered, not just the bytes.
- enhanced_encryption scrypt password hashing.Download passwords are stored as salted scrypt hashes, never in plain text, so a leaked record does not leak the password.
- cookie Signed session cookies.A small signed cookie tracks an unlocked session, so the password is not re-sent on every request and cannot be tampered with.
- speed Per-IP login rate limiting.Repeated wrong passwords from one address are slowed and capped, so the gate cannot be brute-forced.
- folder_off Path-traversal defenses.Stored names are derived server-side from the token, so a crafted upload name can never escape the storage directory.
Operations decisions
- downloading Streaming to disk.Uploads are written as they arrive, never held whole in memory, so a multi-gigabyte file runs comfortably on a 1 GB box.
- save Atomic, collision-proof writes.Each upload lands at a unique path and is moved into place only once complete, so a partial or duplicate write can never be served.
- cleaning_services Background expiry sweeper.A scheduled task deletes expired links and their files, so storage does not grow without bound and data does not linger.
- database Free-disk floor.If free space drops below a threshold, new uploads are refused with a clear message rather than filling the disk and crashing the shared host.
- lan Behind nginx and TLS.The service runs as a managed background process and sits behind the existing web server, which terminates TLS in front of it.
- restart_alt Supervised with systemd.The process is supervised so it restarts cleanly on failure or reboot, and reuses the box already serving the rest of the site.
Security checklist
A quick audit view of the defenses above. Expand each for the one-line rationale.
Honest framing: the production service has no runtime AI. It was built with AI assistance (this writeup and demo included), but the running system is plain systems and security engineering. This sandbox is a faithful illustration of that system; it stores nothing and sends nothing.