Repository navigation
hisn 0.4.0
0.4.0 adds seats: a hisn session is a named place that several clients join,
locally or over SSH (ssh -t host hisn attach --session <name>), sharing one
sandbox, one pid namespace, one session env snapshot and one audit log, with
idle leases, an explicit hisn stop that keeps the session directory, and
archival of the audit on prune.
Host evidence: make leaktest on rubin: 308 passed, 0 failed, 6 skipped,
1 weak; remote attach verified on smaragd (Fedora 44, kernel 7.2.13).
Security: equal access per uid in 0.4.0; the client record, the single
authorize() seam and the per-client audit ship now, so roles are a policy
change later.
Added
- Named sessions:
hisn run --name <name>(unique per user);--session
accepts a name or id everywhere;hisn lsshows NAME, ID, STATE, CWD,
ROOTFS, NET, AGE, CLIENTS, LEASE. A per-user index in the/tmp/hisn-$UID
root is authoritative; a fallback scan repairs it (ADR 0014). - Attach:
hisn attach --session <name|id>— an interactive shell
($SHELL from the env snapshot, else /bin/sh) in the session cwd. Multiple
attaches are peers. The detach key Ctrl-] d closes the client; the shell
is killed on disconnect (no --detach in 0.4.0) (ADR 0015). - Client identity and the authorization seam: every control request
carries aClientRecord(uid, pid, label, req_id, seq, principal). One
authorize()function gates every op; in 0.4.0 it allows iff
uid == owner.uid. TheAuthorizedtoken cannot be forged outside the
authzmodule. Every audit line carriesclient,seq,authz.
Members are append-only insession.json(ADR 0016). - Session env snapshot:
--env K=Vat run declares a session env;
precedence: scrub < declared < computed; a request naming a declared key
getsE_ENV_LOCKED(ADR 0017). - Leases, stop, archival:
[session] idle_timeout(duration string,
default none).hisn stop --session Xsets state stopped and keeps the
dir.ls --prunearchivesgrants.jsonl+session.jsonto
$XDG_STATE_HOME/hisn/audit/<id>.jsonl(0600) before removing;--purge
skips archival (ADR 0019). Idle expiry runs the same stop function as
hisn stop(dir kept asstopped, auditlease/expired); a foreground
hisn runthen exits 143 withhisn: session <name|id> stopped: idle for <d> (idle_timeout <d>). A stop racing the session end no longer removes
the dir.hisn ls --jsongainsdir. - Lifecycle state:
session.jsoncarriesstate ∈ {creating, running, stopping, stopped, crashed}.
Known issues (0.4.1)
hisn run --detachstays in the foreground instead of returning once the
session is ready.- Inside an attach,
ttyname()fails (tty: no such device): the client's
pty slave is not visible in the session's private/dev/pts.isattyis
true (L20), so interactive programs work; programs that need the tty's
name do not. hisn ls --jsonlacks theclientsarray and does not list a live
attach underexecs.- CLIENTS is not zeroed on a stopped session.
- L56 and L58 remain host-only / documented checks (not automated in the
leak suite).
Changed
- Repository cleanup (no code change): process documents (plans, patches,
host-run logs, the verification record) are removed from the tree; their
decisions are indocs/adr/. The policy schema is regenerated from the
struct (addslandlock,shm,shm_size,tmp_size). Example profiles use
/tmp/hisn-outasgrantable_rw, so they validate on a fresh host. CI builds
the musl binary and validates the example profiles.
Leak suite: the portable subset runs in CI; host-only checks (user namespaces, rootfs, attach, leases) are verified on a real host before tagging — see the release notes for the host result. 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".