Repository navigation
hisn 0.3.2
Hardening before the tag (same version):
rootfs importmoved torootfs_import: streamingtarcrate extraction with
explicit hardening, unique staging, no-clobber / rename-aside--replace,
manifest.jsonwritten without following archive links, option-like
--from-imagevalues refused.[rootfs] namethat cannot be resolved is an error (it used to fall back to the
host toolchain); a rootfs overlapping a writable mount, or with a symlinked
/etc, is refused.[home] persistrefuses fixed host trees, shared dirs, hisn's own state dirs and
directories owned by someone else.- ssh proxy rejects malformed SIGN_REQUESTs locally, caps clients, times out idle
ones.
Added
- Persistent
$HOME([home] persist,--home-persist): a profile may
declare a persistent home directory that survives across sessions, bind-mounted
rw at the same in-sandbox path. Refuse list (real$HOME, ancestors of
$HOME,/, cwd, ancestors of cwd) enforced before any namespace exists. Risk
labelhome-persist(Data). ADR 0009. Leak test L42. - Read-only rootfs (
[rootfs] name|path,--rootfs-path): a profile may
declare a rootfs tree that replaces the host toolchain dirs (/usr,/bin,
/sbin,/lib,/lib32,/lib64,/opt,/nix,/etc) inside the sandbox.
All rootfs mounts arero, nosuid, nodev. Host/usr,/opt,/nixare not
visible when a rootfs is set.hisn rootfs import|list|path|rmsubcommand with
streaming extraction (via thetarcrate — handles ustar prefix, GNU
LongLink, and PAX extended headers) and hardening (strip setuid, reject
traversal, reject hard links outside, reject symlink-then-write, skip
devices, atomic staging).hisn checkreports the rootfs store. Risk label
rootfs(Trust). ADR 0010. Leak tests L43, L44, L46. - SSH agent T1 (
[ssh] agent = true,keys = [...]): a filtering proxy that
forwards onlyREQUEST_IDENTITIESandSIGN_REQUEST, rejects all mutations
(ADD,REMOVE,LOCK,UNLOCK,EXTENSION), filters by fingerprint
allowlist, and injectsSSH_AUTH_SOCKinto the scrubbed env. The host
SSH_AUTH_SOCKis never mounted. Every forwarded sign request is logged
(fingerprint, session id) — allowlist or not. The accept loop retries on
EMFILE/ENFILE/EAGAIN. Risk labelssh-agent(Signing). ADR 0011.
Leak test L45.
Changed
Cargo.tomlversion bumped to 0.3.2.- CI: musl target (
x86_64-unknown-linux-musl) added to the release workflow
alongside the glibc build, with a-muslsuffix in the asset name. Glibc
remains the default download.
Tests
- L42 (home-persist): persist dir created, cross-session persistence (file
written in session A exists in B), symlink escape blocked, pre-0.3.2 home
location fails, each refuse-list case (real$HOME, ancestor of$HOME,
/, cwd, ancestor of cwd) rejected before any namespace exists, HOME env
is the sandbox path, persist ≠ real$HOME. - L43 (rootfs, with
HISN_TEST_ROOTFS): host/optmarker not visible,
host binary not executable,/usrmount showsro,nosuid,nodevin
mountinfo, remount cannot drop ro, username matches,nosuidenforced. - L44 (rootfs import hardening, always runs): path traversal, absolute names,
hard link escape, setuid stripping on a synthetic tar. - L46 (rootfs symlink traps, with
HISN_TEST_ROOTFS): symlink traps in
/usr/local/binand absolute symlinks to host$HOMEdo not reach host
data. - L45 (ssh-agent): two ed25519 keys; with
keys=[fp1]:ssh-add -lshows
only key1, key2 filtered, ssh-add (add) and ssh-add -D (remove all) from
inside session fail, host agent still lists both keys, proxy socket absent
after teardown; withoutkeys=: both keys listed, add/remove still fail
(skip if ssh-agent or ssh-add not found).
The leak suite (L1-L45) passed on Ubuntu 22.04 and 24.04 x86_64 CI runners for this exact commit before these binaries were built; the aarch64 binary is built and started (--version) but has not been leak-tested. The glibc binaries (hisn-x86_64-linux-gnu, hisn-aarch64-linux-gnu) are dynamically linked and built natively on Ubuntu 22.04 (glibc 2.35 or newer required). The musl binary (hisn-x86_64-linux-musl) is statically linked. Verify with sha256sum -c SHA256SUMS. See README, "Verifying a build".