{"id":51035664,"url":"https://github.com/kernel-guard/bpfcompat","last_synced_at":"2026-07-02T12:01:31.685Z","repository":{"id":362663518,"uuid":"1260268687","full_name":"Kernel-Guard/bpfcompat","owner":"Kernel-Guard","description":"Open-source eBPF compatibility evidence and CI gate","archived":false,"fork":false,"pushed_at":"2026-07-01T23:48:12.000Z","size":4784,"stargazers_count":13,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-02T01:22:01.611Z","etag":null,"topics":["bpf","bpfcompat","ci","compatibility","ebpf","github-actions","kernel-testing","kvm","libbpf","linux-kernel","observability","qemu","security","systems-programming","vm-testing"],"latest_commit_sha":null,"homepage":"https://bpfcompat.kernelguard.net/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kernel-Guard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T10:12:21.000Z","updated_at":"2026-07-01T23:44:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Kernel-Guard/bpfcompat","commit_stats":null,"previous_names":["kernel-guard/bpfcompat"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Kernel-Guard/bpfcompat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kernel-Guard%2Fbpfcompat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kernel-Guard%2Fbpfcompat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kernel-Guard%2Fbpfcompat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kernel-Guard%2Fbpfcompat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kernel-Guard","download_url":"https://codeload.github.com/Kernel-Guard/bpfcompat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kernel-Guard%2Fbpfcompat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35045926,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bpf","bpfcompat","ci","compatibility","ebpf","github-actions","kernel-testing","kvm","libbpf","linux-kernel","observability","qemu","security","systems-programming","vm-testing"],"created_at":"2026-06-22T05:32:23.304Z","updated_at":"2026-07-02T12:01:31.602Z","avatar_url":"https://github.com/Kernel-Guard.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bpfcompat\n\n[![CI](https://github.com/Kernel-Guard/bpfcompat/actions/workflows/ci.yml/badge.svg)](https://github.com/Kernel-Guard/bpfcompat/actions/workflows/ci.yml)\n[![CodeQL](https://github.com/Kernel-Guard/bpfcompat/actions/workflows/codeql.yml/badge.svg)](https://github.com/Kernel-Guard/bpfcompat/actions/workflows/codeql.yml)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Kernel-Guard/bpfcompat/badge)](https://scorecard.dev/viewer/?uri=github.com/Kernel-Guard/bpfcompat)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13230/badge)](https://www.bestpractices.dev/projects/13230)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n\u003cimg width=\"1672\" height=\"941\" alt=\"ChatGPT Image Jun 27, 2026, 04_40_42 PM\" src=\"https://github.com/user-attachments/assets/697ee208-15e2-4725-9066-c30cb81f753b\" /\u003e\n\n`bpfcompat` is an open-source compatibility validator for compiled eBPF\nartifacts. **Test your eBPF across real kernels — locally or in CI.** It boots\nreal distro kernels in disposable VMs, runs libbpf load/attach checks, and\nproduces JSON/Markdown reports that can fail CI when an artifact regresses — so\nthe answer is empirical, not inferred from CO-RE.\n\nThe core question is simple:\n\n\u003e Will this `.bpf.o` load and attach on the kernels I care about, and if not,\n\u003e what failed?\n\nPoint it at a local `.bpf.o` or a **published gadget by OCI reference**, on your\nlaptop or as a CI gate — `--quick` needs no matrix file:\n\n```sh\nbpfcompat test --artifact ghcr.io/inspektor-gadget/gadget/trace_open:latest --quick\n```\n\n**Live demo:** [bpfcompat.kernelguard.net](https://bpfcompat.kernelguard.net) — upload a\n`.bpf.o` and see the compatibility matrix.\n\n**Quickstart \u0026 trust model:** [docs/quickstart.md](docs/quickstart.md) — gate it in CI\nin ~10 minutes; self-hosted-first, your artifact never leaves your runner.\n\n## Why not just rely on CO-RE / BTFHub?\n\nCO-RE makes a `.bpf.o` *portable in principle*; it does not guarantee it will\n*load* on a given kernel. Real-world failures that CO-RE does not prevent:\n\n- missing or partial kernel BTF,\n- CO-RE relocation errors against a divergent kernel,\n- unsupported map types (e.g. ringbuf before 5.8),\n- unsupported program/attach types,\n- capability and kernel-config differences.\n\n`bpfcompat` answers the empirical question CO-RE leaves open: *does it actually\nload and attach here?* — by running the artifact in a real kernel.\n\n## How validation works: full VMs, not static analysis\n\nbpfcompat does **not** parse your object and guess. For every target it:\n\n1. boots the **real distro cloud image and its actual kernel** as a disposable\n   QEMU/KVM virtual machine (default `--runner vm`; `virtme-ng`, `firecracker`,\n   and `host` are also selectable);\n2. copies a **C/libbpf validator and your `.bpf.o` into the guest** over a\n   per-run SSH key;\n3. runs the **real `bpf()` load — and attach, in `load_attach` mode — inside\n   that kernel**, then copies a structured result back and throws the VM away.\n\nSo a verdict is what the kernel itself accepted or rejected (verifier log, BTF,\nCO-RE relocation, map/program/attach support), not a heuristic. Each run leaves\nper-target evidence — `serial.log` (the guest kernel boot), `qemu.log`, and\n`validator-result.json`.\n\n### Validate via your own loader (command mode)\n\nThe bundled validator answers \"does this `.bpf.o` load/attach?\" Sometimes you\nwant to answer \"does **my project's actual loader** come up on this kernel?\" —\nwhich also exercises your userspace path and needs no manifest kept in sync with\nthat loader. Command mode does exactly that: it runs your loader command\n(optionally a binary you ship in) **inside each matrix kernel VM**, and the\nper-kernel verdict is its **exit code**. The bundled validator is *not* used, so\nthis tests the real userspace loader path.\n\n```bash\n# Dedicated verb: ship your loader, run it on every kernel, exit code = verdict.\nbpfcompat test-command --cmd '$BPFCOMPAT_BIN --self-test' \\\n  --bin ./build/myloader --matrix matrices/mvp.yaml --out report.json\n\n# Equivalent flag form on `test`, e.g. driving a loader against a shipped .bpf.o:\nbpfcompat test --command '$BPFCOMPAT_BIN --obj $BPFCOMPAT_ARTIFACT' \\\n  --command-binary ./build/loader --artifact ./build/probe.bpf.o \\\n  --matrix matrices/mvp.yaml --out report.json\n```\n\nA real run, shipping a libbpf loader and pointing it at the\n[known-tricky kernel library](docs/kernel-quirk-library.md) — the loader's exit\ncode catches the ring-buffer incompatibility on 5.4 and passes 5.15, with no\nvalidator load in between:\n\n![bpfcompat test-command running a loader across kernels; ubuntu-20.04-5.4 fails (loader exit 2, ring buffer needs \u003e= 5.8) and ubuntu-22.04-5.15 passes (loader exit 0), with libbpf load/attach skipped](docs/images/test-command-demo.png)\n\nThe command runs as root in the disposable guest with `$BPFCOMPAT_BIN` (your\nshipped binary), `$BPFCOMPAT_ARTIFACT` (a staged `.bpf.o`, if given), and\n`$BPFCOMPAT_REMOTE_ROOT` exported. See\n[docs/command-validation.md](docs/command-validation.md).\n\nIf your project loads with **ebpf-go** (cilium/ebpf) rather than libbpf, ship an\nebpf-go loader the same way — ebpf-go is a separate loader implementation, so a\nlibbpf pass does not guarantee an ebpf-go pass. A complete static-loader recipe\nlives in [docs/ebpf-go-validation.md](docs/ebpf-go-validation.md).\n\nPoint either flow at the **library of known-tricky vendor kernels** — the ones\nwhere \"version ≠ feature support\" bites (ring-buffer boundary, enterprise\nbackports, no-BTF, vendor rebases, variant bands):\n\n```bash\nbpfcompat test --command '$BPFCOMPAT_BIN --self-test' --command-binary ./build/loader \\\n  --matrix matrices/quirk-library.yaml --out report.json\n```\n\nSee [docs/kernel-quirk-library.md](docs/kernel-quirk-library.md). The library\nis re-validated weekly and the resulting matrix is published at\n[kernel-guard.github.io/bpfcompat](https://kernel-guard.github.io/bpfcompat/).\n\n### Distributions covered\n\nA curated, multi-distro, multi-architecture matrix of the kernels enterprises\nand cloud fleets actually run (full list in\n[docs/profile-catalog.md](docs/profile-catalog.md)):\n\n| Family | Versions / kernels |\n|---|---|\n| Ubuntu | 16.04 → 25.10 (5.4, 5.8, 5.15, 6.5, 6.8, 6.11, 6.14, 6.17) |\n| Debian | 11 · 12 · 13 |\n| RHEL¹ / AlmaLinux / Rocky / CentOS Stream | 8 (4.18) · 9 (5.14) · 10 (6.12) |\n| Oracle Linux (UEK) | UEK 7 · UEK 8 |\n| Amazon Linux | 2 (4.14, 5.10) · 2023 (6.1) |\n| SUSE / openSUSE Leap | 15.6 (6.4) |\n| Upstream mainline | kernel.org 5.x–6.x sweeps |\n\nArchitectures: **x86_64 and ARM64**. ¹RHEL itself is a BYO subscription image;\nAlmaLinux/Rocky/CentOS Stream are the public, ABI-compatible rebuilds used as the\nreproducible RHEL stand-in.\n\n### Kernel version ≠ feature support (backports)\n\nEnterprise distros **heavily backport** eBPF features onto old kernel bases, so\nthe version number alone predicts nothing. Because bpfcompat boots the real\nvendor kernel, this is tested directly instead of inferred:\n\n- A ring-buffer program **fails on Ubuntu's vanilla 5.4** (ring buffer lands\n  upstream in 5.8) yet **passes on AlmaLinux 8's backported 4.18**.\n- **Amazon Linux 2's 4.14 — with no embedded BTF — still loads and attaches.**\n\nThis is proven across a 14/14 enterprise tier:\n[docs/case-study-enterprise-kernels.md](docs/case-study-enterprise-kernels.md).\n\n### CoreOS / OpenShift (Ignition boot)\n\nCoreOS-family nodes boot via **Ignition**, not cloud-init, so they need a\ndifferent bootstrap. bpfcompat implements it (Ignition config over QEMU\n`-fw_cfg`), and the two cases differ only by image availability:\n\n- **Fedora CoreOS — supported, image is public.** Fetch with\n  `make vm-image-fcos` and run; proven booting FCOS stable (kernel `7.0.11`) with\n  load + attach inside the guest.\n- **RHCOS / OpenShift — opt-in, operator-supplied image.** RHCOS ships with an\n  OpenShift release rather than an evergreen public cloud image, so it is **off\n  by default** and never claimed runnable without a real image. Stage your image\n  and opt in:\n\n  ```sh\n  make rhcos-image RHCOS_IMAGE=/path/to/rhcos-qemu.x86_64.qcow2   # or RHCOS_IMAGE_URL=...\n  BPFCOMPAT_ENABLE_RHCOS=1 bpfcompat test -artifact build/probe.bpf.o \\\n    -matrix matrices/rhcos.yaml -runner vm -out report.json\n  ```\n\n  Recorded evidence — real boots, not claims, and not just 4.16: **OpenShift\n  4.14, 4.16, and 4.18 on x86_64 (6 artifacts each), plus OpenShift 4.16 on\n  aarch64** — [docs/evidence-rhcos.md](docs/evidence-rhcos.md), with a\n  machine-readable [docs/report-rhcos-summary.json](docs/report-rhcos-summary.json).\n  Highlights: ring-buffer and perf-buffer load+attach pass on every release; a\n  **BPF-LSM** program is rejected on 4.14 (RHEL 9.2) but loads+attaches all hooks\n  on 4.16/4.18 (RHEL 9.4) — a real backport boundary; a CO-RE failure is\n  correctly rejected everywhere; and the aarch64 boot\n  (`5.14.0-427.50.1.el9_4.aarch64`) load+attaches under emulation. Without an\n  image, the **RHEL / AlmaLinux 9 (5.14)** profiles are the interim kernel\n  approximation. Full guide: [docs/rhcos-openshift.md](docs/rhcos-openshift.md).\n\n## Library mode: embed the pre-load gate\n\nBeyond the CLI and the GitHub Action, bpfcompat is an embeddable Go library\n([`pkg/bpfcompat`](https://github.com/Kernel-Guard/bpfcompat/tree/main/pkg/bpfcompat)).\n`ValidateBeforeLoad` does a real `bpf()` load against the node's **own running\nkernel** — no VM, no network — so a loader (e.g. bpfman) can refuse an object\nthat won't verify *before* it loads it. Host loading is gated behind the\n`hostload` build tag and needs `CAP_BPF`/`CAP_SYS_ADMIN`.\n\nA complete, real example is [`examples/preload-gate`](examples/preload-gate):\n\n![preload-gate.go — a real program using ValidateBeforeLoad](docs/images/library/library-code.png)\n\n```sh\ngo get github.com/kernel-guard/bpfcompat@v0.3.0\ngo build -tags hostload -o preload-gate ./examples/preload-gate\nsudo ./preload-gate probe.bpf.o\n```\n\nA compatible object passes; an incompatible one is blocked with the kernel's own\nverdict and a stable classification code — exit 0 vs 1:\n\n![preload-gate real run: a good object loads, a CO-RE failure is blocked](docs/images/library/library-run.png)\n\nSee [`pkg/bpfcompat/README.md`](pkg/bpfcompat/README.md) for the full API.\n(Pre-1.0 / experimental.)\n\n## Try it in CI without your own KVM box\n\nGitHub-hosted Linux runners now expose `/dev/kvm`, so the full QEMU VM\ncompatibility gate runs on a stock `ubuntu-latest` runner — no self-hosted KVM\nmachine required. This is proven end-to-end:\n[`.github/workflows/bpfcompat-example-hosted.yml`](.github/workflows/bpfcompat-example-hosted.yml)\nboots a disposable VM and runs the `dev-functional` suite (load + behavioral\nexecve) in **under two minutes**.\n\nOne gotcha: some hosted images expose `/dev/kvm` but the runner user isn't in\nthe `kvm` group, so QEMU can't open it. The example workflow runs\n`sudo chmod 0666 /dev/kvm` to handle that. If a runner genuinely lacks KVM,\nvalidation degrades to TCG software emulation (correct, just slower) instead of\nfailing.\n\n## Proof: a real Falco probe catches a real regression\n\n`bpfcompat` validates Falco's `modern_bpf` probe (`bpf_probe.o`, ~64 programs)\n**the way Falco's `libpman` loads it** — runtime-sized maps, helper-gated program\nvariants, and trial-probed BPF iterators, declared in a manifest so a plain\nlibbpf load doesn't undercount support. (This *mirrors* libpman's loader\ncontract; it is not Falco's loader binary itself — to run that exact binary, use\n[command mode](docs/command-validation.md).) Across a 5-kernel matrix:\n\n| Profile | Host kernel | Status | Why |\n|---|---|---|---|\n| `ubuntu-20.04-5.4` | `5.4.0-216` | ❌ fail | `UNSUPPORTED_MAP_TYPE` — ringbuf needs ≥ 5.8 |\n| `ubuntu-22.04-5.15` | `5.15.0-173` | ✅ pass | loads; selects `*_old_x` syscall variants |\n| `debian-12-6.1` | `6.1.0-47` | ✅ pass | loads; full variant set |\n| `ubuntu-23.10-6.5` | `6.5.0-44` | ✅ pass | loads; full variant set |\n| `ubuntu-24.04-6.8` | `6.8.0-106` | ✅ pass | loads; full variant set |\n\nThe red `5.4` row is the point: a kernel below Falco's real floor is flagged\n*before* shipping, with the exact mechanism (`ringbuf_maps` create returns\n`-EINVAL`) and remediation — not a generic \"it broke.\" Reproduce this matrix\nlocally; see [`docs/falco-parity.md`](docs/falco-parity.md).\n\n## Validate a published gadget in one command\n\neBPF gadgets ship as OCI images. Point `bpfcompat` at one by reference — it\nextracts the eBPF object, auto-sizes runtime-sized maps, and validates it across\nkernels with no manifest and no matrix file:\n\n```sh\nbpfcompat test --artifact ghcr.io/inspektor-gadget/gadget/trace_open:latest --quick\n```\n\nPulled straight from the registry, Inspektor Gadget's `trace_open`/`trace_exec`\nload and attach on 6.1/6.8 and are correctly flagged on 5.4 (the `events` ring\nbuffer needs ≥ 5.8) — and `trace_open` passes on AlmaLinux 8's backported 4.18,\nthe textbook \"kernel version ≠ feature support\" case. Full write-up, including\nthe `trace_dns` loader-contract finding:\n[`docs/case-study-inspektor-gadget.md`](docs/case-study-inspektor-gadget.md).\n\n## Current Status\n\nThe project is a serious MVP for compatibility evidence and CI gating. It is\nnot a production runtime loader and it is not a production multi-tenant SaaS.\n\nImplemented:\n\n- VM-backed `.bpf.o` validation through QEMU/KVM cloud images.\n- **Command/binary validation** (`bpfcompat test-command` / `test --command`) —\n  run *your own* loader binary/command inside each kernel VM and take its **exit\n  code** as the per-kernel verdict. The bundled validator is **not** used in this\n  mode; this tests the real userspace loader path. See\n  [docs/command-validation.md](docs/command-validation.md).\n- **Library of known-tricky vendor kernels** (`matrices/quirk-library.yaml`) —\n  the kernels where \"version ≠ feature support\" bites; run a `.bpf.o` or your\n  own loader against the whole set. See\n  [docs/kernel-quirk-library.md](docs/kernel-quirk-library.md).\n- C/libbpf validator that records load, attach, BTF, CO-RE, map, program, and\n  capability evidence (the default `.bpf.o` flow).\n- Failure classification for common compatibility cases such as missing BTF,\n  CO-RE relocation failures, unsupported map types, unsupported attach types,\n  and unsupported program types.\n- Multi-artifact suite support for collections of BPF objects/programs.\n- JSON, Markdown, GitHub Action summary, and static compatibility-site output.\n\nExperimental tracks (virtme-ng upstream lane, Firecracker backend, Web UI/API,\nruntime decisioning) are consolidated in\n[docs/experimental.md](docs/experimental.md) — kept as controlled proofs, not\nthe project's focus.\n\n## Install\n\nThere are three ways to get the CLI. Most users want the prebuilt release\nbinary or the source build, because running `bpfcompat test` also needs the\nguest-side validator binary and the kernel matrices that ship in this repo.\n\n**1. Prebuilt release binary (recommended, Linux x86_64).** Ships the CLI *and*\nthe static validator, checksum-verified:\n\n```bash\nVER=v0.3.0\nbase=\"https://github.com/Kernel-Guard/bpfcompat/releases/download/$VER\"\ncurl -fsSLO \"$base/bpfcompat-linux-amd64\"\ncurl -fsSLO \"$base/bpfcompat-validator-static-linux-amd64\"\ncurl -fsSLO \"$base/SHA256SUMS\"\nsha256sum -c SHA256SUMS --ignore-missing\nsudo install -m 0755 bpfcompat-linux-amd64 /usr/local/bin/bpfcompat\nbpfcompat version\n```\n\n![Installing bpfcompat from a prebuilt release binary](docs/images/install/install-release-binary.png)\n\n**2. From source.** Builds both the CLI and the validator and gives a binary\nstamped with the real version:\n\n```bash\ngit clone https://github.com/Kernel-Guard/bpfcompat\ncd bpfcompat\nmake build \u0026\u0026 make validator-static\n./bin/bpfcompat version\n```\n\n![Installing bpfcompat from source](docs/images/install/install-from-source.png)\n\n**3. `go install` (CLI only).** Note the module path is **lowercase** and the\ncommand **must** point at the `cmd/bpfcompat` subpackage — the module root has\nno `main` package, so `go install github.com/Kernel-Guard/bpfcompat@latest`\nfails with *\"found, but does not contain package …\"*:\n\n```bash\ngo install github.com/kernel-guard/bpfcompat/cmd/bpfcompat@latest\n```\n\nThis installs the orchestrator CLI only (it reports version `0.1.0-dev` because\n`go install` does not inject build-time ldflags). To run `bpfcompat test` you\nstill need the validator binary (from a release or `make validator-static`) and\na kernel matrix — use option 1 or 2 for that.\n\n![Installing bpfcompat with go install](docs/images/install/install-go-install.png)\n\n### What a run looks like\n\nOnce installed, `bpfcompat test` boots each kernel in a disposable VM and reports\na per-kernel pass/fail matrix — here the `ringbuf_modern` example across three\nkernels, correctly failing on 5.4 (ring buffer support lands in 5.8) and passing\non 6.1 and 6.8:\n\n![A bpfcompat validation run across three kernels](docs/images/install/live-validation.png)\n\n## Prerequisites\n\nFor the main QEMU path:\n\n- Linux host (a GitHub-hosted `ubuntu-latest` runner works; `/dev/kvm`\n  enables hardware acceleration, and bpfcompat falls back to TCG software\n  emulation when it is absent)\n- Go 1.25+\n- `make`\n- `clang`\n- `qemu-system-x86_64`\n- `qemu-img`\n- `ssh`\n- `scp`\n- `jq`\n- `pkg-config`\n- development packages for `libbpf`, `libelf`, and `zlib`\n\nOptional lanes:\n\n- ARM64 VM execution requires an ARM64/aarch64 KVM host, `qemu-system-aarch64`,\n  an ARM64 cloud image, and an ARM64 validator binary.\n- Upstream-kernel execution requires `virtme-ng` (`vng`) and `curl`.\n- Firecracker execution requires a Firecracker binary, `/dev/kvm`, `busybox`,\n  `cpio`, `gzip`, and an uncompressed guest kernel.\n\n## Build\n\n```bash\nmake doctor\nmake deps\nmake build\nmake validator\nmake examples\n```\n\nRestricted-network option:\n\n```bash\nmake vendor\nmake test-vendor\n```\n\nValidator modes:\n\n- `make validator` uses dynamic libbpf linking for local development.\n- `make validator-static` builds the guest-side validator used by VM profiles.\n\n## Quickstart: a collection across kernels\n\nCompatibility questions are rarely about one file. A release ships a\ncollection of BPF objects, and individual programs load differently across\nkernels — so suites are the primary workflow: artifacts + manifests + a\nkernel matrix in, one collection-level pass/fail matrix out.\n\nFast first run (one VM profile):\n\n```bash\nmake examples\nmake vm-ubuntu-22\nmake acceptance-suite-dev-one\n```\n\nRealistic collection across the 8-profile MVP matrix:\n\n```bash\nmake examples oss-examples\nmake vm-images\n./bin/bpfcompat suite \\\n  --suite suites/example-collection.yaml \\\n  --out reports/example-collection.json \\\n  --markdown reports/example-collection.md\n```\n\nEach case stages its artifact, boots a disposable VM overlay per kernel\nprofile, runs the C/libbpf validator inside the guest, and rolls the results\ninto a per-artifact × per-kernel matrix with structured failure reasons.\nExit code `2` means a required profile regressed, so the same command is the\nCI gate.\n\n### Single-artifact mode\n\n```bash\n./bin/bpfcompat test \\\n  --artifact examples/simple-pass/simple_pass.bpf.o \\\n  --manifest examples/simple-pass/manifest-dev-one.yaml \\\n  --matrix matrices/dev-one.yaml \\\n  --out reports/dev-one.json \\\n  --markdown reports/dev-one.md \\\n  --timeout 8m\n```\n\n`make acceptance-dev-one` wraps the same flow.\n\n### Runtime-sized maps\n\nSome artifacts compile maps with `max_entries=0` and size them from\nuserspace at load time (per-CPU arrays, ring buffers — Falco's `modern_bpf`\nprobe is the canonical example). Declare those maps in the manifest so the\nvalidator mirrors what the real loader does before load:\n\n```yaml\nmaps:\n  - name: auxiliary_maps\n    max_entries: cpus\n  - name: ringbuf_maps\n    max_entries: cpus\n    inner_ringbuf_bytes: 8388608\n```\n\nSee [`docs/validator.md`](docs/validator.md) for details.\n\n### Dense kernel sweeps and freshness\n\nOne cloud image samples a kernel series at a single release. The sweep lane\ninstalls exact kernel releases (from the distro archive pool, indexed by\n[falcosecurity/kernel-crawler](https://github.com/falcosecurity/kernel-crawler))\ninside the guest and reboots into them before validating:\n\n```bash\n./bin/bpfcompat kernel-sweep --profile ubuntu-22.04-5.15 --count 4\n./bin/bpfcompat test --artifact app.bpf.o \\\n  --matrix matrices/kernel-sweep-ubuntu-22.04-5.15.yaml --timeout 20m ...\n```\n\n`bpfcompat kernel-freshness` compares each profile's last-validated kernel\nagainst what its distro currently ships and flags stale evidence (run\nweekly in CI). See [`docs/image-pipeline.md`](docs/image-pipeline.md).\n\n## Main Acceptance Flows\n\nFast local checks:\n\n```bash\nmake acceptance-dev-one\nmake acceptance-functional-dev-one\nmake acceptance-suite-dev-one\n```\n\nFull MVP matrix:\n\n```bash\nmake vm-images\nmake acceptance\n```\n\nExpanded runnable matrix:\n\n```bash\nmake vm-images-expanded-2026\nmake matrix-runnable\nmake acceptance-expanded-runnable\n```\n\nReal OSS artifact examples:\n\n```bash\nmake oss-examples\nmake oss-evidence\n```\n\n`make oss-evidence` writes generated outputs under `evidence/oss-validation/`.\n\n## Backend Lanes\n\nQEMU/KVM distro profiles (the default and supported lane):\n\n```bash\nmake acceptance-dev-one\n```\n\nARM64 smoke:\n\n```bash\nmake doctor-arm64-kvm\nmake acceptance-arm64-smoke\n```\n\nThe ARM64 workflow is wired, but real ARM64 VM compatibility proof requires a\nnative ARM64 KVM runner.\n\nThe experimental backends — upstream-mainline via `virtme-ng` and the\nFirecracker generated-initramfs proof — live in\n[docs/experimental.md](docs/experimental.md).\n\n## GitHub Action\n\nThis repository includes a composite action that runs `bpfcompat` and appends\nthe Markdown report to the GitHub Actions job summary. VM-backed validation\nruns on a stock GitHub-hosted `ubuntu-latest` runner (which now exposes\n`/dev/kvm`); a self-hosted KVM runner is only needed for wide matrices, ARM64,\nor the Firecracker lane. See\n[`.github/workflows/bpfcompat-example-hosted.yml`](.github/workflows/bpfcompat-example-hosted.yml).\n\nSuite mode (recommended — gates the whole collection):\n\n```yaml\n- uses: Kernel-Guard/bpfcompat@v0.3.0\n  with:\n    suite: suites/project.yaml\n    suite-out: reports/suite.json\n    suite-markdown: reports/suite.md\n```\n\nSuite cases can opt into `validation_mode: load_only`, `load_attach`, or\n`behavior`. Behavior mode runs manifest or suite smoke commands while BPF links\nare alive and adds the result to the suite-level collection matrix.\n\nSingle artifact:\n\n```yaml\n- uses: Kernel-Guard/bpfcompat@v0.3.0\n  with:\n    artifact: path/to/program.bpf.o\n    manifest: path/to/manifest.yaml\n    matrix: path/to/matrix.yaml\n    out: reports/bpfcompat.json\n    markdown: reports/bpfcompat.md\n    validation-mode: load_attach\n    timeout: 8m\n```\n\nCommand mode — run your project's own loader on every matrix kernel (the\nper-kernel verdict is the loader's exit code), against the built-in\n[library of known-tricky vendor kernels](docs/kernel-quirk-library.md):\n\n```yaml\n- uses: Kernel-Guard/bpfcompat@v0.3.0\n  with:\n    command: $BPFCOMPAT_BIN --self-test\n    command-binary: build/myloader   # static or fully self-contained binary\n    matrix: quirk-library            # bare name -\u003e matrices/ shipped with the action\n    out: reports/bpfcompat.json\n```\n\nMarketplace quick start:\n\n1. Use a stock `ubuntu-latest` runner (it exposes `/dev/kvm`); a self-hosted\n   KVM runner is only needed for wide matrices or ARM64.\n2. Commit compiled `.bpf.o` artifacts (or point `command` at your loader),\n   plus a matrix YAML — or use a built-in matrix name like `quirk-library`.\n3. Use the action in CI to produce JSON, Markdown, and job-summary evidence.\n4. Treat exit code `2` as a compatibility gate failure.\n\n## Web UI / API and Runtime Decisioning (experimental)\n\nBoth tracks are kept as controlled proofs, not the product surface — the\nsupported product is the **CLI + GitHub Action in CI**. The embedded demo UI\n(`make serve`), the HTTP API, and the frozen runtime probe/select/fetch/agent\nflow (host loading disabled/gated by default) are documented together in\n[docs/experimental.md](docs/experimental.md).\n\n## Documentation Map\n\nUser guide — start here:\n\n- [`docs/architecture.md`](docs/architecture.md)\n- [`docs/project-compatibility-suite.md`](docs/project-compatibility-suite.md) — suites and collection matrices\n- [`docs/validator.md`](docs/validator.md) — what the in-guest validator checks\n- [`docs/command-validation.md`](docs/command-validation.md) — validate via your own loader binary/command (exit-code verdict)\n- [`docs/ebpf-go-validation.md`](docs/ebpf-go-validation.md) — validate through ebpf-go (cilium/ebpf): a libbpf pass ≠ an ebpf-go pass\n- [`docs/kernel-quirk-library.md`](docs/kernel-quirk-library.md) — curated library of known-tricky vendor kernels (version ≠ feature support)\n- [`docs/profile-catalog.md`](docs/profile-catalog.md) — kernel/distro profiles and image maintenance\n- [`docs/image-pipeline.md`](docs/image-pipeline.md) — where images come from, integrity, adding profiles\n- [`docs/rhcos-openshift.md`](docs/rhcos-openshift.md) — RHCOS/OpenShift (Ignition boot, operator-supplied image)\n- [`docs/experimental.md`](docs/experimental.md) — virtme-ng lane, Firecracker backend, Web UI/API, runtime decisioning\n\nReference matrices (real, reproducible artifacts):\n\n- [`docs/case-study-falco-modern-bpf.md`](docs/case-study-falco-modern-bpf.md) — Falco `modern_bpf` across 5 kernels\n- [`docs/case-study-enterprise-kernels.md`](docs/case-study-enterprise-kernels.md) — RHEL/Oracle/Amazon/SUSE backported tier\n- [`docs/case-study-inspektor-gadget.md`](docs/case-study-inspektor-gadget.md) — published gadgets from OCI, zero config\n- [`docs/evidence-rhcos.md`](docs/evidence-rhcos.md) — RHEL CoreOS / OpenShift 4.14·4.16·4.18 × 6 artifacts (x86_64) + a real aarch64 boot\n\nInternal evidence and program docs (acceptance records, runbooks, and\nplanning notes — useful for contributors, not needed to use the tool):\n\n- [`docs/acceptance-tests.md`](docs/acceptance-tests.md)\n- [`docs/falco-parity.md`](docs/falco-parity.md)\n- [`docs/supply-chain.md`](docs/supply-chain.md) — supply-chain controls and maintainer repo settings\n- [`docs/backend-execution-proof.md`](docs/backend-execution-proof.md)\n- [`docs/external-ci-proof.md`](docs/external-ci-proof.md)\n- remaining `docs/*.md` proof, runbook, and checklist documents\n\n## Development\n\n```bash\nmake test\nmake openapi-check\nmake env-docs-check\ngo vet ./...\ngolangci-lint run --timeout=5m\ngovulncheck ./...\n```\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md) for route, env, test, and changelog\nexpectations.\n\n## Security\n\nReport security issues through [`SECURITY.md`](SECURITY.md), not public issues.\n\nOperator guidance:\n\n- keep runtime execute disabled on public demos;\n- require write auth or explicit anonymous-demo flags for POST paths;\n- do not enable internal-host or `file://` fetches outside controlled tests;\n- run host-loading flows only through a local policy-gated agent path.\n\n### Supply-chain posture\n\n- **Static analysis:** GitHub CodeQL (`codeql.yml`) plus `govulncheck` and\n  `golangci-lint` in CI on every PR.\n- **Dependency updates:** Dependabot (`dependabot.yml`) for Go modules and\n  pinned GitHub Actions, grouped weekly.\n- **Risk scoring:** OpenSSF Scorecard (`scorecard.yml`), published to the\n  public Scorecard API (badge above).\n- **Signed releases + SLSA provenance:** tag builds produce a CycloneDX SBOM,\n  cosign keyless (Sigstore OIDC) signatures over the binaries / `SHA256SUMS` /\n  SBOM, and **SLSA Build L3 build-provenance attestations** bound to the\n  producing commit and workflow (`release-artifacts.yml`). Quick check:\n\n  ```bash\n  gh attestation verify ./bpfcompat-linux-amd64 --repo Kernel-Guard/bpfcompat\n  ```\n\n  Full verification steps (provenance, cosign, SBOM) are in\n  [`docs/verifying-releases.md`](docs/verifying-releases.md).\n\nMaintainer-side repo settings (branch protection, secret-scanning push\nprotection, OpenSSF Best Practices registration) are tracked in\n[`docs/supply-chain.md`](docs/supply-chain.md).\n\n## License\n\nApache-2.0. See [`LICENSE`](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkernel-guard%2Fbpfcompat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkernel-guard%2Fbpfcompat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkernel-guard%2Fbpfcompat/lists"}