pipvm
Like pipx, but each installed program runs in its own virtual machine (or other type of jail).
AI-generated and unreviewed.
Motivation
pip install runs arbitrary code, and the programs it installs run with everything your user can
touch. pipx keeps their dependencies apart, but not the programs themselves. pipvm installs a
package with pipx inside a small QEMU virtual machine, then starts a fresh machine every time you
run it. The program sees a minimal Linux with no access to your files, your X server, your ssh agent
or your network (unless you ask for the network).
Only the virtual machine "backend" exists so far; the code is arranged so that others (podman, for example) can be added later.
Alternatives and prior work
This is mostly a convenience wrapper around various tools (qemu, pipx, Xephyr) you could use these directly.
Sharing data can be a pain. For tigher interaction I made a tool called [ptrace-approve] which allows you to approve individual system calls - this might be more convenient in these use cases with the price of more configuration. If your use cases are simplare you can use this.
Caveats
The most annoying thing about these tools is sharing data and resources which often make VMs unusable. I am partly making this tool as a game to practice using VMs where I can "secure" things which have easy data requirements.
There is quiter a lot of overhead of running VMs.
Usage
pipvm install cowsay # builds a base image the first time, then installs with pipx in a VM
cowsay -t "hello" # a command like pipx's: each run starts a fresh VM; stdin, stdout, stderr and exit status are forwarded
pipvm run cowsay -- -t "hello" # the same without the command on your PATH
echo hi | pipvm run --exe cat cowsay # --exe: the program to run, when it is not named like the package
pipvm run --net httpie -- example.com # let this run use the internet (it has none by default)
pipvm run --shell cowsay # a shell in the VM, to look around
pipvm list
pipvm uninstall cowsay
Options for run go before the app's name; everything after -- is passed to the program.
install writes a small script for each command the package provides into ~/.local/bin (or
$PIPVM_BIN_DIR), like pipx does. The script just runs pipvm run --exe COMMAND NAME -- "$@", so the
command always runs in a VM. A file that is already there and is not pipvm's own script is never overwritten
(pipvm says so, and you can still use pipvm run --exe). uninstall removes only the scripts pipvm wrote.
Commands started this way have no network; to give one network access run it with pipvm run --net instead.
- The program runs in the guest as an unprivileged user. QEMU itself runs as you, not root.
- A new machine is started for every run, and everything the program writes to its disk is thrown away when it stops. Programs that need to keep state between runs cannot yet.
- The guest has no network unless you pass
--net: it cannot reach the internet, your LAN or your host. - Your files are not visible to it. Pass data through standard input and output.
installdoes have network access, to fetch the package.
How it works
- The first install downloads Alpine's cloud image (checked against Alpine's published sha512) and runs a
one-off VM that installs Python, pipx and ssh into it. The result is cached in
~/.cache/pipvm, and every app is a small copy-on-write overlay on top of it, so adding an app does not copy the base. installboots the overlay with network access, runspipx installas the unprivileged user, then powers the VM off cleanly so the package is on the disk.runboots the overlay with QEMU's-snapshot(writes are discarded), waits for ssh on a port forwarded on localhost, and runs the program over ssh. The ssh streams are yours, so output arrives as the program writes it, with standard output and error kept apart.- Only a key pipvm generates (in
~/.cache/pipvm) can log into the guest.
In one test run on this machine, preparing the base image took 26 seconds (plus the download), and
starting a VM and running cowsay took about 6 seconds.
Requirements
Linux with KVM available to your user, qemu-system-x86_64, qemu-img, xorriso, and ssh. x86_64 only.
The first install needs the internet. debugfs (e2fsprogs), if present, is used to show the provisioning
log if preparing the image fails.
Limits
- A VM protects your machine from the program. It does not protect the internet from the program when
--netis on. - Programs cannot yet read or write your files, or open windows: file sharing and display are not implemented.
- QEMU and the Linux guest are themselves code that could have bugs; a VM is a stronger boundary than a container, not an absolute one.
Development
pipx install --editable .
python3 -m unittest discover -s tests
Metadata
Release files for pip-vm 0.1.1
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 |
|---|---|---|---|---|
| pip_vm-0.1.1.tar.gz | 31.0 kB | Without provenance | Details for pip_vm-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pip_vm-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for pip_vm-0.1.1-py3-none-any.whl |
Total release size: 63.0 kB
Release files / pip_vm-0.1.1.tar.gz
| Download URL | pip_vm-0.1.1.tar.gz |
|---|---|
| Size | 31.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e044b537cf69109ce53ecf8b0935a4c0d2936dfff0feeee4e1f4d9b270a7138b
|
|
BLAKE2b-256 checksum How to use checksums |
28317bce547ddd35f3b80a9186de60c56a3d433764090ee3af8cff11393a5bdf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / pip_vm-0.1.1-py3-none-any.whl
| Download URL | pip_vm-0.1.1-py3-none-any.whl |
|---|---|
| Size | 32.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4921a2ca76218fd3054031c43d189f0d556a7542b508cc1ac1e4a43fda7cfed8
|
|
BLAKE2b-256 checksum How to use checksums |
9108809e1cdbe0f3bec5cc7f8eee6e726a3fe5979e20358a7bb73d709d9f5399
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for pip-vm 0.1.1
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.