diff --git a/packages/nash-default-shell/files/etc/nucleic/nash.conf b/packages/nash-default-shell/files/etc/nucleic/nash.conf new file mode 100644 index 0000000..4bf0582 --- /dev/null +++ b/packages/nash-default-shell/files/etc/nucleic/nash.conf @@ -0,0 +1,23 @@ +# nash operator policy (docs/NASH.md §4.3) — baked into the narOS image. +# +# nash reads its levers ONLY from this file. They used to live in the environment +# (NUCLEIC_NASH_DISABLE, NUCLEIC_REAL_BASH), which meant the process nash exists to +# observe could turn that observation off in one word, silently. This file is root-owned +# and not group/other-writable; nash checks that ownership before honoring a single line, +# so an agent-created copy is ignored. +# +# Nucleic rewrites this file when it starts a container, carrying the `legacyShell` +# rollback lever into `disable`. Editing it by hand is an operator action. + +# Observation may not be switched off by the observed process: a shell whose transport +# env has been stripped, or which was handed NUCLEIC_SHELL_CAPTURE=off, still records and +# spools to /var/spool/nucleic-nash for the drain. +require_observation=1 + +# Exec target for the parse-failure fallback and the break-glass below. +real_bash=/usr/bin/bash.real + +# Break-glass (NASH.md §4.1): 1 makes nash re-exec the real bash with identical argv. +# The one lever that turns the agent shell off, and it lives here precisely so that an +# agent cannot reach it. +disable=0 diff --git a/packages/nash-default-shell/files/etc/profile.d/naros-shell.sh b/packages/nash-default-shell/files/etc/profile.d/naros-shell.sh index f622b7c..e13c1a8 100644 --- a/packages/nash-default-shell/files/etc/profile.d/naros-shell.sh +++ b/packages/nash-default-shell/files/etc/profile.d/naros-shell.sh @@ -1,4 +1,8 @@ -# narOS shell environment (nash-default-shell). NUCLEIC_REAL_BASH is nash's -# parse-failure fallback + NUCLEIC_NASH_DISABLE target (NASH.md §4.1). -export NUCLEIC_REAL_BASH=/usr/bin/bash.real +# narOS shell environment (nash-default-shell). +# +# Deliberately does NOT export NUCLEIC_REAL_BASH: nash's fallback target is an operator +# lever, and operator levers now come from the trusted policy file (/etc/nucleic/nash.conf, +# NASH.md §4.3), never from the environment — which is the agent's to write. nash carries +# /usr/bin/bash.real as its compiled-in default anyway, so the export bought nothing but a +# published bypass. [ -n "${SHELL:-}" ] || export SHELL=/usr/local/bin/nash diff --git a/tests/smoke-rootfs.sh b/tests/smoke-rootfs.sh index c7e62b4..1541df4 100755 --- a/tests/smoke-rootfs.sh +++ b/tests/smoke-rootfs.sh @@ -29,6 +29,14 @@ COMMON=' . /etc/os-release; test "$ID" = naros readlink /bin/sh | grep -q nash test -x /usr/bin/bash.real + # nash trusted policy (NASH.md §4.3): present, root-owned, not group/other-writable — + # the three properties nash checks before it honors an operator lever. A packaging + # slip on any of them silently returns the levers to nobody (or, worse, to the agent). + test -f /etc/nucleic/nash.conf + grep -q "^require_observation=1" /etc/nucleic/nash.conf + test "$(stat -c %u:%a /etc/nucleic/nash.conf)" = "0:644" + # The bypass the image used to publish to every shell it started. + ! grep -rq NUCLEIC_REAL_BASH /etc/profile.d/ ' # A runtime-clean sources.list (no build-time copy:// pool left in), scoped away from