Skip to content
trishula-devPublic

About

eBPF-native, developer-first WAF & API firewall for Kubernetes — kernel shield · userspace engine · control plane

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Trishula

eBPF-native, developer-first Web Application and API Firewall for Kubernetes. kernel shield · userspace engine · control plane

license GitHub commit activity Libraries.io dependency status for GitHub repo GitHub Release

pre-commit.ci status go-build Dependency Review cue-gate OpenSSF Scorecard OpenSSF Best Practices

Trishula protects Kubernetes traffic in three planes. The kernel shield runs verifier-checked eBPF programs. The userspace engine runs the detection stack: OWASP CRS, CEL rules, OpenAPI positive security, bot fingerprints and the ban table. The control plane compiles WAFPolicy CRDs into signed policy bundles. Every verdict is a correlated OpenTelemetry record.

Status: the 2026.01-rc3 component set sits merged on main. The socket-plane compiler pathway lands its first class (route marking) with a machine-checked verifier gate. The lab gates run green on a live cluster. The bench harness measures the §17 walls in CI. The gaps carry their own list on this page.

What exists today

Each slice landed as a watched-RED then GREEN leaf PR per AGENTS.md.

Component Where What exists Evidence
Shield loaders internal/shield/ CO-RE XDP + TC objects (arm64, amd64); Go loaders; fail-closed TierRefusal; tier measure at boot. #80 tier run · #10 ban E2E
Kernel C + wire bpf/ shield_xdp.c (ACL, verdict cache, ban table), flow_tc.c (ringbuf); wire layouts test-pinned. banwire tests in-package
Ingest internal/engine/ingest/ ringbuf drain → decode → per-connection assembly; kernel-free. TR-04d merge
Detection ladder internal/engine/ladder/ S0–S5 wiring + verdict vocabulary; HTTP/1 and HTTP/2/gRPC parse. TR-05 merge
OTel telemetry internal/engine/otel/ span + metric + log record, correlated by request id; the trishula.ban record and the verdict.dos.sig signature attribute (TR-195). #11 evidence · #250 tests in-package
Bot fingerprints internal/engine/botdef/ JA4 + header-plane detector; golden vectors. #99
Positive security internal/engine/positive/ OpenAPI 3.1-subset body gate; fail-closed. #13 evidence
CRS evaluator internal/crs/ · test/crs-differential/ embedded Coraza reference + CI-blocking parity differential. #7 parity 19/19
ScoredWindowBan internal/engine/rateban/ §13.3 ban with clock seam + evidence; kernel publish. #10 in-VM E2E
Rate algorithms internal/engine/rateban/ token bucket, multi-window sliding, EWMA per §13.2; CRD-selected; Retry-After on every throttle. #20 RED/GREEN tables in-package
Behavioural DoS detectors internal/engine/rateban/ · bpf/flow_tc.c slowloris shape over the kernel's flow-window features + the h2 rapid-reset ratio; kernel counts and stamps only; the detector path scores, never enforces. #31 RED/GREEN tables in-package + the ingest4d kernel gate
Shield DoS runner cmd/shield/ · internal/shield/ TR-195: the pinned flow_stats sweep → the detector cues → the scored path → the enforcer publish; the cue, the evidence row and the kernel row state the same signature. #249 tests in-package; in-VM acceptance #253
Operator internal/operator/ · api/v1alpha1/ WAFPolicy CRD → bundle compile (fail closed) → publish. #76 M9 evidence
Manual ban rules internal/operator/ · cmd/engine/ TR-195: a CEL rule action: ban stops the request with 403 + X-Trishula-Decision: ban + the owning rule; the rule emits the manual-rule would-ban record with the signature. #248 tests in-package · #252 consult-signal tests
Route-class fast path internal/fastpath/ · bpf/ TR-40b: the route class compiles through the census into the template, loads through the verifier under route-gate.yml, and the split reads back. A tracked evaluation; no runtime commitment. census record §9
Engine + consult cmd/engine/ transparent proxy; bundle consult; hot reload; one verdict-signal emission per consult decision (the ban decisions carry the signature). #6 hop evidence · #252 consult-signal tests
DX1 lab lab/dx1/ · lab/demo.sh idempotent bring-up; timed apply→effect; hop verification. Proof record

Measured performance

Budgets read off §17.1. Wall numbers read from the last recorded per-row CI run. The run: 40147859961, head 05affd9, the rc3 content with the verbose bench step (#230). The numbers re-read at each release. Each row's wall carries the receipt comment this read posted.

Cell Budget p99 Last build p99 Verdict
idle-get 600 µs 865.0 µs unmet (1.44x) on this read — runner noise; the quiet rig reads 0.30x
attack-sqli-small 1500 µs 1029.0 µs holds (0.69x)
attack-xss-small 1500 µs 1078.9 µs holds (0.72x) — variance class, #147
ladder-json-1k 600 µs 825.7 µs unmet (1.38x) on this read — runner noise; the quiet rig reads 0.64x
ladder-json-8k 600 µs 862.1 µs unmet (1.44x) — variance class, #147
ladder-json-64k 1200 µs 1096.6 µs holds (0.91x)
ladder-form-dense-1k 600 µs 15395.2 µs pinned open — the §17.1
ladder-form-dense-8k 600 µs 135633.1 µs pinned open — the §17.1
steady-json-8k (the M2 e2e cell) 1500 µs 433.7 µs holds (0.29x)

Upcoming features

The list pairs each not-shipped feature with its tracker.

  • Inline < 10 ms walls on the lab plane — the CI harness measures engine-only cells today.
  • Verdicts on live ringbuf traffic inside cluster pods — a later engine slice.
  • HTTP/3 request-path parse — the posture evaluation record publishes (TR-29); the parse is a later engine slice.
  • Socket-plane: more policy classes after route marking, and the kTLS posture — the first class lands as a tracked evaluation (#52).
  • trishulactl full CLI surface — the skeleton exists; the surface is a later phase.
  • OpenAPI promotion gates — learn mode and drift telemetry ship (TR-18); the full gate ladder rides later slices (#18).
  • ML scoring beyond v0 — the ONNX in-band scorer ships (TR-21); the adaptive tier rides later slices (#21).
  • Wire-out OTLP export — the triad verifies in-memory today.
  • The DPU-class port — the evaluation record publishes (TR-32); the port itself rides a later phase (#32). Multi-arch and OpenShift notes ship (TR-33); the rows leave this list.

The board is the Trishula Roadmap.

api/v1alpha1/     CRD types (WAFPolicy, BanPolicy, …)
cmd/              engine, operator, shield, trishula, trishulactl, attackdemo, cuegen
bpf/              shield_xdp.c, flow_tc.c (CO-RE, bpf2go)
cue/              CUE definitions — the declarative layer (TR-46), the golden-diff source
internal/         engine (ingest, ladder, cel, http1, http2, otel, botdef, positive, rateban), operator, shield, cuegen
manifests/        install manifests (the CRD only; controller-gen-owned)
deployment/       derived manifests (the dx1 lab tree, written by cmd/cuegen — never hand-edited)
lab/              demo.sh · dx1/ · demo-attack.sh · verify-xdp-chain.sh · tier-gate.sh
test/             crs-differential · ban-conformance · banenforce · tier · bench
docs/             spec, paper, academy

Run the demo (one command)

just demo        # or: bash lab/demo.sh

just alone lists every lab lane; the runner installs with brew install just. The prereq gate = docker OR a reachable kubernetes cluster; the gate runs inside the scripts (lab/prereq.sh). The script brings the DX1 lab up on the cluster your kubeconfig points at — a local kind or OrbStack, or a cloud Kubernetes. Needs go, kubectl, helm and one of the two target surfaces. It builds the engine and operator binaries, applies the policy and runs the timed apply→effect scenario. The exit banner reads DEMO-OK or DEMO-FAIL. The verbatim recorded output sits on the issue record above.

Run the timed gate

bash lab/dx1/dx1-gate.sh

The gate asserts: clone → first enforced rule in ≤ 15 min. The nightly job keeps the timing asserted.

Run the tests

go test ./...

The suite gates the bench walls, the CRS parity differential (19/19 corpus cases), the ban conformance set, the shield tier gate and the docs guards.

Run the bench on the dev VM

lab/bench-vm.sh runs the §17.2 rig in the dev VM. Start from a VM copy of the tree:

orb run -m trishula-build-dev -u root bash /mnt/mac/<path-to-clone>/lab/bench-vm.sh

The script prints four sections: the new CI shape, the old-shape control, the walls with the prefilter on and the control with it off. The VM is the A/B surface. Hosted CI stays the calibration surface.

Proof

The verbatim lab/demo.sh output for the rc1 exit (2026-10-10) sits on the recorded run at main ed9b271. The hop, M9 and parity evidence trails link from the rows above.

Shield visibility tiers

The shield measures what the hook sees (#80). On OrbStack-family pod-veths the attach altitude is not the effective altitude.

Tier Meaning Enforcement posture
full every packet at both altitudes (XDP + TC) full payload visibility at TC
first_packet first packet only (OrbStack pod-veth posture) ban/ACL on new connections only; sampled flows
none no packets visible loader refuses and fails loudly (TierRefusal)

License

MIT — see LICENSE.

About

eBPF-native, developer-first WAF & API firewall for Kubernetes — kernel shield · userspace engine · control plane

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages