A clean, personal SFTP server for Windows: pick a folder, add a user (or hit Quick Start), and hand someone a ready-to-paste connection card. Each user is locked to their own folder, sign-in is by password or key, and you watch connections and transfers live. Secure connections only.
Built by JDE-Projects, home of the Simple X Tools suite.
If you enjoyed this project and would like to buy me a coffee, check out my Ko-fi.
- Quick Start: one click brings a full-access share live with a fresh random password in a copyable connection card.
- Users with a per-user folder (a real folder picker, or "Make folder"), and a jail so each user only ever sees inside their own folder.
- Three access modes per user: read-only, read & write, or upload-only (a drop box). Deleting and renaming is off unless you allow it.
- Sign-in by password, public key, or both, with a built-in Ed25519 (default) or RSA-4096 key generator for users who have none.
- Connection card: LAN address, on-demand public IP, port, and the host-key fingerprint, all copyable for first-connection verification.
- Live panel: connected clients with what each one is doing right now (listing a folder, reading file details, transferring), running request counts and bytes moved, in-flight transfers, a recent-activity feed, and locked-out IPs with one-click Unlock.
- Brute-force lockout: repeated failed logins block that account for fifteen minutes, with an address-level backstop against password spraying and a manual override.
- Concurrent connections are capped, per address and overall, so a flood of half-open connections can't exhaust the server.
- Default port 2222 (no admin needed), with a plain-language message if a port is already in use, plus a pre-flight port check.
- Built-in check for updates against GitHub Releases.
- Optional debug log, off by default; no passwords or key material are written to it.
- Secure transport only: weak or vulnerable algorithms are disabled, so the server runs securely or fails with a clear message (no unsafe fallback).
- Backend: paramiko over SSH/SFTP, one jailed session per connection.
- Config:
server_config.jsonnext to the app (usernames, folders, settings, and one-way bcrypt password hashes; never a plaintext password). - Host identity: an Ed25519 host key generated on first run and kept next to the app, so its fingerprint stays stable for clients to trust.
- Window: pywebview on the Qt backend, UI in
simple_sftp_server-UI.html.
Two ways to get it from the Releases page - pick one:
- Installer (recommended): download
SimpleSFTPServer-vX.Y.Z-setup.exeand run it. It installs the app, adds a Start menu shortcut, and can be removed later from Add or Remove Programs. Installs just for you by default (no admin needed); you can choose all users during setup. - Portable .zip: download
SimpleSFTPServer-vX.Y.Z.zip, extract it, and runSimple SFTP Server.exefrom inside the extracted folder. No install - good for a locked-down PC or a USB stick. Keep the folder together; the exe needs the files next to it.
Or install the same installer from the command line with WinGet:
winget install --exact --id JDE-Projects.SimpleSFTPServer
Either way: Windows only, no Python or setup required. Unsigned, so SmartScreen may warn the first time: More info > Run anyway. On first connection a client also needs your firewall to allow the port, and for access from outside your network, a port-forward to this machine.
Simple SFTP Server doesn't update itself. The bottom bar has a Check for updates button that tells you when a newer release is out; when it does, get the new version from the Releases page the same way you first installed it.
- Installer: download the new
SimpleSFTPServer-vX.Y.Z-setup.exeand run it. It installs over your current copy and keeps your saved users, folders, and theme choice. - Portable .zip: download and extract the new
SimpleSFTPServer-vX.Y.Z.zip. To keep your saved users and settings, copyserver_config.jsonfrom the old folder into the new one. Also copyhost_ed25519, the server's host key, so its fingerprint stays the same for clients who already trust it; otherwise every client will see a fingerprint-changed warning on first reconnect. Copysimple_sftp_server.preftoo, for your theme choice. - WinGet: run
winget upgrade --exact --id JDE-Projects.SimpleSFTPServer. It runs the installer over your current copy, same as the Installer option above. The WinGet listing can trail a new release by a few days while Microsoft reviews it.
Saved-user passwords exist only as bcrypt hashes inside server_config.json,
so there's nothing else to carry over.
This release was built on GitHub from this public source, not on a personal machine, and is signed with a build-provenance attestation. To confirm your download is genuine, install the GitHub CLI and run:
gh attestation verify SimpleSFTPServer-vX.Y.Z.zip \
--repo JDE-Projects/Simple-SFTP-Server \
--signer-repo JDE-Projects/Build-Tools
A Verification succeeded! line means the file was built by the published
pipeline from this repo. You can also check the file against the published
.sha256.
- Python 3 on PATH.
pip install -r requirements.txt(pinned versions: PySide6, pywebview, paramiko, cryptography, bcrypt, and PyInstaller)- Keep
simple_sftp_server.py,simple_sftp_server-UI.html, thefonts/folder, the.ico, and.pngtogether. - Run from source:
python simple_sftp_server.py - Build the .exe:
Build_Simple_SFTP_Server.bat->dist\Simple SFTP Server\Simple SFTP Server.exe
- Quick Start for an instant share: click it, reveal the password, and send
the connection card. The share folder is
QuickStart-Sharenext to the app, with full access (read, write, delete, rename). - For anything narrower, add a user instead: set a username, a folder, an access mode, and a password or public key. That user is locked to that folder.
- Press Start (or Quick Start) and give the other person the address, port, and their sign-in details from the connection card. Have them verify the host-key fingerprint on first connection.
- Watch the Live panel for who is connected and what is transferring. Unlock an address if it gets locked out after failed logins.
- Generate an Ed25519 or RSA key pair for a user who needs one and hand them the private key. The public key is filled into the user form, but it is only saved to the account when you click Save, alongside any keys already listed (it does not replace them).
The first time the server starts listening, Windows shows its own one-time "Windows Security Alert" popup asking whether to allow the app through Windows Defender Firewall. Clicking Allow needs administrator rights. If you are not an administrator, or you dismiss or deny the popup, no allow rule is created (and Windows may even add a block rule), so inbound connections stay blocked with no further prompt on later launches.
If that happens, an administrator can add an allow rule after the fact in Windows Defender Firewall (Control Panel > Windows Defender Firewall > Advanced settings > Inbound Rules), allowing the app or the chosen port for the profile you use (Private, Public, or Domain).
The app also runs a quick, read-only check of the Windows Firewall state after it starts, and shows an amber warning in Connection Details if it looks like the firewall may be blocking the chosen port. That check only sees Windows Defender Firewall, so it cannot detect a third-party firewall (common in some antivirus suites) or a router blocking the connection; no warning does not guarantee a client on another network can reach you.
For access from outside your local network, forward the chosen port on your router to this machine's LAN address, in addition to allowing it locally. Third-party firewalls, if you run one, may also need the port opened separately from Windows Defender Firewall.
- Saved-user passwords are stored only as a one-way bcrypt hash and are never shown again after you save them. Public-key users store only their public key text. No plaintext password is ever written to disk.
- The Quick Start password lives in memory only, is revealable as often as you like while it runs, and is wiped when you stop it; every launch makes a new one.
- Generated passwords use a cryptographic random source: 20 characters, no look-alikes, with letters, digits, and symbols guaranteed.
- Each user is jailed to their folder; paths that try to escape it are refused.
- Failed logins are rate-limited per account (five strikes, fifteen-minute lockout), with a wider address-level backstop against spraying across usernames, plus a manual unlock.
- Only modern, secure key-exchange, ciphers, and MACs are offered; known-weak algorithms are disabled. There is no "compatibility" downgrade.
- The host key persists next to the app so its fingerprint is stable; treat that file as private and do not commit it.
- The optional debug log is off by default; when on it writes
Debug_Log_MMDDYYYY_HHMMSS.txtnext to the app. It records activity and errors but no passwords or key material, and a redaction pass on every entry enforces that even for captured error traces. - Network use. Other than the job you ask of it, this app makes one automatic network call: a check to GitHub for a newer release (at startup and when you press Check for updates), which sends only a version request. It collects and sends no personal data, usage data, or analytics.
This project was built with AI assistance. The design decisions, feature direction, and real-world testing were directed by me. The code was written and revised with an AI assistant against that direction. Treat it like any community tool: review and test it before relying on it.
Released under the PolyForm Noncommercial License 1.0.0 (see LICENSE). Personal and any noncommercial use, modification, and noncommercial redistribution are permitted; commercial use is not. Keep the copyright notice; no warranty. This tool bundles third-party code; see THIRD-PARTY-LICENSES.txt.
For commercial licensing, open a GitHub issue with the title "Commercial License Inquiry".
