Skip to main content

Composable bubblewrap sandboxes.

Project description

Hozo

Simple wrapper around bubblewrap that provides composable profiles for sandboxing.

Read/write/network access are all deny by default except for a minimal set of directories.

Note: Hozo uses bubblewrap and is still subject to its limitations. It's not a full isolation solution, but it does make it easier to run untrusted code with a sane default policy and a few composable profiles. This won't protect you against entirely malicious code or kernel exploits, but will help avoid accidentally leaking secrets/files, and also reduce the blast radius of a misbehaving tool.

Requirements

  • Linux with bubblewrap (bwrap). Other OSes are not supported.
  • Python ≥ 3.11. Proxy mode also needs python3 inside the sandbox.

Install

uv tool install hozo
hozo --help

Quick start

hozo +untrusted -- make test          # no network, no secrets, cwd writable
hozo +untrusted -- bash               # sandboxed shell
hozo explain +untrusted -- echo hi    # shows what bwrap args would be used
hozo +node +proxy -- npm install      # network limited to the npm registry
hozo --allow-net=pypi.org -- pip install requests   # grant just this host
hozo --allow-read=/etc/hosts +untrusted -- cat /etc/hosts
hozo profile list                     # built-in + your profiles

By default, the current directory is mounted read-write at the same path inside the sandbox. So if you're in /home/user/myproject, then /home/user/myproject is mounted read-write inside the sandbox. Other adjacent directories like /home/user/myotherproject are NOT visible.

This allows you to run commands like make or pytest in a sandboxed environment without worrying about them accessing other files on your system.

Profiles

Profiles are composable YAML files that define what is allowed inside the sandbox. Multiple profiles can be combined and merged to create a final policy for the sandbox.

Several built-in profiles are provided with Hozo, but you can create your own custom profiles by putting them in ~/.config/hozo/profiles/<name>.yaml. Built-in profiles can also be overridden by a user profile of the same name.

hozo profile list shows what's available. hozo explain +a +b -- cmd shows the merged result.

Policies

Profiles are deny-by-default. The base profile always applies, and other profiles can be added to grant more access.

Network is also off by default. The +proxy profile enables egress through a host-side proxy, but still allows no hosts by default. Grant hosts with --allow-net=HOST,HOST.

Ad-hoc allows can be granted on the cli:

  • --allow-net=HOST,HOST allows connecting to these hosts via the proxy
  • --allow-net with no value opens full host networking, no proxy required
  • --allow-read=PATH,PATH / --allow-write=PATH,PATH allows reading/writing to specific paths.

Network egress

Network egress is off by default. There are three modes:

  • Allow all egress.
  • Allow egress to specific hosts.
  • No egress at all.
hozo +proxy -- curl https://pypi.org/                        # blocked: no hosts granted
hozo --allow-net=pypi.org -- curl https://pypi.org/simple/   # 200
hozo --allow-net=pypi.org -- curl https://example.com/       # blocked: 403
hozo +python +proxy -- uv pip install ruff                   # +python grants PyPI, +proxy enables egress

Everyday use

To launch a tool sandboxed without typing the full command each time, use a shell alias:

alias claude='hozo +claude -- claude'

The sandbox home is wiped each run. To persist a tool's login/config, bind a host dir over the sandbox home in a profile:

# ~/.config/hozo/profiles/claude-home.yaml
name: claude-home
binds:
  - { source: "~/.hozo/claude", target: /home/{user}, mode: rw }

Development

uv run pytest
uv run ruff check src tests
uv run black src tests

Status

This is a personal project for my own needs. Use at your own risk. Issues and PRs welcome.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hozo-0.1.0.tar.gz (40.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hozo-0.1.0-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file hozo-0.1.0.tar.gz.

File metadata

  • Download URL: hozo-0.1.0.tar.gz
  • Upload date:
  • Size: 40.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for hozo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f39d2b6a42914b35ee62a550cbbabc380181a8e6b13025c94d3d80516978d287
MD5 82f71762cfc72ac9487e197725dfcc5f
BLAKE2b-256 83947facd7841062249c15c6f36bf42d8129cc4f7e40cd070d948d0bd7b4c737

See more details on using hashes here.

Provenance

The following attestation bundles were made for hozo-0.1.0.tar.gz:

Publisher: pypi-publish.yml on justyns/hozo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hozo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: hozo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for hozo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 48d7439035c169f3188542c361801805a465a574b5b1b458cad6d498d7368b87
MD5 9f52ddeaccbfda729ba36b608aecf45e
BLAKE2b-256 6f292b517ba0da15511a490c372231a453e81770a28e46a7e0c502d13378bf5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for hozo-0.1.0-py3-none-any.whl:

Publisher: pypi-publish.yml on justyns/hozo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page