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.

  1. Clone the product repository:
git clone https://github.com/trishula-dev/trishula && cd trishula
  1. 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
  1. 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.

  1. 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.sh

setup.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

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 marker DX1 lab setup complete printed.
  • 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.