██╗ ██╗██╗███████╗██████╗
██║ ██║██║██╔════╝██╔══██╗
██║ █╗ ██║██║███████╗██████╔╝
██║███╗██║██║╚════██║██╔═══╝
╚███╔███╔╝██║███████║██║
╚══╝╚══╝ ╚═╝╚══════╝╚═╝
A VPN for the sessions you actually need.
A monthly subscription bills you for every minute of the month so you can use thirty. Wisp spins up a WireGuard server in your own cloud account, connects you, and destroys it when you're done — measured: ~30 seconds to a working tunnel on your own VPS, ~2–3 minutes on a cloud provider (the VM boot is the slow part), and a typical session costs fractions of a cent on pay-as-you-go pricing.
Why Wisp
| Subscription VPN | Always-on VPS | Wisp | |
|---|---|---|---|
| Billing | Flat, monthly | 24/7, whether you use it or not | Per session — fractions of a cent |
| Who runs the server | The provider | You | You, briefly |
| Upkeep | None | Patches, a box to forget | None — it's destroyed |
| Exit IP | Shared pool | Dedicated, tied to your account | Dedicated, tied to your account |
Who it's for: developers who already have a cloud account (or a spare VPS) and use a VPN occasionally — a few sessions a month, not all day every day.
Who it's not for: if you need an anonymous exit IP, look elsewhere — Wisp's exit IP belongs to your cloud account or your VPS, which is the point.
- Designed so nothing outlives your session. The VM is destroyed on exit —
q,Ctrl+C, closing the terminal — and an optional TTL watchdog tears down forgotten sessions. (The watchdog timer runs on your machine: if that machine is off or suspended when the TTL expires, the session survives until the nextwisp gc— andwisp gc --destroycleans up anything a crash left behind.) - Nothing to clean up by hand. Orphan detection and
wisp gccatch anything a crash left behind. - Bring your own server. Already have a VPS? Skip the cloud entirely — Wisp configures WireGuard on it over SSH and cleans up after itself.
- No sudo at runtime. The privileged daemon owns the local WireGuard interface; the CLI/TUI never elevate after installation.
Features
| Feature | What it means | |
|---|---|---|
| TUI | Interactive terminal UI | Full deploy wizard, live progress, one-key teardown |
| CLI | Scriptable subcommands | deploy, destroy, regions, gc — JSON output, tqdm progress |
| Multi-cloud | AWS · OCI · GCP | Provisioned via Pulumi; RSA 4096 SSH keys per session |
| BYO server | Custom VPS | No cloud account needed — SSH into a host you own |
| Ephemeral | Session guard | q/Ctrl+C/esc/signals/atexit all release the resources, exactly once |
| Watchdog | TTL auto-destroy | Optional OS-level timer runs wisp destroy if the session outlives its TTL |
| Garbage collection | wisp gc |
Finds and destroys leftover stacks from crashed sessions |
| No sudo at runtime | Privileged daemon | After installation the CLI/TUI never elevate; a local daemon owns wg-quick |
| Live installer output | Progress streaming | The remote WireGuard install streams into the progress bar — no frozen screens |
How it works
Wisp CLI/TUI ──Pulumi──▶ Cloud VM (AWS EC2 / OCI Compute / GCP + WireGuard)
│ ▲ │
│ └──── Paramiko (SSH) ────┘ installs & configures the server
▼
wisp daemon (privileged) ──wg-quick──▶ local WireGuard interface (wg0)
The client-side privileged daemon means the unprivileged CLI/TUI never needs
sudo to bring the local tunnel up or down; it talks to the daemon over a
group-restricted Unix socket (Linux) or Named Pipe (Windows) instead. The
session guard arms before provisioning starts, so a crashed TUI still
leaves a marker behind — the next run offers to clean it up, and the optional
TTL watchdog handles it even if nobody reopens Wisp.
Install (from source)
Requirements: Python 3.14+ (if you install via uv, it manages Python for
you — you never see this requirement), the
Pulumi CLI, and WireGuard tools — both
installed by the setup script.
# 0. Clone and enter the repo
git clone https://github.com/dosquisd/wisp.git && cd wisp
# 1. Install the CLI (isolated tool venv)
uv tool install .
# 2. Install the privileged local daemon (needs root/administrator)
sudo ./setup.sh # Linux; or: sudo ./setup.sh --skip-pulumi
./setup.ps1 # Windows (self-elevates to administrator)
Then log out and back in (or newgrp wisp) so your wisp group membership
takes effect. macOS is not supported yet (the daemon adapter is not
implemented — see MacOSAdapter in
daemon/adapter.py). A published PyPI package
with a one-command installer is planned.
Quick start
# 1. Authenticate the Pulumi backend (the deployment state lives there)
pulumi login
# 2. Configure your cloud credentials (standard SDK chains — see docs)
aws configure # or ~/.oci/config, or [gcp] in wisp.toml
# 3. Launch the TUI (or use the CLI directly)
wisp
# CLI equivalent — deploy, tunnel, destroy:
wisp deploy aws --region eu-west-1 # provisions VM + WireGuard, connects you
wisp destroy aws --region eu-west-1 # tears it all down
CLI cheat sheet
| Command | What it does |
|---|---|
wisp |
Launch the interactive TUI |
wisp deploy <provider> [-r region] |
Deploy a VPN (add --ttl 120, --wireguard-port 51820) |
wisp deploy vps --host <ip> --ssh-user root |
Configure WireGuard on a server you own |
wisp destroy <provider> [-r region] |
Tear down the tunnel + all cloud resources |
wisp regions <provider> |
List available regions (JSON) |
wisp gc [--refresh] [--destroy] |
Find and clean up leftover stacks |
Supported providers
| Provider | Provisioning | Credentials |
|---|---|---|
| AWS | Pulumi (t3.micro, most-recent Ubuntu AMI) |
Standard AWS chain (aws configure, env vars) |
| OCI | Pulumi (VM.Standard.A1.Flex, Ubuntu 24.04) |
~/.oci/config profile |
| GCP | Pulumi (SPOT e2-micro, default network) |
Service account key or ADC |
| Custom VPS | None — SSH into a host you already own | Your own SSH key ([vps] in wisp.toml) |
Note: as of this writing, Wisp ships with support for
aws,oci,gcp, andvps. The provider layer is designed to be extensible — seeProviderEnum(src/wisp/providers/base.py) andPROVIDERS_MAP(src/wisp/providers/__init__.py), or the contributing guide to add your own.
Documentation
Full documentation lives in docs/:
| Architecture | High-level design, module map, runtime data flow |
| Installation | System requirements, setup.sh / setup.ps1, daemon |
| Usage | Full CLI and TUI reference |
| Configuration | wisp.toml, WispConfig, per-provider settings |
| Deployment flow | Step-by-step deploy and destroy |
| Security model | Keys, firewall, socket permissions, trust boundaries |
| Components reference | Per-module reference |
| Contributing | Adding a provider, style, commits |
Security
Keys are per-session RSA 4096 pairs, stored 0600 and removed on destroy.
The daemon socket is group-restricted (root:wisp). Cloud credentials are
never stored by Wisp — each provider uses its standard SDK chain (the only
file Wisp ever touches is the optional [gcp].credentials_path, which you
point at; Wisp reads it, it does not manage it). Read the full
security model.
Contributing
PRs against main. The provider layer is the easiest entry point — see
adding a cloud provider.
License
MIT — Copyright (c) 2026 Juan D. Perez
Metadata
Release files for wisp-vpn 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| wisp_vpn-0.1.0.tar.gz | 120.0 kB | Without provenance | Details for wisp_vpn-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| wisp_vpn-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for wisp_vpn-0.1.0-py3-none-any.whl |
Total release size: 249.0 kB
Release files / wisp_vpn-0.1.0.tar.gz
| Download URL | wisp_vpn-0.1.0.tar.gz |
|---|---|
| Size | 120.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f228ec336e37a609120e9b872cd402822659e8563ebfefe3d0fd0366984ad303
|
|
BLAKE2b-256 checksum How to use checksums |
b885e1592e00189f13e9352244e6dd15bf3fe60a038985af9727a54fd5f99d31
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / wisp_vpn-0.1.0-py3-none-any.whl
| Download URL | wisp_vpn-0.1.0-py3-none-any.whl |
|---|---|
| Size | 129.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
99376809cbdbf8d9bf5ae6f41c8c6e613fb8f445311ea15b292acf081d9a4b68
|
|
BLAKE2b-256 checksum How to use checksums |
a2f0b8872909e3c93aade565ddb8e99f7d41374e9063cc562477cd8c3f9f527b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for wisp-vpn 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.