Skip to main content
██╗    ██╗██╗███████╗██████╗
██║    ██║██║██╔════╝██╔══██╗
██║ █╗ ██║██║███████╗██████╔╝
██║███╗██║██║╚════██║██╔═══╝
╚███╔███╔╝██║███████║██║
 ╚══╝╚══╝ ╚═╝╚══════╝╚═╝

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.

Wisp TUI — deploy, tunnel, destroy

Python License Platform Providers

Installation · Quick start · Documentation · Contributing


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 next wisp gc — and wisp gc --destroy cleans up anything a crash left behind.)
  • Nothing to clean up by hand. Orphan detection and wisp gc catch 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 PyPI)

Wisp is published on PyPI as wisp-vpn — it needs Python 3.12+ (with uv, Python itself is managed for you).

On Linux, the one-command installer sets everything up (uv, the wisp-vpn CLI, WireGuard tools, the optional Pulumi CLI, and the privileged daemon):

curl -fsSL https://raw.githubusercontent.com/dosquisd/wisp-vpn/HEAD/scripts/install.sh | bash

Rather manage the CLI yourself with your tool manager of choice?

uv tool install wisp-vpn      # uv manages its own Python
# or
pipx install wisp-vpn         # uses your system Python — it must be 3.12+

Then add the privileged daemon (and WireGuard tools, which the one-command installer covers for you):

sudo wisp daemon install

On Windows, the self-contained PowerShell installer needs no repository checkout:

Set-ExecutionPolicy -Scope Process Bypass
irm https://raw.githubusercontent.com/dosquisd/wisp-vpn/HEAD/scripts/install.ps1 | iex

This installs WireGuard, Pulumi, the Wisp daemon, and its native Windows service. To skip Pulumi, use .\scripts\install.ps1 -SkipPulumi from a local checkout. To remove Wisp later while preserving shared tools and user data:

irm https://raw.githubusercontent.com/dosquisd/wisp-vpn/HEAD/scripts/uninstall.ps1 | iex

The uninstaller removes the Wisp daemon, CLI, group, user data, and dependencies that the Wisp installer originally installed. Dependencies that were already present are preserved. Destroy any active session before uninstalling; uninstalling the client does not remove cloud resources.

See the installation guide for Linux flags and the Windows install/uninstall options.

Install (from source)

Requirements: Python 3.12+ (with uv, Python itself is managed for you — you never see this requirement), the Pulumi CLI, and WireGuard tools — the one-command installer above covers both on Linux; scripts/install.ps1 covers them on Windows.

# 0. Clone and enter the repo
git clone https://github.com/dosquisd/wisp-vpn.git && cd wisp-vpn

# 1. Install the CLI (isolated tool venv)
uv tool install .

# 2. Install the privileged local daemon (needs root/administrator)
sudo wisp daemon install      # Linux
.\scripts\install.ps1        # Windows (self-elevates only daemon setup)

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). The PyPI package with the one-command installer above is the recommended path; the steps in this section are for a source checkout.

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, and vps. The provider layer is designed to be extensible — see ProviderEnum (src/wisp/providers/base.py) and PROVIDERS_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, install.sh / install.ps1 / uninstall.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.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wisp-vpn 0.1.3
File Size Uploaded Provenance Actions
wisp_vpn-0.1.3.tar.gz 127.2 kB Without provenance Details for wisp_vpn-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wisp-vpn 0.1.3
File Interpreter ABI Platform Actions
wisp_vpn-0.1.3-py3-none-any.whl Python 3 none any Details for wisp_vpn-0.1.3-py3-none-any.whl

Total release size: 260.6 kB

Release files / wisp_vpn-0.1.3.tar.gz

Download URL wisp_vpn-0.1.3.tar.gz
Size 127.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3e32504c74f7c87442014943dca607679dd2fcc38a95c429b671d526d779b8ba
BLAKE2b-256 checksum
How to use checksums
5a1491471663cf42bc74d1d9cbe6500aacf26345e89c102867bd443526058dd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / wisp_vpn-0.1.3-py3-none-any.whl

Download URL wisp_vpn-0.1.3-py3-none-any.whl
Size 133.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
56701aa4bda835d3987acd30f13714f3376af75942e6d8b39e665914afc5e45c
BLAKE2b-256 checksum
How to use checksums
f9536b32c4128d35d13f7c53c377118c7e1be0ef9d4840cff26e70d16f7d741b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for wisp-vpn 0.1.3

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page