A Haskell rewrite of the fine toolbox-constrained tool.
Run a Toolbx image in an isolated
podman container. Unlike toolbox enter, this does not bind-mount
your home directory or integrate with the host by default.
You explicitly choose what "capabilities" the container can access.
constrained-toolbox TOOLBOX [options] [CMD...]
The image is committed (saved) from the named toolbox container using buildah.
Examples
# Isolated shell, no host access
$ constrained-toolbox my-toolbox
# Mount current (project) directory in / and set it as the working directory
$ constrained-toolbox my-toolbox -p .
# Bind mount a volume
$ constrained-toolbox my-toolbox -v ~/data:/data
# Use capabilities from config
$ constrained-toolbox my-toolbox --cap ssh --cap git
# Read-only container filesystem
$ constrained-toolbox my-toolbox --readonly
# Remove the saved image after exit
$ constrained-toolbox my-toolbox --delete
# Set environment variables and prepend to PATH
$ constrained-toolbox my-toolbox -e MY_VAR=hello -P ~/.local/bin
# Run a specific command
$ constrained-toolbox my-toolbox -- ls /
# Dry run: print the podman command without running it
$ constrained-toolbox my-toolbox --dryrun
Usage
$ constrained-toolbox --version
0.1
$ constrained-toolbox --help
constrained-toolbox
Usage: constrained-toolbox [--version] [TOOLBOX]
[-v|--volume HOST:CONTAINER[:opts]]
[-e|--env KEY[=VALUE]] [-P|--path DIR]
[-i|--init CMD] [--cap NAME] [-p|--project DIR]
[--caps] [--readonly] [--dryrun] [--refresh]
[--delete] [CMD]
Run a toolbox image in an isolated podman container
Available options:
-h,--help Show this help text
--version Show version
-v,--volume HOST:CONTAINER[:opts]
Bind mounts (default to selinux :z)
-e,--env KEY[=VALUE] Set or pass through an environment variables
-P,--path DIR Prepend a directory to PATH inside the container
-i,--init CMD Run a bash snippet before entering the container
--cap NAME Enable a capability from the config file
-p,--project DIR Mount a project directory and set as workdir
--caps List available capabilities from the config file
--readonly Make the container filesystem read-only
--dryrun Print the podman command instead of running it
--refresh Force re-commit of the toolbox image
--delete Remove the committed image after running
Capabilities
Define reusable groups of volumes, environment variables, PATH entries,
and init commands in ~/.config/constrained-toolbox/config.toml:
[capabilities.ssh]
volumes = ["~/.ssh:~/.ssh:ro"]
[capabilities.git]
volumes = ["~/.gitconfig:ro"]
[capabilities.wayland]
env = ["WAYLAND_DISPLAY", "XDG_RUNTIME_DIR"]
volumes = ["$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY"]
security_opts = ["label=disable"]
[capabilities.rust]
path = ["~/.cargo/bin"]
Each capability can define:
volumes — list of bind mount specs
env — list of environment variables to set or pass through
path — list of directories to prepend to $PATH
init — a bash snippet to run on container startup
security_opts — list of --security-opt values passed to podman
~ and envvars are expanded in volume and path specs.
If the host and container paths are the same, you can use the shorthand
PATH[:opts] instead of PATH:PATH[:opts].
How it works
- Commits the named toolbox container to an image using
buildah commit
(reuses the existing image unless --refresh is passed)
- Runs
podman run with --userns=keep-id so you are your own user, not root
- Sets up passwordless
sudo inside the container
- Bind mounts get SELinux
:z (shared) labels automatically,
so multiple containers can safely access the same directories
- If
--delete is used, the committed image is removed after exit
Building
cabal install
Requirements
- podman and buildah
- An existing toolbox container (created with
toolbox create)