Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Built-in Recipes

This file is auto-generated by can-docgen. Do not edit manually.

Canister ships with the following recipe files in the recipes/ directory. The base.toml and default.toml recipes are embedded in the binary.

Overview

RecipeDescriptionAuto-detected
base.tomlEssential OS paths for any Linux binaryNo
cargo.tomlRust/Cargo toolchain ($HOME/.cargo, $HOME/.rustup)Yes ($HOME/.cargo, $HOME/.rustup)
default.tomlDefault baseline — common syscalls for any Linux process. Blocks dangerous kernel operations and namespace escapes.No
elixir.tomlElixir/Erlang development: mix tasks, iex, Phoenix serverNo
example.tomlExample recipe showing all available optionsNo
flatpak.tomlFlatpak applicationsYes (/var/lib/flatpak, $HOME/.local/share/flatpak)
generic-strict.tomlStrict no-network policy for untrusted binaries (CI/production)No
gnu-store.tomlGNU Guix package manager (/gnu/store)Yes (/gnu/store)
homebrew.tomlHomebrew/Linuxbrew package managerYes (/opt/homebrew, /home/linuxbrew/.linuxbrew)
neovim.tomlNeovim editor with LSP, tree-sitter, and plugin supportNo
nix.tomlNix package manager (/nix/store)Yes (/nix/store)
node-build.tomlNode.js build tasks: npm install, build, testNo
opencode.tomlOpenCode AI coding agent with scoped filesystem and restricted networkNo
python-pip.tomlInstall Python packages with pip (network access to PyPI)No
snap.tomlSnap package manager (/snap)Yes (/snap)

Recipe Contents

base.toml

# Canister base recipe — essential OS bind mounts.
#
# This recipe provides the minimal set of system paths required for any
# Linux binary to execute inside the sandbox. It replaces the hardcoded
# ESSENTIAL_BIND_MOUNTS list for auditability and customization.
#
# Composition order: base.toml is always loaded first, before default.toml,
# auto-detected recipes, and explicit --recipe arguments.
#
# Override: Place a base.toml in $XDG_CONFIG_HOME/canister/recipes/ or
# ./.canister/ to customize. The embedded copy is used as fallback.

[recipe]
name = "base"
description = "Essential OS paths for any Linux binary"
version = "2"

[filesystem]
# Paths bind-mounted read-only for basic execution. These provide:
# - Shell utilities and system binaries (/bin, /sbin, /usr/bin, /usr/sbin)
# - Shared libraries and the dynamic linker (/lib, /lib64, /usr/lib, /usr/lib64)
# - Locally installed binaries and libraries (/usr/local/bin, /usr/local/lib)
# - Shared data files (/usr/share)
# - Dynamic linker cache and configuration (/etc/ld.so.*)
# - DNS and network resolution (/etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts)
# - TLS certificates (/etc/ssl, /etc/ca-certificates)
# - Timezone data (/etc/localtime)
# - Alternatives system (/etc/alternatives)
# - User/group databases (/etc/passwd, /etc/group) — needed by Go, Python, etc.
# - Temporary file directory (/tmp) — isolated per sandbox via overlay
allow = [
    "/bin",
    "/sbin",
    "/lib",
    "/lib64",
    "/usr/bin",
    "/usr/sbin",
    "/usr/lib",
    "/usr/lib64",
    "/usr/local/bin",
    "/usr/local/lib",
    "/usr/share",
    "/tmp",
    "/etc/ld.so.cache",
    "/etc/ld.so.conf",
    "/etc/ld.so.conf.d",
    "/etc/resolv.conf",
    "/etc/nsswitch.conf",
    "/etc/hosts",
    "/etc/ssl",
    "/etc/ca-certificates",
    "/etc/localtime",
    "/etc/alternatives",
    "/etc/passwd",
    "/etc/group",
]

deny = [
    "/etc/shadow",
    "/etc/gshadow",
]

cargo.toml

# Canister recipe for Cargo (Rust) toolchain.
#
# Cargo installs binaries to $HOME/.cargo/bin and stores the toolchain
# (rustc, rustup) under $HOME/.rustup. Both are needed for Rust
# compilation and tool execution.
#
# Auto-detection: triggered by match_prefix (uses env var expansion)

[recipe]
name = "cargo"
description = "Rust/Cargo toolchain ($HOME/.cargo, $HOME/.rustup)"
version = "1"
match_prefix = ["$HOME/.cargo", "$HOME/.rustup"]

[filesystem]
allow = ["$HOME/.cargo", "$HOME/.rustup"]
deny = ["$HOME/.cargo/credentials.toml", "$HOME/.cargo/credentials"]

default.toml

# Default baseline — the canonical syscall policy for Canister.
#
# This file defines the base set of allowed and denied syscalls used by
# every sandbox invocation. It is embedded into the binary via
# include_str!() as a fallback, but can be overridden by placing a
# default.toml in the recipe search path:
#
#   1. ./.canister/default.toml              (project-local)
#   2. $XDG_CONFIG_HOME/canister/recipes/  (per-user)
#   3. /etc/canister/recipes/              (system-wide)
#
# Regular recipes extend this baseline with allow_extra / deny_extra.
# Only the baseline itself uses the absolute allow / deny fields.

[recipe]
name = "default"
description = "Default baseline — common syscalls for any Linux process. Blocks dangerous kernel operations and namespace escapes."
version = "1"

[syscalls]
# Absolute allow list — syscalls needed by virtually any Linux process:
# libc init, memory allocation, signal handling, file I/O, threading.
#
# Recipes MUST NOT use these fields — they use allow_extra / deny_extra
# to layer on top of this baseline.
allow = [
    # Process lifecycle
    "fork",
    "vfork",
    "clone",
    "clone3",
    "execve",
    "kill",
    "tkill",
    "tgkill",
    "exit",
    "exit_group",
    "wait4",
    "waitid",

    # Process control (prctl only — ptrace, personality, seccomp per-recipe)
    "prctl",

    # File I/O
    "open",
    "openat",
    "openat2",
    "creat",
    "close",
    "close_range",
    "read",
    "write",
    "readv",
    "writev",
    "pread64",
    "pwrite64",
    "lseek",
    "dup",
    "dup2",
    "dup3",
    "fcntl",
    "flock",
    "fsync",
    "fdatasync",
    "truncate",
    "ftruncate",
    "fallocate",

    # File metadata
    "stat",
    "fstat",
    "lstat",
    "newfstatat",
    "statx",
    "access",
    "faccessat",
    "faccessat2",
    "chmod",
    "fchmod",
    "fchmodat",
    "chown",
    "fchown",
    "lchown",
    "fchownat",

    # Directory operations
    "mkdir",
    "mkdirat",
    "rmdir",
    "rename",
    "renameat",
    "renameat2",
    "link",
    "linkat",
    "unlink",
    "unlinkat",
    "symlink",
    "symlinkat",
    "readlink",
    "readlinkat",
    "getdents",
    "getdents64",

    # Memory
    "mmap",
    "mprotect",
    "munmap",
    "mremap",
    "madvise",
    "msync",
    "brk",
    "mlock",
    "mlock2",
    "munlock",
    "mlockall",
    "munlockall",

    # Network
    "socket",
    "connect",
    "accept",
    "accept4",
    "bind",
    "listen",
    "sendto",
    "recvfrom",
    "sendmsg",
    "sendmmsg",
    "recvmsg",
    "shutdown",
    "getsockopt",
    "setsockopt",
    "getsockname",
    "getpeername",
    "socketpair",

    # Signals
    "rt_sigaction",
    "rt_sigprocmask",
    "rt_sigreturn",
    "rt_sigsuspend",
    "sigaltstack",

    # Time
    "nanosleep",
    "clock_nanosleep",
    "clock_gettime",
    "clock_getres",
    "gettimeofday",

    # Polling / async I/O
    "poll",
    "ppoll",
    "select",
    "pselect6",
    "epoll_create",
    "epoll_create1",
    "epoll_ctl",
    "epoll_wait",
    "epoll_pwait",
    "epoll_pwait2",
    "eventfd",
    "eventfd2",
    "timerfd_create",
    "timerfd_settime",
    "timerfd_gettime",

    # File monitoring
    "inotify_init",
    "inotify_init1",
    "inotify_add_watch",
    "inotify_rm_watch",

    # IPC
    "pipe",
    "pipe2",
    "shmget",
    "shmat",
    "shmctl",
    "shmdt",
    "semget",
    "semop",
    "semctl",
    "msgget",
    "msgsnd",
    "msgrcv",
    "msgctl",

    # Process info
    "getpid",
    "getppid",
    "getuid",
    "getgid",
    "geteuid",
    "getegid",
    "gettid",
    "getpgid",
    "getpgrp",
    "setpgid",
    "setsid",
    "getgroups",
    "setgroups",
    "setuid",
    "setgid",
    "setreuid",
    "setregid",
    "setresuid",
    "setresgid",

    # I/O control + legacy AIO
    "ioctl",
    "io_setup",
    "io_submit",
    "io_getevents",
    "io_destroy",

    # Misc / threading
    "futex",
    "set_tid_address",
    "set_robust_list",
    "get_robust_list",
    "sched_yield",
    "sched_getaffinity",
    "sched_setaffinity",
    "sched_setscheduler",
    "sched_getscheduler",
    "rseq",
    "getcwd",
    "chdir",
    "fchdir",
    "umask",
    "uname",
    "sysinfo",
    "getrusage",
    "getrandom",
    "prlimit64",
    "pidfd_open",
    "copy_file_range",
    "sendfile",
    "splice",
    "tee",

    # Arch-specific
    "arch_prctl",
]

# Absolute deny list — dangerous kernel operations that a sandboxed
# process should never need. Always denied regardless of mode.
deny = [
    "reboot",
    "kexec_load",
    "init_module",
    "finit_module",
    "delete_module",
    "swapon",
    "swapoff",
    "acct",
    "mount",
    "umount2",
    "pivot_root",
    "chroot",
    "syslog",
    "settimeofday",
    # Namespace escapes — a sandboxed process must never create new
    # namespaces or join existing ones.
    "unshare",
    "setns",
    # In-memory code execution — memfd_create + execveat enables fileless
    # execution, a common technique for running malicious payloads without
    # touching disk. Recipes that legitimately need these (e.g., BEAM VM)
    # can opt in via allow_extra.
    "memfd_create",
    "execveat",
]

elixir.toml

# Canister recipe for Elixir/Erlang workloads.
#
# The BEAM VM needs ptrace for :observer, :dbg, and erlang:trace/3.
# This recipe adds BEAM-specific syscalls, Hex.pm network access, and
# BEAM environment variables. System paths are provided by base.toml.
#
# Usage:
#   can run -r elixir -- mix test
#   can run -r elixir -r nix -- iex -S mix

[recipe]
name = "elixir-dev"
description = "Elixir/Erlang development: mix tasks, iex, Phoenix server"
version = "2"

# Strict mode: abort if any isolation layer cannot be set up.
# Recommended for CI. Uncomment to enable.
# strict = true

[syscalls]
# BEAM needs ptrace for tracing/debugging tools (:observer, :dbg).
# BEAM uses memfd_create for JIT code loading (moved to deny list in default baseline).
allow_extra = ["ptrace", "memfd_create"]

[filesystem]
deny = ["/etc/shadow", "/root"]

[network]
egress = "proxy-only"
# Allow hex.pm for dependency fetching and common Elixir registries.
[[host]]
domain = "hex.pm"

[[host]]
domain = "repo.hex.pm"

[[host]]
domain = "builds.hex.pm"

[[host]]
domain = "github.com"
[process]
# BEAM spawns many lightweight processes via OS threads; the default
# scheduler count equals the CPU core count. 256 is generous for most
# mix tasks and development servers.
max_pids = 256
# Environment variables the BEAM commonly needs.
env_passthrough = [
    "PATH",
    "HOME",
    "LANG",
    "TERM",
    "MIX_ENV",
    "MIX_HOME",
    "HEX_HOME",
    "ERL_AFLAGS",
    "ELIXIR_ERL_OPTIONS",
    "RELEASE_COOKIE",
    "RELEASE_NODE",
    "RELEASE_DISTRIBUTION",
    "SECRET_KEY_BASE",
    "DATABASE_URL",
    "PHX_HOST",
    "PHX_SERVER",
    "PORT",
]

example.toml

# Example Canister recipe — a complete sandbox policy for Python scripts.
#
# System paths (/usr/lib, /usr/bin, /lib, /tmp, etc.) are provided by
# base.toml — recipes only need to add application-specific paths.
#
# Usage: can run -r example -- python3 script.py

[recipe]
name = "example"
description = "Example recipe showing all available options"
version = "2"

# Strict mode: abort if any isolation layer cannot be set up.
# Recommended for CI. Uncomment to enable.
# strict = true

[filesystem]
# Paths the sandboxed process can read (mounted read-only).
# System paths are already provided by base.toml — only add app-specific paths here.
allow = []
# Paths the sandboxed process can write to (changes persist on host).
# The working directory ($PWD) is always writable. Uncomment for additional paths:
# allow_write = ["/var/data/myapp"]
# Paths explicitly denied (checked before allow and allow_write).
deny = ["/etc/shadow", "/root"]

[network]
egress = "proxy-only"
# Allowed IPs or CIDRs for direct connections. Empty = no IP-literal
# egress; everything must go through the DNS-resolved `[[host]]` list
# below.
allow_ips = []

# Allowed upstream destinations. The proxy refuses any other host.
[[host]]
domain = "pypi.org"

[[host]]
domain = "files.pythonhosted.org"

[process]
# Max child PIDs.
max_pids = 64
# Restrict which executables the sandbox may run (optional, opt-in).
# By default, all executables are allowed — the real security boundaries
# are network, filesystem, and seccomp. Uncomment to lock down:
# allow_execve = ["/usr/bin/python3"]
# Environment variables passed through from host.
env_passthrough = ["PATH", "HOME", "LANG", "TERM"]

# [resources] section — cgroup v2 resource limits (optional).
# Requires cgroups v2 on the host. Uncomment to enable:
# [resources]
# memory_mb = 512
# cpu_percent = 50

# [syscalls] section — customize the default seccomp baseline.
# Uncomment to add or remove specific syscalls:
# [syscalls]
# seccomp_mode = "allow-list"
# allow_extra = ["ptrace"]        # add ptrace to the allow list
# deny_extra = ["personality"]    # remove personality from allow, add to deny

flatpak.toml

# Canister recipe for Flatpak applications.
#
# Flatpak installs applications under /var/lib/flatpak (system-wide)
# and $HOME/.local/share/flatpak (per-user).
#
# Auto-detection: triggered by match_prefix

[recipe]
name = "flatpak"
description = "Flatpak applications"
version = "1"
match_prefix = ["/var/lib/flatpak", "$HOME/.local/share/flatpak"]

[filesystem]
allow = ["/var/lib/flatpak", "$HOME/.local/share/flatpak"]

generic-strict.toml

# Canister recipe for strict-mode execution of arbitrary binaries.
#
# Enables strict mode: any setup failure is fatal, seccomp uses
# KILL_PROCESS. No network access. Minimal filesystem (base.toml only).
# Intended for CI pipelines and production jobs where security is paramount.
#
# Usage:
#   can run -r generic-strict -- ./my-binary --flag
#   can run -r generic-strict -- cargo test

strict = true

[recipe]
name = "generic-strict"
description = "Strict no-network policy for untrusted binaries (CI/production)"
version = "2"

[syscalls]
# For compiled binaries that may use ptrace (debuggers), io_uring
# (modern async I/O), personality (multilib), or seccomp (self-sandboxing).
allow_extra = [
    "ptrace",
    "personality",
    "seccomp",
    "io_uring_setup",
    "io_uring_enter",
    "io_uring_register",
]

[filesystem]
deny = ["/etc/shadow", "/root", "/home"]

[network]
egress = "none"

[process]
max_pids = 64
env_passthrough = ["PATH", "LANG", "TERM"]

gnu-store.toml

# Canister recipe for GNU Guix package manager.
#
# Guix uses a content-addressed store at /gnu/store, similar to Nix.
# Binaries reference sibling store entries, so the entire store must
# be mounted.
#
# Auto-detection: triggered by match_prefix

[recipe]
name = "gnu-store"
description = "GNU Guix package manager (/gnu/store)"
version = "1"
match_prefix = ["/gnu/store"]

[filesystem]
allow = ["/gnu/store"]

homebrew.toml

# Canister recipe for Homebrew (Linuxbrew) package manager.
#
# On Linux, Homebrew installs to /home/linuxbrew/.linuxbrew or
# /opt/homebrew (rare on Linux, common path on macOS). Binaries
# reference the Cellar and shared libraries within the prefix.
#
# Auto-detection: triggered by match_prefix

[recipe]
name = "homebrew"
description = "Homebrew/Linuxbrew package manager"
version = "1"
match_prefix = ["/opt/homebrew", "/home/linuxbrew/.linuxbrew"]

[filesystem]
allow = ["/opt/homebrew", "/home/linuxbrew/.linuxbrew"]

neovim.toml

# Canister recipe for Neovim with LSP support.
#
# Mounts the user's full Neovim configuration (config, data, state, cache)
# so plugin managers (lazy.nvim), LSP servers (via Mason), tree-sitter
# parsers, and other tooling work out of the box.
#
# System paths (/usr/lib, /usr/bin, /lib, /tmp, etc.) are provided by
# base.toml — this recipe only adds Neovim-specific paths.
#
# Usage:
#   can run -r neovim -- nvim
#   can run -r neovim -r elixir -r nix -- nvim

[recipe]
name = "neovim"
description = "Neovim editor with LSP, tree-sitter, and plugin support"
version = "2"

[filesystem]
allow = [
    # Neovim XDG directories
    "$HOME/.config/nvim",
    "$HOME/.local/share/nvim",
    "$HOME/.local/state/nvim",
    "$HOME/.cache/nvim",
]
deny = ["/etc/shadow", "/root"]

[network]
egress = "proxy-only"
# LSP servers, Mason, and plugin managers may need network access
# for installation and updates. Lock down to known hosts.
[[host]]
domain = "github.com"

[[host]]
domain = "objects.githubusercontent.com"

[[host]]
domain = "raw.githubusercontent.com"

[[host]]
domain = "api.github.com"

[[host]]
domain = "registry.npmjs.org"

[[host]]
domain = "pypi.org"

[[host]]
domain = "files.pythonhosted.org"

[[host]]
domain = "luarocks.org"

[[host]]
domain = "github.com"
[process]
max_pids = 256
allow_execve = []
env_passthrough = [
    "PATH",
    "HOME",
    "LANG",
    "TERM",
    "COLORTERM",
    "TERMINFO",
    "USER",
    "SHELL",
    "EDITOR",
    "VISUAL",

    # XDG directories (so nvim finds its config)
    "XDG_CONFIG_HOME",
    "XDG_DATA_HOME",
    "XDG_STATE_HOME",
    "XDG_CACHE_HOME",
    "XDG_RUNTIME_DIR",

    # Nix
    "NIX_PATH",
    "NIX_PROFILES",

    # LSP / language tooling
    "CARGO_HOME",
    "RUSTUP_HOME",
    "GOPATH",
    "GOROOT",
    "NODE_PATH",
    "npm_config_prefix",
]

[syscalls]
# Neovim + LSP servers need ptrace (for debugging) and
# memfd_create (used by various runtimes)
allow_extra = ["ptrace", "memfd_create"]

nix.toml

# Canister recipe for Nix package manager.
#
# Nix stores all packages in /nix/store with content-addressed paths.
# Binaries freely reference sibling store entries, so the entire store
# must be mounted. This recipe is auto-detected when the resolved
# command binary lives under /nix/store.
#
# Auto-detection: triggered by match_prefix

[recipe]
name = "nix"
description = "Nix package manager (/nix/store)"
version = "1"
match_prefix = ["/nix/store"]

[filesystem]
# Mount the entire Nix store — binaries reference sibling entries
# via rpaths and wrapper scripts.
allow = ["/nix/store"]

node-build.toml

# Canister recipe for Node.js build tasks (npm/yarn/pnpm).
#
# Allows network access to the npm registry and common CDNs.
# System paths are provided by base.toml — this recipe only adds
# Node.js-specific network and environment configuration.
#
# Usage:
#   can run -r node-build -- npm install
#   can run -r node-build -- npm run build

[recipe]
name = "node-build"
description = "Node.js build tasks: npm install, build, test"
version = "2"

[filesystem]
deny = ["/etc/shadow", "/root"]

[network]
egress = "proxy-only"
[[host]]
domain = "registry.npmjs.org"

[[host]]
domain = "registry.yarnpkg.com"

[[host]]
domain = "registry.npmmirror.com"
[process]
max_pids = 128
env_passthrough = [
    "PATH",
    "HOME",
    "LANG",
    "TERM",
    "NODE_ENV",
    "NPM_CONFIG_REGISTRY",
    "NPM_TOKEN",
]

opencode.toml

# Canister recipe for OpenCode — AI coding agent.
#
# OpenCode is a Go binary that talks to LLM providers (GitHub Copilot,
# Anthropic, OpenAI, etc.) and runs developer tools (git, cargo, npm,
# ripgrep, etc.) to assist with coding tasks.
#
# This recipe scopes filesystem access to the project working directory,
# OpenCode's own state/config dirs, and common tool locations. Network
# is restricted to known LLM API domains.
#
# Usage:
#   can run --recipe recipes/opencode.toml -- opencode
#
# Note: Run from the project directory you want OpenCode to work on.
# The $PWD will be bind-mounted into the sandbox.

[recipe]
name = "opencode"
description = "OpenCode AI coding agent with scoped filesystem and restricted network"
version = "2"

[filesystem]
# OpenCode needs access to:
# - The project directory (implicitly mounted writable as the working dir)
# - Its own config and state dirs
# System paths (/usr/lib, /usr/bin, /lib, /tmp, etc.) are provided by base.toml.
# Language toolchains ($HOME/.cargo, $HOME/.rustup, /nix/store, etc.) should
# be added via recipe composition in canister.toml, NOT baked in here.
#
# SECURITY: We intentionally do NOT mount:
# - $HOME/.ssh        — SSH private keys. Use SSH_AUTH_SOCK (agent) instead.
# - $HOME/.gitconfig  — may contain credential helpers or tokens. Git identity
#                       is passed via GIT_AUTHOR_NAME/EMAIL env vars.
# - $HOME/.cargo      — contains credentials.toml (crates.io tokens). Mount
#                       via the cargo recipe when needed.
# - $HOME/.gnupg      — GPG private keys.
# - $HOME/.aws        — AWS credentials.
# - $HOME/.kube       — Kubernetes config with tokens.
allow = [
    "$HOME/.opencode",
    "$HOME/.config/opencode",
]
# OpenCode writes to its state dir (SQLite DB, logs, tool output).
allow_write = [
    "$HOME/.local/share/opencode",
]
deny = [
    "/etc/shadow",
    "/root",
    "$HOME/.ssh",
    "$HOME/.gnupg",
    "$HOME/.aws",
    "$HOME/.kube",
    "$HOME/.docker",
    "$HOME/.npmrc",
    "$HOME/.pypirc",
    "$HOME/.netrc",
    "$HOME/.config/gh",
]

[network]
egress = "proxy-only"
# GitHub Copilot auth and API
# - github.com: OAuth device flow
# - api.github.com: token exchange and user info
# - api.githubcopilot.com: chat completions endpoint
# - copilot-proxy.githubusercontent.com: Copilot proxy
#
# Anthropic API (Claude models)
# - api.anthropic.com
#
# OpenAI API
# - api.openai.com
#
# OpenCode's own services (Zen, auth, sharing)
# - opencode.ai
#
# WebFetch tool — OpenCode fetches arbitrary URLs for research.
# If you need unrestricted web access, set egress = "direct".
[[host]]
domain = "github.com"

[[host]]
domain = "api.github.com"

[[host]]
domain = "api.githubcopilot.com"

[[host]]
domain = "copilot-proxy.githubusercontent.com"

[[host]]
domain = "api.anthropic.com"

[[host]]
domain = "api.openai.com"

[[host]]
domain = "opencode.ai"
[process]
# OpenCode spawns subprocesses for tools (git, cargo, rg, etc.)
max_pids = 256
# Environment variables OpenCode and its tools need.
env_passthrough = [
    "PATH",
    "HOME",
    "LANG",
    "TERM",
    "COLORTERM",
    "EDITOR",
    "SHELL",
    "USER",
    "XDG_CONFIG_HOME",
    "XDG_DATA_HOME",
    "XDG_STATE_HOME",
    "XDG_CACHE_HOME",
    "GIT_AUTHOR_NAME",
    "GIT_AUTHOR_EMAIL",
    "GIT_COMMITTER_NAME",
    "GIT_COMMITTER_EMAIL",
    "HTTPS_PROXY",
    "HTTP_PROXY",
    "NO_PROXY",
    "SSH_AUTH_SOCK",
    "CARGO_HOME",
    "RUSTUP_HOME",
    "NODE_PATH",
]

python-pip.toml

# Canister recipe for installing Python packages with pip.
#
# Allows network access to PyPI. System paths are provided by base.toml.
#
# Usage:
#   can run -r python-pip -- pip install requests
#   can run -r python-pip -- python3 -m pip install -r requirements.txt

[recipe]
name = "python-pip"
description = "Install Python packages with pip (network access to PyPI)"
version = "2"

[filesystem]
deny = ["/etc/shadow", "/root"]

[network]
egress = "proxy-only"
[[host]]
domain = "pypi.org"

[[host]]
domain = "files.pythonhosted.org"
[process]
max_pids = 32
env_passthrough = [
    "PATH",
    "HOME",
    "LANG",
    "TERM",
    "PIP_INDEX_URL",
    "PIP_TRUSTED_HOST",
    "VIRTUAL_ENV",
]

snap.toml

# Canister recipe for Snap packages.
#
# Snap installs applications under /snap with the runtime under
# /snap/core*. Binaries are launched via /snap/bin wrappers.
#
# Auto-detection: triggered by match_prefix

[recipe]
name = "snap"
description = "Snap package manager (/snap)"
version = "1"
match_prefix = ["/snap"]

[filesystem]
allow = ["/snap"]