mirror of
https://github.com/hanzoai/gateway.git
synced 2026-10-30 15:04:44 +00:00
The trust boundary's strip did not survive its own bridge. gateway.Mount — the HIP-0106 boundary the unified cloud binary runs, and the one piece of code whose entire job is to delete client-supplied identity — reached the gin middleware through zip.AdaptNetHTTPMiddleware. fiber's adaptor copies the middleware's headers back onto the fasthttp request with Set and never Del, so every header the strip DELETED was restored from the original request. A client-supplied X-User-IsAdmin: true reached the downstream subsystem intact. Reproduced against the old bridge before deleting it; TestZipAuth_StripSurvives is the guard. The cause was braiding: the ALLOW/DENY ladder was written out inside a gin closure, so the zip edge could not call it and bridged to it instead. The ladder is now a value — authGate.admit in authpolicy.go, which knows about no framework — and each transport is a dozen lines over it: gin for the legacy Lura edge, native zip for the mount. TestBothTransportsAdmitAlike drives one request through both and asserts they agree, across refuse / tokenless / public path / public host / ingest / API key / valid token. Every gate is unchanged; the 90KB security suite passes untouched, which is the proof. The probes are TYPED ops. Five anonymous closures across three apps each wrote their own map literal, so one answer had five spellings and none was in any document — an untyped route appends nothing to the op registry, so no OpenAPI operation, no MCP tool, no CLI, no SDK method. One declaration in probes.go now serves all three mount points, and zipdoc_gen.go carries the prose. Route table: BuildApp 2/2 typed, health app 3 routes/2 typed (/metrics is the one hatch — Prometheus exposition is text, and the reason is written next to it), Mount 1 route/0 typed → 2/2. Counts are asserted, not described: TestBuildApp_IsProbesAndNothingElse, TestMount_ProbesAreTypedOps and TestHealthApp_TableIsInTheBinary, which boots the app main boots rather than mounting the table directly. internal/lura and internal/plugin are untouched: they are vendored KrakenD/Lura, they are what the shipping `legacy` image runs, and rewriting a fork's router buys permanent merge pain. They go at Phase C with the rest of the legacy set. What left is the gin RUNTIME on the default build — no first-party path constructs a gin engine any more; the three files that still import it export transports consumed solely by legacy_engine.go. Co-authored-by: Hanzo Dev <[email protected]>
39 lines
4.0 KiB
Go
39 lines
4.0 KiB
Go
// Code generated by zipdoc; DO NOT EDIT.
|
|
|
|
package gateway
|
|
|
|
import (
|
|
"github.com/zap-proto/zip"
|
|
)
|
|
|
|
func init() {
|
|
zip.Describe("GET /_/gateway/healthz", zip.Doc{
|
|
Description: "Reports that the gateway process is running and answering HTTP.\n\nIt deliberately consults NOTHING — not the ZAP node, not a backend peer, not\nthe JWKS cache. A liveness probe that fails when a dependency blinks gets a\nhealthy process restarted and turns one outage into two. The relay degrades\nper-request when a backend is absent (see the lazy picker); it does not stop\nbeing alive.",
|
|
Fields: map[string]string{
|
|
"ProbeOut.service": "Service names the service that answered — always \"gateway\", including on\nthe separate k8s health listener, because the listener is a deployment\ndetail and the service is what the operator asked about.",
|
|
"ProbeOut.status": "Status is \"ok\" from the liveness probe and \"ready\" from the readiness\nprobe. It is the field a scraper reads when it reads the body at all;\norchestrators read the status code.",
|
|
},
|
|
})
|
|
zip.Describe("GET /_/gateway/readyz", zip.Doc{
|
|
Description: "Reports that the gateway is ready to carry traffic.\n\nSame answer as liveness by construction: the gateway holds no per-tenant\nstate, warms no cache it needs before the first request, and dials its\nbackends lazily on first use — so there is no interval during which the\nprocess is up and not yet ready. Readiness is a SEPARATE door rather than an\nalias because the deployment asks the two questions separately, and the day\nthis service acquires something to warm, the widening happens here and\nnowhere else.",
|
|
Fields: map[string]string{
|
|
"ProbeOut.service": "Service names the service that answered — always \"gateway\", including on\nthe separate k8s health listener, because the listener is a deployment\ndetail and the service is what the operator asked about.",
|
|
"ProbeOut.status": "Status is \"ok\" from the liveness probe and \"ready\" from the readiness\nprobe. It is the field a scraper reads when it reads the body at all;\norchestrators read the status code.",
|
|
},
|
|
})
|
|
zip.Describe("GET /healthz", zip.Doc{
|
|
Description: "Reports that the gateway process is running and answering HTTP.\n\nIt deliberately consults NOTHING — not the ZAP node, not a backend peer, not\nthe JWKS cache. A liveness probe that fails when a dependency blinks gets a\nhealthy process restarted and turns one outage into two. The relay degrades\nper-request when a backend is absent (see the lazy picker); it does not stop\nbeing alive.",
|
|
Fields: map[string]string{
|
|
"ProbeOut.service": "Service names the service that answered — always \"gateway\", including on\nthe separate k8s health listener, because the listener is a deployment\ndetail and the service is what the operator asked about.",
|
|
"ProbeOut.status": "Status is \"ok\" from the liveness probe and \"ready\" from the readiness\nprobe. It is the field a scraper reads when it reads the body at all;\norchestrators read the status code.",
|
|
},
|
|
})
|
|
zip.Describe("GET /readyz", zip.Doc{
|
|
Description: "Reports that the gateway is ready to carry traffic.\n\nSame answer as liveness by construction: the gateway holds no per-tenant\nstate, warms no cache it needs before the first request, and dials its\nbackends lazily on first use — so there is no interval during which the\nprocess is up and not yet ready. Readiness is a SEPARATE door rather than an\nalias because the deployment asks the two questions separately, and the day\nthis service acquires something to warm, the widening happens here and\nnowhere else.",
|
|
Fields: map[string]string{
|
|
"ProbeOut.service": "Service names the service that answered — always \"gateway\", including on\nthe separate k8s health listener, because the listener is a deployment\ndetail and the service is what the operator asked about.",
|
|
"ProbeOut.status": "Status is \"ok\" from the liveness probe and \"ready\" from the readiness\nprobe. It is the field a scraper reads when it reads the body at all;\norchestrators read the status code.",
|
|
},
|
|
})
|
|
}
|