Removes all "traefik" branding/paths/env/comments from the shipping
surface while keeping load-bearing config schema and external deps intact.
Paths / binary:
- cmd/traefik/ -> cmd/ingress/ (traefik.go->ingress.go, etc.); merged out
the empty cmd/ingress/generate.go stub. Build refs updated in Dockerfile,
Makefile, .goreleaser.yml.tmpl, script/crossbinary-default.sh, README.
- contrib/systemd/traefik.service -> ingress.service (Hanzo Ingress unit,
/etc/ingress paths, hanzo-ingress binary).
- contrib/grafana/traefik*.json -> ingress*.json; metric queries
traefik_* -> ingress_* (now match the engine's ingress_ prefix) + titles.
- script/gcg/traefik-*.toml -> ingress-*.toml; Owner/Repo -> hanzoai/ingress.
Code/config branding (comments + non-schema strings):
- doc.go, mount.go, client/router.go, zap_backend.go, forward_backend.go,
register.go: "Traefik" -> "the ingress"/"Hanzo Ingress"; corrected the
annotation example to ingress.kubernetes.io/.
- ingress.sample.{toml,yml}: header + log + entryPoint example.
- pkg/config/dynamic/fixtures/sample.toml comment.
- pkg/redactor/testdata example+expected: /etc/traefik/traefik.toml ->
/etc/ingress/ingress.toml, TraefikLogsFile -> IngressLogsFile (both files
kept identical so the redactor golden test stays green).
- .golangci.yml importas aliases traefik* -> ingress* and the stale
crd/traefikio path -> crd/hanzoai; unused-var exclude ingressVersion.
- .dockerignore / .gitignore: drop stale /traefik artifacts.
- script/code-gen.sh: PROJECT_MODULE -> github.com/hanzoai/ingress,
v1alpha1 path -> crd/hanzoai, CRD output -> hanzo.ai_*.yaml /
01-ingress-crd.yml.
- script/deploy.sh: drop the upstream traefik-library-image push.
- Removed dead, disabled upstream docs-publish workflow
(.github/workflows/documentation.yaml, pushed to traefik/doc).
- LLM.md: rewrote rebrand notes; documented load-bearing "traefik" that
stays (external imports, hash-bound realm, upstream issue URL, license
attribution) and vendored upstream docs/webui/changelog as out of scope.
Load-bearing "traefik" intentionally KEPT (not branding):
- external Go modules github.com/traefik/{oxy,yaegi,grpc-web};
- digest_auth_test.go htdigest realm "traefik" (invalidates the hashes);
- consul_test.go upstream issue URL #8092 (provenance citation);
- LICENSE.md + boilerplate.go.tmpl Containous/Traefik Labs copyright
(MIT attribution; Hanzo AI appended);
- integration/ test fixtures (traefik/whoami images, rawdata-*.json
golden entrypoint names, nomad traefik.* tags) — test-only, semantics-
sensitive; out of scope for this pass.
Verify: `go build $(go list ./... | grep -v /webui)` passes; redactor /
config/dynamic / nomad / server/service tests pass. The webui go:embed
failure and the kubernetes/crd test (ingress.k8s.io group mismatch) are
pre-existing on main, not caused by this rebrand.
4.9 KiB
Hanzo Ingress
Overview
Go module: github.com/hanzoai/ingress/v3
Tech Stack
- Language: Go
Build & Run
go build ./...
go test ./...
Structure
ingress/
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Dockerfile
Dockerfile.bin
LICENSE.md
LLM.md
Makefile
README.md
SECURITY.md
cmd/
contrib/
docs/
generate.go
go.mod
Key Files
README.md-- Project documentationgo.mod-- Go module definitionMakefile-- Build automationDockerfile-- Container build
Rebrand Notes
The engine is fully de-traefik'd: the parser dependency was forked to
github.com/hanzoai/ingress-parser (DefaultRootName = "ingress",
DefaultNamePrefix = "INGRESS_"), the config base paths are
/etc/ingress/ingress, the Prometheus metric prefix is ingress_, and
the CRD apiGroup is hanzo.ai. The standalone binary is built from
cmd/ingress (was cmd/traefik) and ships as hanzo-ingress.
Load-bearing "traefik" that intentionally STAYS
These are the only remaining traefik strings outside the vendored
upstream docs/changelog. They are NOT branding and must not be renamed:
- External Go imports —
github.com/traefik/yaegi,github.com/traefik/grpc-web,github.com/traefik/oxyare real third-party modules (ingo.mod/go.sumand the import lines that use them). Renaming breaks the build. - Hash-bound test data —
pkg/middlewares/auth/digest_auth_test.gohtdigest hashes aremd5(user:realm:password)with realm"traefik". Changing the realm invalidates the precomputed hashes (~10 refs). - Upstream issue citation —
integration/consul_test.golinkshttps://github.com/traefik/traefik/issues/8092as the provenance of a regression test. The issue only exists at that URL.
Vendored upstream content (out of scope by nature)
docs/content/**, CHANGELOG.md, webui/** (the dashboard SPA), and
the traefik.io_*.yaml CRD reference dumps under docs/ are imported
upstream Traefik material kept for reference. They carry the bulk of the
remaining traefik occurrences and do not ship in the runtime binary or
image. Rebrand them only as part of a dedicated docs pass.
Wire protocol changes (intentional)
X-Traefik-Fast-Proxyheader renamed toX-Ingress-Fast-ProxyX-Traefik-Routerheader renamed toX-Ingress-Router- Prometheus/InfluxDB metric prefix:
traefik.*renamed toingress.*(the bundled Grafana dashboards incontrib/grafana/ingress*.jsonquery theingress_*metric names accordingly)
Pre-existing build/test issues (not caused by rebrand)
webui/embed.go//go:embed staticfails until the dashboard assets are built (make generate-webui);go build ./...therefore needs the webui built first, or build the subsetgo build $(go list ./... | grep -v /webui).pkg/muxer/http/Test_addRoute/Host_IPv6: Go 1.26 broke IPv6 URL parsingpkg/middlewares/ratelimiter: Timing-sensitive tests, flaky
Header Passthrough Behavior (2026-04-13)
The ingress controller correctly passes through ALL backend response headers.
Both the httputil.ReverseProxy path and the fast proxy path copy response
headers verbatim via VisitAll / Header().Add().
The security-headers Middleware CRD (k8s/hanzo/middlewares.yaml) uses
unrolled/secure to ADD secure headers (HSTS, X-Frame-Options, etc.) via
ModifyResponseHeaders. It uses res.Header.Set(), which overwrites same-named
backend headers. This is intentional -- ingress-level security headers override
backend headers.
The contenttype.DisableAutoDetection wrapper on the entrypoint sets
Content-Type to nil in the header map before handler execution. This prevents
Go's default content-type sniffing but does not strip any other headers.
No code in the ingress adds Content-Disposition. If you see
Content-Disposition: inline; filename="index.html" in responses, it comes from
the backend (Go's http.ServeContent or http.ServeFile).
Annotation prefix
The K8s Ingress provider uses annotation prefix ingress.kubernetes.io/, NOT
traefik.ingress.kubernetes.io/. Annotations with the old Traefik prefix are
silently ignored.
ZAP-HTTP Backend Transport
pkg/server/service/zap_backend.go wraps every backend RoundTripper
returned by TransportManager.createRoundTripper. When the request's
upstream host:port (i.e. req.URL.Host at transport time) matches the
allowlist from env INGRESS_ZAP_BACKENDS (comma-separated), the request
is dialed via github.com/zap-proto/http instead of net/http. All
other backends fall through unchanged. Empty / unset env keeps the
wrapped transport untouched (no allocation, no overhead).
zaphttp.NewTransport pins to one peer (it ignores req.URL.Host
internally), so we keep one *zaphttp.Transport per backend address in
a sync.Map.
External (client-facing) TLS termination is untouched. CRD schema is
untouched. Reference doc:
docs/content/reference/dynamic-configuration/zap-backend.md.