# Sandbox CI: the keyless real-kernel confinement proofs. A separate workflow # from ci.yml because the axis is different — these jobs fan out over # OS×runner (kernel capabilities), not node versions. The Landlock launcher # arrives from the registry with `pnpm install` (the npm package family # `node-addon-landlock-run`, built and released from its own repository), so # these legs exercise the true consumer path — nothing is compiled here. name: Sandbox on: push: branches: [main, master] pull_request: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: contents: read jobs: # Keyless real-kernel sandbox proofs (sandbox RFC § Testing): each ladder # rung is only provable on a host where it enforces, so this job fans out # an OS×runner matrix — bwrap and Landlock on Linux (separate legs: the # Landlock files force the bwrap rung off, so each leg proves exactly one # rung; Landlock twice, once per architecture, each confining through the # registry-installed launcher), Seatbelt on macOS (sandbox-exec ships with # the OS). One node # version only: kernel confinement does not vary by node, and ci.yml's # node matrix already covers the node axis. # # The e2e files self-skip where their runner is absent, so a leg that lost # its runner (no bwrap, kernel without Landlock, macOS without # sandbox-exec) would otherwise pass as a false green — the same trap # e2e.yml's key preflight guards against. Each leg therefore asserts BOTH # its platform files actually ran: `Test Files 2 passed (2)`, no skips. sandbox-e2e: strategy: fail-fast: false matrix: include: - os: ubuntu-latest runner: bwrap - os: ubuntu-24.04 runner: landlock - os: ubuntu-24.04-arm runner: landlock - os: macos-latest runner: seatbelt name: sandbox e2e (${{ matrix.runner }}, ${{ matrix.os }}) runs-on: ${{ matrix.os }} timeout-minutes: 20 steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: 24 - name: Enable corepack (pnpm) run: corepack enable - name: Install (immutable) run: pnpm install --frozen-lockfile # The bwrap rung needs bubblewrap on PATH and unprivileged user # namespaces. Ubuntu 24.04 gates the latter behind an AppArmor knob; # lift it best-effort — on images where the knob is absent the # functional probe (and the run-guard below) is the arbiter anyway. - name: Install bubblewrap (unrestrict userns) if: matrix.runner == 'bwrap' run: | sudo apt-get update -q sudo apt-get install -yq bubblewrap sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 \ || echo "apparmor userns knob absent — the functional probe decides" # The unit suite runs on ubuntu in `checks`; this is the one darwin leg # in the workflow, so run it here too — the platform-dependent unit # expectations (Seatbelt path canonicalization: /tmp IS /private/tmp) # take their darwin branch only on this runner. - name: Unit tests (darwin parity) if: matrix.runner == 'seatbelt' run: pnpm run test - name: Sandbox e2e (real kernel confinement, world-verified) # NO_COLOR: vitest force-enables ANSI color under GITHUB_ACTIONS even # without a TTY, which would thread escape codes through the summary # line the run-guard greps. env: NO_COLOR: 1 run: | set -u +e -o pipefail out=$(pnpm exec vitest run --config vitest.e2e.config.ts \ packages/sandbox/sandbox-local/tests/${{ matrix.runner }}.e2e.ts \ packages/bash/bash-sandbox/tests/${{ matrix.runner }}.e2e.ts 2>&1); status=$? echo "$out" [ "$status" -eq 0 ] # Both platform files must have RUN — a self-skip (runner missing on # the very platform that exists to prove it) is a failure, not a pass. echo "$out" | grep -qE 'Test Files[[:space:]]+2 passed \(2\)' # Publish-path rehearsal, Landlock legs only (the pack gates need built # lib/). The e2e packs the workspace closure, installs the tarballs # into a throwaway consumer — npm pulling `node-addon-landlock-run` # and its platform package from the registry, the true consumer path — # and confines through the INSTALLED launcher, asserting it executable # apart (a mode-stripped binary must not masquerade as a non-enforcing # kernel). Same no-silent-skip guard as above. - name: Build packages (lib/ for the pack rehearsal) if: matrix.runner == 'landlock' run: pnpm run build - name: Packed-distribution e2e (pack → install → confine) if: matrix.runner == 'landlock' env: NO_COLOR: 1 run: | set -u +e -o pipefail out=$(pnpm exec vitest run --config vitest.e2e.config.ts \ packages/sandbox/sandbox-local/tests/packed-install.e2e.ts 2>&1); status=$? echo "$out" [ "$status" -eq 0 ] echo "$out" | grep -qE 'Test Files[[:space:]]+1 passed \(1\)'