feat(agent): real nix (sandbox=false) for firmware SBOM, replacing nix-portable #159

Merged
sharang merged 1 commits from feat/real-nix-firmware-sbom into main 2026-07-13 16:01:10 +00:00
Owner

Closes the phase-2 firmware build on the actual deployment.

Why nix-portable failed

It fell back to proot (user namespaces are blocked by the container's default seccomp/apparmor profile; orca exposes no security-opt to relax it). proot then corrupts the build's permission syscalls — every firmware build died at cp: setting permissions … No such file or directory. Confirmed on the master: unshare --user fails in the container but works with --security-opt seccomp=unconfined,apparmor=unconfined.

The fix: real nix, no sandbox

  • Multi-stage: a throwaway nixos/nix stage packs a real store (+ validity DB) into a compressed bootstrap tarball; only the tarball lands in the final image.
  • /etc/nix/nix.conf: sandbox = false (a gcc/make build needs no user namespace), flakes on, single-user, cache.nixos.org substituter.
  • docker/agent-entrypoint.sh seeds /nix from the tarball on first start, so a persistent /nix volume survives redeploys.
  • All best-effort: broken/missing nix → analysis-only fallback, never breaks a scan.
  • No agent code changeNixBackend::detect() already prefers system nix.

Paired orca-infra change

The /nix volume mount (orca-certifai-agent-nixstore:/nix) — pushed to orca-infra main separately.

Caveat

The nix build path can't be exercised in CI (no nix in the runner); it's validated at runtime on the deployment. CI covers compile + the fallback.

Closes the phase-2 firmware build on the actual deployment. ## Why nix-portable failed It fell back to **proot** (user namespaces are blocked by the container's default seccomp/apparmor profile; orca exposes no security-opt to relax it). proot then corrupts the build's permission syscalls — every firmware build died at `cp: setting permissions … No such file or directory`. Confirmed on the master: `unshare --user` fails in the container but works with `--security-opt seccomp=unconfined,apparmor=unconfined`. ## The fix: real nix, no sandbox - Multi-stage: a throwaway `nixos/nix` stage packs a real store (+ validity DB) into a compressed bootstrap tarball; only the tarball lands in the final image. - `/etc/nix/nix.conf`: **`sandbox = false`** (a gcc/make build needs no user namespace), flakes on, single-user, cache.nixos.org substituter. - `docker/agent-entrypoint.sh` seeds `/nix` from the tarball on first start, so a **persistent /nix volume** survives redeploys. - All best-effort: broken/missing nix → analysis-only fallback, never breaks a scan. - **No agent code change** — `NixBackend::detect()` already prefers system `nix`. ## Paired orca-infra change The `/nix` volume mount (`orca-certifai-agent-nixstore:/nix`) — pushed to orca-infra main separately. ## Caveat The nix build path can't be exercised in CI (no nix in the runner); it's validated at runtime on the deployment. CI covers compile + the fallback.
sharang added 1 commit 2026-07-13 15:54:57 +00:00
feat(agent): real nix (sandbox=false) for firmware SBOM, replacing nix-portable
CI / Check (pull_request) Successful in 5m26s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
c2d43c55e7
nix-portable fell back to proot in the deployment (user namespaces are blocked
by the container's default seccomp/apparmor profile, and orca can't relax it),
and proot corrupts the nix build's file-permission syscalls — every firmware
build failed at `cp: setting permissions … No such file or directory` and fell
back to the analysis-only SBOM.

Ship a real nix instead and disable its build sandbox (`sandbox = false`): a
plain gcc/make firmware build needs no user namespace, so it runs under the
locked-down profile with no proot at all. The store ships as a compressed
bootstrap tarball (built in a throwaway `nixos/nix` stage) and is seeded onto
/nix at first start by docker/agent-entrypoint.sh, so a persistent /nix volume
survives redeploys. Seeding and the whole path are best-effort — a broken nix
just falls back to analysis-only, never breaking a scan.

No agent code change: NixBackend::detect() already prefers the system `nix`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sharang merged commit 613847d4d3 into main 2026-07-13 16:01:10 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sharang/compliance-scanner-agent#159