Recipe 1 — Install Trishula on a kind cluster and see the first verdict
| Tool | Section | Level | Time | Layer | Tags |
|---|---|---|---|---|---|
lab/dx1/ on any Docker provider (kind, or OrbStack Kubernetes) |
Getting started | easy | 15 min | gateway + engine | install, kind, verdict |
Problem
You want Trishula on a local Kubernetes cluster. You want one enforced verdict on one probe request. You want it inside the 15 min M3 gate window. You do not want a hosted cluster or manual manifests.
Solution
You need just, go, kubectl, helm, crane and curl. just = the entry runner. brew install just installs it. just alone lists the lanes. bash lab/... stays equivalent. One target surface: docker OR a reachable Kubernetes. Pick a local kind, the OrbStack-provided Kubernetes or any cluster your kubeconfig points at. The prereq gate in lab/prereq.sh prints the target it found.
- Clone the product repository:
git clone https://github.com/trishula-dev/trishula && cd trishula- Run the timed DX1 gate. The gate builds the linux binaries, brings the lab up and times the first enforced rule:
bash lab/dx1/dx1-gate.sh- Read the printed evidence. The shapes below come from the recorded run. Volatile values stand as placeholders:
== pre-policy baseline: the benign probe passes transparently (200)
== (d) effect: SQLi probe → 403
HTTP/1.1 403 Forbidden
== M9 apply→effect: <ms> (target ≤ 5s) — PASS
== DX1 verify: hop 1 NGF -> hop 2 engine -> hop 3 echo pod all evidenced above
== Done. The lab remains installed (no teardown).
The gate asserts the verdict fields on the blocked probe: X-Trishula-Decision: block and X-Trishula-Rule: DX-LAB-001. The probe answers 403.
- The three legs run alone. Each leg is idempotent. The lab stays installed:
bash lab/dx1/setup.sh
bash lab/dx1/apply-effect.sh
bash lab/dx1/verify.shsetup.sh reuses the cluster, rebuilds the engine image and re-applies the manifests. apply-effect.sh applies the policy, compiles the bundle and times the apply→effect leg. verify.sh prints the hop-by-hop evidence. Re-run any leg at any time.
Discussion
The request path carries three hops:
client ──> NGF edge-gateway ──> dx1-engine ──> dx1-echo
The engine hop marks its response with X-Trishula-Hop: engine. A second Host value on the same NodePort skips the engine. The HTTPRoute steers only the engine host.
The apply leg applies the lab WAFPolicy. The operator compiles rule DX-LAB-001 and publishes the bundle. The engine picks up the bundle. No restart happens. The SQLi probe is a POST with a UNION probe in the query string. The engine answers 403. The benign POST still passes: defaultAction: pass keeps the transparent forward.
The M9 leg carries a 5 s budget. The recorded smoke read 1174 ms. The M3 budget is 15 min from clone to first enforced rule. The gate fails above either budget.
A broken policy fails at compile. The operator publishes no bundle. The engine keeps the loaded bundle. The traffic shape does not change. Both pods stay Ready.
On OrbStack-provider Kubernetes, the NGF 2.x dataplane does not register. setup.sh then installs the NGF 1.6.2 single-pod chart. The hop evidence stays the same.
See also
- The DX1 lab README — the three steps and the knobs.
- spec 10.2 — the Gateway API contract. spec 10.3 — the reference walkthrough.
- The Build page — the same loop inside the site’s verification story.
- DX1 issue #6 · TR-08c issue #76.
Provenance
Verified against trishula@7c352f65 on main, 2026-10-24.
Smoke run, 2026-10-24, on the OrbStack-provided Kubernetes provider with NGF 1.6.2:
lab/dx1/setup.sh: exit 0. The markerDX1 lab setup completeprinted.lab/dx1/apply-effect.sh: exit 0. The M9 leg read 1174 ms. The fail-closed leg read 8758 ms.lab/dx1/verify.sh: exit 0. The hop evidence printed.
The gate composes the same three legs. No separate gate run is recorded.