Skip to content

feat(cross): --offline-strict with fail-closed network-namespace enforcement#101

Merged
jwinarske merged 2 commits into
mainfrom
jw/offline-netns
Jul 4, 2026
Merged

feat(cross): --offline-strict with fail-closed network-namespace enforcement#101
jwinarske merged 2 commits into
mainfrom
jw/offline-netns

Conversation

@jwinarske

Copy link
Copy Markdown
Contributor

Strengthens --offline so a build subprocess can't quietly reach the network. Builds on #98/#100.

Why

--offline denies emb's own egress (cached inputs, CARGO_NET_OFFLINE) but trusts a build subprocess — a crate build script, a CMake FetchContent — to honor it. --offline-strict removes that trust.

What

  • --offline-strict (implies --offline): runs build subprocesses inside a rootless network namespace (unshare --net --map-root-user, loopback brought up), so an off-host connection is denied outright.
  • Fail closed. When that isolation is unavailable — no unshare, or unprivileged user namespaces disabled (common on locked-down CI runners and in containers) — --offline-strict refuses to build rather than silently downgrading. Plain --offline degrades with a warning.
  • Cargo module builds are wrapped when isolation is available; unshare inherits cwd and env, so CARGO_HOME/CARGO_NET_OFFLINE still reach cargo.

Structure

New lib/src/cross/offline_enforcement.dart: OfflineMode, the netnsWrap argv builder, a netnsAvailable capability probe, and resolveOfflineEnforcement (the fail-closed/degrade policy) — all unit-tested with a fake runner. emb cross resolves the enforcement once, before the build.

Test

  • dart analyze lib test clean; dart format --set-exit-if-changed clean; cspell dictionary extended.
  • New offline_enforcement_test.dart (argv wrap, probe outcomes, strict-fails-closed / deny-degrades / off-noop).
  • Full suite: 507 pass, 1 skip, 2 pre-existing real dpkg-deb/real debugfs env failures.

Scope / follow-ups

  • Wrapping is applied to cargo module builds; extending it to the cmake/meson module builds (via CrossBuilder) and the future hook runner is the next step.
  • A seccomp/proxy-deny middle rung (below netns, above env-hints) for hosts without user namespaces.

jwinarske added 2 commits July 3, 2026 22:02
A rootless netns wrapper (unshare --net --map-root-user, loopback up), a
capability probe, and a policy that fails closed under strict mode when
isolation is unavailable and degrades with a warning otherwise.

Signed-off-by: Joel Winarske <joel.winarske@linux.com>
Add --offline-strict (implies --offline): resolve the enforcement level
once a build is about to run and refuse to build when a network
namespace is unavailable, rather than trusting a subprocess to honor
--offline. Cargo module builds run wrapped in the namespace when
isolation is available.

Document both flags in the README and extend the cspell dictionary.

Signed-off-by: Joel Winarske <joel.winarske@linux.com>
@jwinarske
jwinarske merged commit 79ed5c0 into main Jul 4, 2026
39 checks passed
@jwinarske
jwinarske deleted the jw/offline-netns branch July 4, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant