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.
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.
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 main2026-07-13 16:01:10 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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 --userfails in the container but works with--security-opt seccomp=unconfined,apparmor=unconfined.The fix: real nix, no sandbox
nixos/nixstage 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.shseeds/nixfrom the tarball on first start, so a persistent /nix volume survives redeploys.NixBackend::detect()already prefers systemnix.Paired orca-infra change
The
/nixvolume 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.