feat(lsm): default-deny IPv4 egress (#54) + AF_UNIX deputy denylist (#55) #48
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 1: Release build | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| build: | |
| name: Build (release) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y libz3-dev keyutils | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-registry- | |
| - name: Cache target directory | |
| uses: actions/cache@v4 | |
| with: | |
| path: target | |
| key: ${{ runner.os }}-cargo-target-release-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-target-release- | |
| - name: Build release | |
| run: cargo build --release 2>&1 | |
| - name: Upload release binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ts_cli-release-${{ github.sha }} | |
| path: target/release/ts_cli | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 2: Test suite (unit + integration) | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| test: | |
| name: Tests | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y libz3-dev keyutils | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-registry- | |
| - name: Cache target directory | |
| uses: actions/cache@v4 | |
| with: | |
| path: target | |
| key: ${{ runner.os }}-cargo-target-test-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-target-test- | |
| ${{ runner.os }}-cargo-target-release- | |
| - name: Download release binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ts_cli-release-${{ github.sha }} | |
| path: target/release/ | |
| - name: Mark binary executable | |
| run: chmod +x target/release/ts_cli | |
| - name: Run all tests | |
| env: | |
| JINNGUARD_TEST_BINARY: ${{ github.workspace }}/target/release/ts_cli | |
| run: cargo test --workspace 2>&1 | |
| # Anti-lockout / safe-mode invariants in the LSM verdict loop only build | |
| # under the kernel feature. Run them so a regression that could strand the | |
| # operator fails CI. | |
| - name: Run kernel-feature safety invariants | |
| run: cargo test --bin ts_cli --features kernel_telemetry 2>&1 | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 2b: Fleet feature gate (open-core enterprise client) | |
| # The signed-bundle client (`--fleet-policy-url`) compiles only with the | |
| # `fleet` feature (off by default). The other jobs build feature-off; this one | |
| # guarantees the gated code still compiles, lints, and that the accept/reject | |
| # decision (apply-forward / reject-rollback / reject-bad-signature) is correct. | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| fleet: | |
| name: Fleet feature gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y libz3-dev keyutils | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-registry- | |
| - name: Cache target directory | |
| uses: actions/cache@v4 | |
| with: | |
| path: target | |
| key: ${{ runner.os }}-cargo-target-fleet-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-target-fleet- | |
| - name: Install clippy | |
| run: rustup component add clippy | |
| - name: Clippy (fleet feature, deny warnings) | |
| run: cargo clippy -p ts_cli --features fleet -- -D warnings 2>&1 | |
| - name: Test fleet bundle accept/reject decision | |
| run: cargo test -p ts_cli --features fleet --bin ts_cli fleet_policy 2>&1 | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 3: Benchmark compilation check | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| bench: | |
| name: Bench (compile check) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y libz3-dev keyutils | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-registry- | |
| - name: Cache target directory | |
| uses: actions/cache@v4 | |
| with: | |
| path: target | |
| key: ${{ runner.os }}-cargo-target-bench-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-target-bench- | |
| - name: Compile benchmarks (no-run) | |
| run: cargo bench --no-run 2>&1 | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 4: Clippy (deny warnings) | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| clippy: | |
| name: Clippy | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y libz3-dev keyutils | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-registry- | |
| - name: Install clippy | |
| run: rustup component add clippy | |
| - name: Run clippy | |
| run: cargo clippy -- -D warnings 2>&1 | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 5: Rustfmt check | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| fmt: | |
| name: Format check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install rustfmt | |
| run: rustup component add rustfmt | |
| - name: Check formatting | |
| run: cargo fmt --check 2>&1 | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Job 6: eBPF build | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| build-ebpf: | |
| name: Build eBPF LSM objects | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install clang, llvm, libbpf-dev | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y clang llvm libbpf-dev | |
| # Compile each of the five LSM objects the daemon actually loads against the | |
| # vendored bpf/vmlinux.h (committed to the repo). This deliberately does NOT | |
| # use bpftool or the runner's live BTF: obtaining a working bpftool on | |
| # GitHub's Azure-kernel runner is unreliable, and a compile sanity check | |
| # doesn't need the runner's own kernel types. This GATES CI — a change that | |
| # breaks BPF compilation (bad map, missing helper, etc.) fails the build. | |
| - name: Compile LSM objects (gating) | |
| run: | | |
| set -euo pipefail | |
| test -f bpf/vmlinux.h || { echo "ERROR: bpf/vmlinux.h missing (it is vendored)"; exit 1; } | |
| cd bpf | |
| for f in lsm/jg_socket_connect lsm/jg_socket_sendmsg \ | |
| lsm/jg_bprm_check_security lsm/jg_inode_create lsm/jg_inode_unlink; do | |
| echo " CLANG $f.o" | |
| clang -O2 -g -target bpf -D__TARGET_ARCH_x86 -I/usr/include -I. -c "$f.c" -o "$f.o" | |
| done | |
| - name: Upload eBPF LSM objects | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: jinnguard-lsm-objects-${{ github.sha }} | |
| path: bpf/lsm/*.o | |
| if-no-files-found: error |