bpfcompat serve provides a local web interface and HTTP API for:
- uploading
.bpf.oartifacts or.bpf.csource, - selecting distro/kernel target profiles,
- running VM-backed validation,
- exporting compatibility report JSON through API responses,
- tracking artifact version history,
- comparing compatibility between artifact versions.
The web UI is intentionally optimized for the primary compatibility workflow:
- select target kernels from presets or a custom matrix,
- upload or compile one BPF object, or preview a collection suite,
- choose the test intent,
- run the compatibility gate,
- read the verdict and pass/fail matrix first, then open drill-down evidence only when needed.
Target selection supports presets plus a search/filter box for narrowing long kernel catalogs by distro, kernel family, or architecture. After a run, the first result panel shows a plain verdict, required/optional target counts, a filterable color-coded matrix, and required failures sorted first. The run builder also shows a live readiness strip for selected targets, BPF input, and expected output before the gate starts. History, compare, and runtime decision proof stay behind the Advanced evidence and history drawer and are loaded only when that drawer is opened.
For projects that ship collections of BPF objects/programs, use suite mode in
the CLI or GitHub Action. The web UI treats the collection as a first-class
gate input: it previews object cases, counts load_only, load_attach, and
behavior checks, mirrors the collection summary in the result panel, and
generates both the local CLI command and GitHub Action YAML. Real collection
execution remains CI-first. Suite cases may choose validation_mode: load_only, load_attach, or behavior; behavior mode runs manifest or suite
test commands while the BPF links are alive and reports those results in the
suite-level matrix.
The public web gate intentionally exposes only the low-risk single-object paths:
- Load only: verifier/libbpf load evidence without attaching hooks.
- Load + attach: load plus best-effort attach evidence.
Behavior assertions and production runtime loading stay in the lower-level CLI/action/agent paths because they need project-specific scripts, host capabilities, and operator policy.
make build
make validator-static
BPFCOMPAT_API_ALLOW_ANONYMOUS_VALIDATE=true \
BPFCOMPAT_API_ALLOW_ANONYMOUS_READ=true \
BPFCOMPAT_API_ALLOW_ANONYMOUS_RUNTIME_DELIVERY=true \
./bin/bpfcompat serve --addr :8080 --workdir .bpfcompat --matrix matrices/mvp.yamlFor local demos:
make serve(make serve starts the public-demo profile by default: validation, read-only
history, and runtime select/fetch proof are available without a write key.
Runtime execute remains hidden/disabled in the public UI.)
Open:
http://127.0.0.1:8080http://127.0.0.1:8080/results(mobile-friendly latest result snapshot)
GET /resultsGET /demo-resultGET /api/healthGET /api/configGET /api/profilesPOST /api/validate(multipart form)GET /api/history/artifacts?artifact_name=<name>&limit=<n>GET /api/history/runs?limit=<n>GET /api/history/run-report?run_id=<run-id>POST /api/compareGET /api/runtime/probeGET /api/runtime/decisions?limit=<n>&workdir=<path>POST /api/runtime/selectPOST /api/runtime/fetchPOST /api/runtime/execute(JSON body, explicitallow_host_load=truerequired)GET /api/registry/projects?tenant=<tenant>[&project=<project>&limit=<n>]POST /api/registry/projectsPOST /api/registry/artifacts/upload(multipart form)GET /api/registry/artifacts?tenant=<tenant>&project=<project>[&artifact_name=<name>&limit=<n>]GET /api/registry/artifacts/download?tenant=<tenant>&project=<project>&artifact_name=<name>&version=<v>GET /api/registry/history/verify?tenant=<tenant>&project=<project>GET /api/registry/audit/events?tenant=<tenant>[&project=<project>&limit=<n>]
GET /api/runtime/probe query options (all optional):
prefer_privileged=true|falseuse_sudo=true|falsesudo_non_interactive=true|false
Runtime policy object (optional for select/fetch/execute):
{
"policy": {
"require_summary_pass": true,
"min_required_passed": 1,
"max_required_failed": 0,
"require_attach_support": true,
"deny_classification_codes": ["UNKNOWN"],
"allow_classification_codes": ["MISSING_BTF", "UNSUPPORTED_MAP_TYPE"]
}
}Runtime probe object (optional for select/fetch/execute):
{
"probe": {
"prefer_privileged": true,
"use_sudo": true,
"sudo_non_interactive": true
}
}Runtime select/fetch/execute responses include:
correlation_idfor cross-linking API responses with runtime decision trace and registry audit events- operation payload (
selection,fetch,execution) - optional
host_probeandselectioncontext where applicable - optional
history_verificationsummary (when strict history verification is enabled; default for fetch/execute) auditmetadata withdecision_id, trace file path, and event stream path- optional
audit_errorwhen operation succeeds but audit persistence fails
GET /api/profiles includes execution-readiness hints:
source_mode:urlormanual-localsource_url: profile image URL when availabletransport: execution transport (sshorunsupported)transport_supported: whether current validator executor can run this profiletransport_note: reason when transport is unsupported
UI behavior for unsupported transports:
- profiles with
transport_supported=falseare not selected by default - "Select All" only selects transport-supported profiles
Runtime fetch and execute request fields:
require_verified_history(optional, defaulttrue):- when
true, operation fails closed if signed history verification is not clean - when verification fails, API returns
412 Precondition Failed
- when
Runtime execute additional required fields:
tenantproject
Runtime execute auth requirements:
- write auth (one of):
- API key:
X-API-Key - JWT identity token:
X-API-Identity-Token(HS256orRS256), configured by:BPFCOMPAT_API_WRITE_JWT_HS256_SECRET(HS256)BPFCOMPAT_API_WRITE_JWT_JWKS_PATH(RS256 JWKS file path)BPFCOMPAT_API_WRITE_JWT_JWKS_URL(RS256 JWKS URL)BPFCOMPAT_API_WRITE_JWT_JWKS_CACHE_TTL(default5m)BPFCOMPAT_API_WRITE_JWT_JWKS_HTTP_TIMEOUT(default5s)BPFCOMPAT_API_WRITE_JWT_OIDC_ISSUER_URL(optional issuer discovery URL)BPFCOMPAT_API_WRITE_JWT_OIDC_DISCOVERY_CACHE_TTL(default10m)BPFCOMPAT_API_WRITE_JWT_REQUIRED_SCOPES(optional global required scopes)BPFCOMPAT_API_WRITE_JWT_REQUIRED_ROLES(optional global required roles)BPFCOMPAT_API_WRITE_JWT_REQUIRED_SCOPES_<ACTION>(optional per-action scopes)BPFCOMPAT_API_WRITE_JWT_REQUIRED_ROLES_<ACTION>(optional per-action roles)BPFCOMPAT_API_RUNTIME_EXECUTE_JWT_REQUIRED_SCOPES(optional runtime-execute-only scopes)BPFCOMPAT_API_RUNTIME_EXECUTE_JWT_REQUIRED_ROLES(optional runtime-execute-only roles)BPFCOMPAT_API_WRITE_REQUIRE_IDENTITY=true(fail closed)- optional issuer/audience checks:
BPFCOMPAT_API_WRITE_JWT_ISSUER,BPFCOMPAT_API_WRITE_JWT_AUDIENCE
- API key:
- execute approval token (
X-Execute-Approval-Token) - registry scope token in
Authorization: Bearer <token>authorized for the requesttenant/project - for runtime execute, keep registry auth in
Authorizationand send write identity viaX-API-KeyorX-API-Identity-Token - RS256 JWKS verification caches keys by source and performs a forced refresh retry on signature/key mismatch to handle key rotation.
- if explicit OIDC issuer URL is not set and
BPFCOMPAT_API_WRITE_JWT_ISSUERis anhttpsURL, discovery falls back to that issuer. JWKS/OIDC URL verification requires HTTPS in production. - JWT write auth checks
scope/scpclaims androles/roleclaims when required-scope/role env gates are configured. - action-specific claim gates support actions
COMPARE,RUNTIME_SELECT,RUNTIME_FETCH,RUNTIME_EXECUTE,VALIDATE,REGISTRY_PROJECT_READ,REGISTRY_PROJECT_LIST,REGISTRY_PROJECT_UPSERT,REGISTRY_ARTIFACT_UPLOAD,REGISTRY_ARTIFACT_LIST,REGISTRY_ARTIFACT_DOWNLOAD,REGISTRY_HISTORY_VERIFY, andREGISTRY_AUDIT_LIST. - optional anonymous validate mode:
BPFCOMPAT_API_ALLOW_ANONYMOUS_VALIDATE=trueallowsPOST /api/validatewithout write auth and allows matching validate-status reads (other POST endpoints still require write auth). - optional anonymous read mode:
BPFCOMPAT_API_ALLOW_ANONYMOUS_READ=trueopens history/status/runtime read endpoints for public demos. - host load execution is delegated from API to worker process
bpfcompat runtime worker-execute - optional worker identity controls:
BPFCOMPAT_API_RUNTIME_EXECUTE_WORKER_USERBPFCOMPAT_API_RUNTIME_EXECUTE_REQUIRE_WORKER_IDENTITY=true
- optional runtime execute policy controls:
BPFCOMPAT_API_RUNTIME_EXECUTE_POLICY_PATHBPFCOMPAT_API_RUNTIME_EXECUTE_REQUIRE_POLICY=true
Registry endpoints use bearer-token auth (Authorization: Bearer <token>).
Token grants are loaded from:
.bpfcompat/cloud-registry/auth/tokens.json
Sample grant file:
{
"schema_version": "cloud_registry_auth.v0.1",
"tokens": [
{
"token": "acme-admin-token",
"subject": "acme-admin",
"tenant": "acme",
"projects": ["*"],
"can_read": true,
"can_write": true
}
]
}Optional bootstrap shortcut for local demos:
export BPFCOMPAT_REGISTRY_AUTH_TOKEN='<short-lived-bootstrap-token>'
# Optional RFC3339 validity window. Recommended even for short-lived demos.
export BPFCOMPAT_REGISTRY_AUTH_TOKEN_NOT_BEFORE='2026-05-27T00:00:00Z'
export BPFCOMPAT_REGISTRY_AUTH_TOKEN_EXPIRES_AT='2026-05-28T00:00:00Z'Optional identity gate for registry endpoints:
BPFCOMPAT_API_REGISTRY_REQUIRE_IDENTITY=truerequiresX-API-Identity-TokenJWT on all registry endpoints.- registry identity uses the same verifier config as write endpoints (
BPFCOMPAT_API_WRITE_JWT_HS256_SECRET,BPFCOMPAT_API_WRITE_JWT_JWKS_PATH,BPFCOMPAT_API_WRITE_JWT_JWKS_URL,BPFCOMPAT_API_WRITE_JWT_OIDC_ISSUER_URL). - per-action scope/role gates apply to registry actions with:
BPFCOMPAT_API_WRITE_JWT_REQUIRED_SCOPES_<ACTION>BPFCOMPAT_API_WRITE_JWT_REQUIRED_ROLES_<ACTION>
- when identity token claims include
tenantand/orprojects, they are enforced against requested registry tenant/project scope.
Operational controls (env-configurable):
- Registry API rate limiting (per
subject+tenant+project+action):BPFCOMPAT_REGISTRY_RATE_LIMIT_MAX_REQUESTS(default120)BPFCOMPAT_REGISTRY_RATE_LIMIT_WINDOW_SECONDS(default60)
- Registry project upload quotas:
BPFCOMPAT_REGISTRY_MAX_ARTIFACT_BYTES(default67108864)BPFCOMPAT_REGISTRY_MAX_ARTIFACT_VERSIONS_PER_NAME(default200)BPFCOMPAT_REGISTRY_MAX_PROJECT_STORAGE_BYTES(default2147483648)
When a request is denied by authz/rate-limit/quota, a deny audit event is appended to the registry audit stream.
For runtime_execute/runtime_execute_denied, audit metadata includes:
correlation_idapproved_byrequested_byrequested_versiontarget_profile- selected-version context when available
- success context such as
artifact_sha256,execution_status, andworker_identity
Project visibility modes:
private: token required for read/writepublic: anonymous read allowed for artifact listing/download; write still requires token
Required input:
- one of:
artifact_filesource_filesource_code
Optional fields:
manifest_filemanifest_textprofiles(repeated field for selected profile IDs)required_profiles(repeated field for required IDs among selected)artifact_nameartifact_versionartifact_variantartifact_uri(optional canonical remotehttp/httpsURI used later by runtime fetch/execute when local paths are unavailable;file://is disabled by default outside explicit local proof runs)timeout(for example8m)concurrency(for example2)clang_flags(used only with source input mode)
{
"tenant": "acme",
"project": "aegis-bpf",
"visibility": "private",
"default_matrix_path": "matrices/mvp.yaml"
}Required:
tenantprojectartifact_nameartifact_versionartifact_file
Optional:
artifact_variantartifact_uriartifact_sha256(expected SHA-256 integrity check)manifest_pathsource_run_idreport_fileorreport_json(existing validation report)- compatibility hints when no report is provided:
summary_statusrequired_passedrequired_failedtotal_profilesmatrix_pathmatrix_namesupported_profiles(repeat or comma-separated)failed_profiles(repeat or comma-separated)classification_codes(repeat or comma-separated)
Either direct report paths:
{
"base_report": "reports/ringbuf-modern-mvp.json",
"head_report": "reports/perfbuf-fallback-mvp.json"
}Or artifact-version lookup from registry history:
{
"artifact_name": "perfbuf_fallback",
"base_version": "v1",
"head_version": "v2"
}- run metadata index:
.bpfcompat/registry/runs.jsonl - artifact version history index:
.bpfcompat/registry/artifact_versions.jsonl - artifact history signing keys:
.bpfcompat/keys/artifact-registry-signing-key.ed25519+.pub - optional enterprise signer mode:
BPFCOMPAT_SIGNING_MODE=external-cmdwithBPFCOMPAT_SIGNING_EXTERNAL_CMD - runtime decision event stream:
.bpfcompat/registry/runtime_decisions.jsonl - per-decision trace files:
.bpfcompat/runtime-audit/decisions/<decision-id>.json - per-run metadata:
.bpfcompat/runs/<run-id>/metadata.json
Cloud-registry storage layout:
- project metadata:
.bpfcompat/cloud-registry/tenants/<tenant>/projects/<project>/project.json - project artifact binaries:
.bpfcompat/cloud-registry/tenants/<tenant>/projects/<project>/artifacts/** - project signed artifact history:
.bpfcompat/cloud-registry/tenants/<tenant>/projects/<project>/registry/artifact_versions.jsonl - project signing keys:
.bpfcompat/cloud-registry/tenants/<tenant>/projects/<project>/keys/* - registry audit stream:
.bpfcompat/cloud-registry/audit/events.jsonl