Skip to content

Security hardening: chokepoint lint + default-deny/safe-default guards#85

Merged
NathanFlurry merged 3 commits into
mainfrom
security/ci-guards
Jun 19, 2026
Merged

Security hardening: chokepoint lint + default-deny/safe-default guards#85
NathanFlurry merged 3 commits into
mainfrom
security/ci-guards

Conversation

@NathanFlurry

@NathanFlurry NathanFlurry commented Jun 19, 2026

Copy link
Copy Markdown
Member

Two CI hardening guards that lock in the secure-exec trust boundary so a refactor cannot silently weaken it. Both are pure tests (no production code changes) and are green today.

#2 — Chokepoint / boundary lint

crates/sidecar/tests/architecture_guards.rs scans the secure-exec Rust source tree and FAILS if a banned host API appears OUTSIDE an explicit allowlist of sanctioned chokepoint modules. The allowlist is built from the current legitimate uses, so it is green today and catches only NEW uses.

Banned classes:

  • fs: std::fs / tokio::fs / File::open / File::create / OpenOptions / openat
  • net: std::net:: / tokio::net:: / reqwest / hyper / raw socket constructors (TcpStream::, TcpListener::bind, UdpSocket::bind, UnixStream::connect/pair, UnixListener::bind) / to_socket_addrs / std::os::unix::net
  • process: std::process::Command / process::Command / tokio::process / Command::new / libc::fork / nix::unistd::fork
  • env: std::env::var / var_os / vars / vars_os

Exclusions: build scripts (build.rs, *build_support.rs, v8_bridge_build.rs), tests/ and benches/ trees, src/bin/ and benchmark.rs dev tooling, and inline #[cfg(test)] modules (brace-tracked).

Sanctioned allowlist (each entry documented in-file with why the access is safe):

  • fs: sidecar host-FS plumbing + bootstrap (filesystem, plugins/host_dir, plugins/module_access, stdio, state, vm, service, execution) and language-runtime asset/module loaders (execution::{python, wasm, javascript, node_import_cache, runtime_support}).
  • net: kernel network plane (dns, socket_table, kernel), sidecar host-net chokepoint (execution, state, vm), host-backed storage/agent plugins (s3, google_drive, sandbox_agent), embedded V8 runtime IPC socketpair (embedded_runtime, v8_runtime), and the client transport that spawns/connects to the sidecar.
  • process: only secure-exec-client/src/transport.rs (spawns the sidecar helper). Guest process spawns go through the kernel CommandDriver registry and never touch Command::new.
  • env: scrubbed/bootstrap config readers (transport, host_node, v8-runtime/bridge, sidecar/execution, plugins/s3).

Also asserts no secure-exec crate Cargo.toml depends on any agent/acp/session crate, and a sanity test that the lint actually scans real sources (guards against a vacuous pass).

#5 — Default-deny + safe-default guards

crates/kernel/tests/default_deny_guards.rs:

  • Default-deny / fail-closed: with no policy (Permissions::default(), all four checks None), filesystem, network, child-process spawn, and environment reads are all denied (EACCES / empty env).
  • New-variant fail-closed: exhaustive, wildcard-free match over FsOperation / NetworkOperation / EnvironmentOperation forces a compile error if a new capability variant is added (verified: removing a variant produces E0004), and a runtime check denies every enumerated variant under the empty policy.
  • Safe defaults: every safety-critical NON-TIME resource limit (processes, open fds, sockets, connections, pipes, ptys, filesystem bytes, inodes, socket buffer/queue caps) is Some(_) and non-zero by default; never silently unbounded.
  • Time budgets stay opt-in: CPU/wall-clock budgets are intentionally opt-in, so no default time cap is asserted.

Test results

architecture_guards: 6 passed
default_deny_guards:  7 passed
cargo build --workspace: green

Add tests/architecture_guards.rs that scans the secure-exec source tree and
fails if a banned host API (std::fs/tokio::fs/File::open/openat,
std::net/tokio::net/reqwest/hyper/raw sockets, std::process::Command/
tokio::process/fork, std::env::var/var_os/vars) appears outside an explicit
allowlist of sanctioned chokepoint modules. The allowlist is built from the
current legitimate uses so the lint is green today and catches only NEW uses.
Build scripts, benches, bins, and #[cfg(test)] modules are excluded. Also
asserts no secure-exec crate depends on an agent/acp/session crate.
Add crates/kernel/tests/default_deny_guards.rs:
- Default-deny: with no policy (Permissions::default(), all checks None),
  filesystem, network, child-process spawn, and environment reads all fail
  closed (EACCES / empty env).
- Fail-closed on new variants: exhaustive (wildcard-free) matches over
  FsOperation/NetworkOperation/EnvironmentOperation force a compile error if a
  new capability variant is added, and a runtime check denies every enumerated
  variant under the empty policy.
- Safe defaults: every safety-critical NON-TIME resource limit (processes,
  open fds, sockets, connections, pipes, ptys, filesystem bytes, inodes, socket
  buffer/queue caps) is Some(_) and non-zero by default; time budgets (CPU/
  wall-clock) are intentionally left opt-in and are not asserted.
@railway-app

railway-app Bot commented Jun 19, 2026

Copy link
Copy Markdown

🚅 Environment secure-exec-pr-85 in rivet-frontend has no services deployed.

@NathanFlurry NathanFlurry merged commit 6324019 into main Jun 19, 2026
1 of 2 checks passed
@NathanFlurry NathanFlurry deleted the security/ci-guards branch June 19, 2026 09:31
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