No description
Find a file
Dzuchun 4e73ec02c8
Some checks failed
CI / check (push) Has been cancelled
fix: sporadic socat kill errors in the EXIT trap
basically, the tests sporadically fail to kill the `socat` process,
reporting it to not exist. in the log, you could also see the `socat`
existing with SIG15. so my guess is -- `socat` can get killed by the
environment (nix build pipeline, for instance), and would no longer
require a cleanup (won't be reparented to PID1).

so the mental shift is -- as long as `socat` is gone, the clean was
successful. the failure mode here would be incorrectly capturing
`socat`'s PID, or missing the `kill` command (right now, it comes from
`coreutils` package, so presumably it would always be available).
2026-05-21 18:19:07 +01:00
.github/workflows add: initial version 2026-05-20 01:49:14 +01:00
flake.lock [flake.lock] 2026-05-20 04:23:59 +01:00
flake.nix fix: sporadic socat kill errors in the EXIT trap 2026-05-21 18:19:07 +01:00
README.md fix[docs]: clarify framing of the tool project 2026-05-20 05:20:37 +01:00
tests.nix fix: correctly forward the cli args 2026-05-21 17:47:45 +01:00

Brief

unsafe-cell is designed with following workloads in mind:

  • share a cache/binary store with the host
  • share a configuration with the host
  • allow limited internet access (to a set list of domains)
  • jailed program might misbehave -- host must be protected from accidental damage

So this cell aims to prevent malfunction, not malice; for example: current design shares a nix daemon with the host -- a malicious code could easily exploit the build pipeline to dos, mine crypto or circumvent the web proxy. However, this kind of malfunction is extremely unlikely happen accidentally, while benefits of sharing the nix store with host are self-explanatory.

Example use-cases:

  • trusted CI job container
  • agentic runtime (like opencode, for instance)

Parameters

  • command (pkgs -> derivation): a function to build the cell entrypoint from nixpkgs instantiation
  • worktreePath (string): host path to bind as /home/cell/worktree inside the jail. Use this parameter to expose jailed processes primary worktree (like a repo you work on)
  • extraCombinators (jail-nix -> list, default _: []): a function to produce additional jail.nix combinators you want the jail to have.
  • tinyproxyFilter (string or null): Path to a tinyproxy filter file. null means "allow all", non-null should contain a regex list of the allowed domains. Uses tinyproxy (with your filter as a white-list!).
  • logDir (string or null): directory to bind for log output. null means using the jail tempdir (wherever mktemp creates it).
  • nixDaemonSocket (string, default "/var/nix/daemon-socket"): host path to nix daemon socket directory (contains socket).

NOTE: if you want to pass some truly special arguments to bwrap, see unsafe-add-raw-args jail.nix combinator -- an escape hatch for adding bare os args for the bwrap process. NOTE: for now, the host is expected to have a nix daemon socket. To make the cell work, at the bare minimum, you should make up a socket and point nixDaemonSocket to it -- cell will connect socat to it, but won't actually communicate with the other side, for as long as you don't use nix inside the jail.

Capabilities

  • nix daemon access:
    • read-only bind of host store (/nix/store)
    • bind of the daemon socket (/run/nix)
    • nix client config to silence experimental feature warnings (nix-command, flakes)
    • nix client substitutions enabled to allow binary cache usage (client controls that, for some reason?)
  • network:
    • http proxied through tinyproxy, with optional filter
    • isolated network namespace with no interfaces
  • workdir bind-mounted at a configurable host path
  • optional log directory bind

planned:

  • spawning a personal dockerd (blocked by some annoying stuff inside bwrap)
  • support for MITM docker image cache (could be implemented now, but is useless without a personal dockerd)

NOTE: unfortunately, outward communication with protocols other than HTTP(S) is not supported. Any celled app failing to interpret {HTTP{,S},NO}_PROXY envvars, is also likely to misbehave.

Usage example

See tests.nix.

Will probably add my opencode run script, once it's complete.