Hardened Image (Distro Zero)
This feature is currently in early access.
Traefik Labs' Distro Zero image (or hardened image) is a vendor-supported secure runtime delivered as Traefik Hub in license-free Proxy Mode. It gives platform and security teams a container whose entire executable content is a single memory-safe binary, with validated cryptography built inside it. With a license, you can unlock every advanced capability in that same binary, from API gateway and API management to AI and MCP gateway.
Unlike the
standard Alpine-based image, it is built FROM scratch, adding only what the
statically-linked binary needs to run.
Why use the hardened image
- Smaller attack surface: no shell, no package manager, and no shared libraries beyond what the static binary needs, so there's nothing extra on disk for an attacker to abuse if the container is compromised.
- No interactive shell: even with a container escape or RCE, there's no
sh/bashto drop into. - Nonroot by default: runs as uid/gid 65532 out of the box, satisfying Kubernetes restricted Pod Security Standards and OpenShift restricted SCC without extra configuration.
- Pairs with FIPS: available as a combined
-fips-hardenedvariant, so teams needing both a minimal attack surface and FIPS compliance get one image, not a tradeoff between the two. - Works with Proxy Mode: run the hardened image without a license using Proxy Mode, then add a token later without redeploying.
The hardened image is a paid feature and must be enabled on your workspace. Contact sales to request access.
Runtime differences from the standard image
-
Runs as a nonroot user (uid/gid 65532) by default, unlike the standard image.
-
Listens on 8000/8443 rather than 80/443.
-
Because a nonroot process can't bind ports below 1024, deployments that expose Hub directly on 80/443 (Docker, Compose, Swarm, Nomad without a fronting load balancer) need either:
- entrypoints configured on a port ≥1024, as already shown in the Nomad installation guide, or
cap_add: [NET_BIND_SERVICE](Docker/Nomad), orrunAsUser: 0to opt back into root.
Kubernetes
Serviceport remapping (for exampleport: 443→targetPort: 8443) absorbs this automatically, so it mainly affects non-Kubernetes platforms.
Available variants
| Tag suffix | Base | FIPS |
|---|---|---|
-hardened | scratch | No |
-fips-hardened | scratch | Yes |
Both are published to a private container registry, separate from the public registry used by the standard and FIPS images.
Generating registry credentials
Workspace owners and admins can generate registry credentials from Workspace Settings > Registry credentials (only visible if your workspace has the hardened image feature):
- Click Create. The password is shown once: copy it immediately, since it cannot be retrieved again.
- Use the generated username/password with
docker loginagainst the registry host provided in your workspace settings. - Revoke a credential by typing its username to confirm.
Enabling the hardened image when creating a gateway
Once you have registry credentials, the simplest way to deploy the hardened image is to enable it directly in the gateway creation flow, rather than editing the install command by hand.
- Go to Gateways and create a gateway.
- Select a container platform. The Hardened image toggle is only displayed for Kubernetes, Docker Compose, Swarm, and Nomad: it isn't available for the Linux binary install as there is no container image involved.
- Turn on the Hardened image option. If you haven't generated registry credentials yet, an inline reminder links back to workspace settings.
- The generated install snippet updates automatically to use the hardened
image, so you can copy it as-is:
- Kubernetes: adds
--set hub.hardened=trueto the Helm command. - Docker, Swarm, Nomad: points the image reference at the private
registry with the
-hardenedtag suffix.
- Kubernetes: adds
The manual per-platform steps in the next section are useful if you're deploying outside this quick-config flow, for example scripting an install or adding the hardened image to an existing gateway's config directly.
Deploying the hardened image
The hardened image ships the same Traefik Hub binary as the standard image. Follow your platform's installation guide, then apply the changes below.
- Kubernetes
- Docker
- Nomad
In addition to the Kubernetes installation steps, create an image pull secret from your registry credentials and reference it in the Helm install:
kubectl create secret docker-registry hub-hardened-registry --namespace traefik \
--docker-server=<registry-host> \
--docker-username=<registry-username> \
--docker-password=<registry-password>
helm install traefik -n traefik --wait \
--set hub.token=license \
--set hub.hardened=true \
--set image.pullSecrets[0].name=hub-hardened-registry \
traefik/traefik
The hardened image also works with Proxy Mode. Replace --set hub.token=license
with --set hub.enabled=true, and set --set image.tag=v3.21.0-ea.1 or newer since Proxy
Mode requires Traefik Hub >= v3.21.0-ea. The registry pull secret and
hub.hardened=true flag stay the same.
Following the Docker installation guide, log in to the registry and swap the image:
docker login <registry-host> -u <registry-username> -p <registry-password>
services:
hub:
image: <registry-host>/traefik-hub/traefik-hub:v3-hardened
command:
- --providers.docker
- --hub.token=YOUR-TRAEFIK-HUB-TOKEN
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Omit the --hub.token=YOUR-TRAEFIK-HUB-TOKEN line to run the hardened image in
Proxy Mode, same as the standard image.
This applies to Docker Swarm deployments as well.
Following the Nomad installation guide, add registry auth and swap the image in the task config:
config {
image = "<registry-host>/traefik-hub/traefik-hub:v3-hardened"
auth {
username = "<registry-username>"
password = "<registry-password>"
}
}
The hardened image supports Proxy Mode the same way the standard image does. See the Nomad installation guide for the token vs. no-token job configuration; the image and registry auth above apply either way.
Combining with FIPS
A hardened FIPS image is available with the -fips-hardened tag suffix,
requiring both the hardened image and FIPS workspace features.
Contact sales to request access to the
hardened image and FIPS features.
Debugging without a shell
The hardened image has no shell or package manager, so kubectl exec /
docker exec won't work. Before reaching for exec-based debugging, check
whether the existing observability surface already answers the question.
Hub's metrics, tracing, and (with --api.debug=true) pprof endpoints cover
most troubleshooting without needing a shell at all.
When you do need to inspect the running container:
Kubernetes: ephemeral debug container
kubectl debug -it <pod-name> --image=busybox --target=traefik-hub -- sh
Attaches a toolbox container into the pod, sharing its network namespace, with
no changes to the running container. Once inside, the target container's
filesystem is available at /proc/1/root/.
Docker: namespace-sharing sidecar
docker run --rm -it --pid=container:<name> \
--mount=type=image,source=busybox:musl,destination=/dbg,ro \
--entrypoint /dbg/bin/sh \
<registry-host>/traefik-hub/traefik-hub:v3-hardened \
-c 'export PATH=/dbg/bin:$PATH; exec /dbg/bin/sh'
Runs a new instance of the hardened image itself, sharing the running
container's process namespace, with BusyBox's tools mounted read-only at
/dbg and the entrypoint overridden to /dbg/bin/sh since the hardened image
has no shell of its own.
Docker Desktop / Docker Business
docker debug <container>
Does the sidecar trick automatically if you have Docker Desktop.
