Securing the Traefik Dashboard with an Internal Entrypoint and BasicAuth
Bind the Traefik dashboard to a private entrypoint, gate it with BasicAuth middleware, and verify access with curl. Includes recovery steps for lost credentials.
06 Jun 2026, 06:59 UTC

Desired outcome
The Traefik dashboard and REST API expose routing tables, provider state, and runtime metrics. If they are reachable from an untrusted network, an attacker can map your infrastructure or probe for misconfigurations. The practical fix is to bind the dashboard to an internal-only entrypoint and require authentication before any request reaches the api@internal service.
This guide shows how to configure that boundary with a dedicated entrypoint and a BasicAuth middleware, then how to verify the gate works and recover if access is lost.
Prerequisites
- Traefik v2 or v3. Older v1 patterns such as the
api.insecureflag are not valid. - Access to the static configuration file or CLI arguments used to start Traefik.
- A private network interface, localhost binding, or firewall rule for the internal entrypoint.
- The
htpasswdutility (often inapache2-utils) to generate credential hashes. - The file provider enabled for dynamic configuration, or an equivalent label/CRD workflow.
Procedure
1. Define the internal entrypoint and enable the API
In static configuration, create an entrypoint that listens on a private address. Binding to 127.0.0.1:8080 restricts access to the host itself; binding to a private subnet address such as 10.0.0.5:8080 allows internal clients only. Enable the dashboard and API with the api block.
entryPoints:
internal:
address: "127.0.0.1:8080"
api:
dashboard: true
providers:
file:
filename: "/etc/traefik/dynamic.yml"
If you use Docker or Kubernetes labels instead of the file provider, the router and middleware definitions move to labels or CRDs, but the entrypoint and api block remain in static configuration.
2. Create the dashboard router and BasicAuth middleware
In dynamic configuration, define a router that uses only the internal entrypoint, points to api@internal, and applies a BasicAuth middleware. The rule can match an internal hostname or the /api and /dashboard paths.
http:
routers:
dashboard:
rule: "Host(`traefik.internal.example`) || (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
service: api@internal
entryPoints:
- internal
middlewares:
- dashboard-auth
middlewares:
dashboard-auth:
basicAuth:
users:
- "admin:$2y$05$abcdefghijklmnopqrstuv..." # replace with actual bcrypt hash
Replace traefik.internal.example with your internal hostname and the users array with your htpasswd output.
3. Generate credentials
Run htpasswd on an administrative host or your local workstation:
htpasswd -nbB admin 'your-strong-password'
This prints a line in htpasswd format. Copy the entire string, including the bcrypt prefix, into the users list. Avoid leaving the plaintext password in shell history by quoting it or using an interactive prompt; some htpasswd builds support -i for stdin.
4. Reload and verify
If you use the file provider, saving the dynamic file triggers a hot reload; no process restart is required. If you changed static configuration, restart the Traefik service or process.
Expected checks
Run these from a machine that can reach the internal address. Replace <INTERNAL_ADDRESS> with the actual bind address and <USER>/<PASSWORD> with your credentials.
Unauthenticated request should fail:
curl -I http://<INTERNAL_ADDRESS>/dashboard/
Expect a 401 Unauthorized response. If you receive 200, the middleware is not attached or the entrypoint is not restricted as intended.
Authenticated request should succeed:
curl -I -u <USER>:<PASSWORD> http://<INTERNAL_ADDRESS>/dashboard/
Expect a 200 OK response and HTML content. For the API:
curl -u <USER>:<PASSWORD> http://<INTERNAL_ADDRESS>/api/rawdata
The JSON output should list the dashboard router and confirm it references the dashboard-auth middleware and the api@internal service.
Check Traefik logs at debug level when reloading. Look for messages indicating the middleware was initialized and the router was attached. Exact log strings vary by version, so search for your middleware and router names rather than fixed error codes.
Recovery options
Lost credentials. Because the dashboard router is dynamic, you can restore access without restarting Traefik. Edit the users list in the dynamic configuration file, save it, and the file provider reloads the middleware. If the file provider itself is unavailable, keep an emergency static configuration or CLI fallback that points to a known-good dynamic file.
Wrong network binding. If you accidentally bound the internal entrypoint to a public interface, revert the address in static configuration and restart Traefik. Then verify with curl from an external network that the port is no longer reachable.
Broken dynamic file. If a syntax error prevents reload, Traefik typically keeps the last valid configuration. Fix the YAML or TOML error and save again. Keep a backup of the working dynamic file so you can copy it back quickly.
Limitations and hardening
BasicAuth transmits credentials base64-encoded in the Authorization header. On a private network this may be acceptable, but if the dashboard is reachable across any untrusted segment, terminate TLS in front of the entrypoint or restrict access further with an IP allowlist middleware. The api@internal service also exposes provider and runtime data; treat it as sensitive even when password-protected. Environment-variable expansion and secret references differ across providers, so avoid hardcoding production credentials in version-controlled files. Confirm the exact schema for your Traefik minor version, because label keys and CRD fields change between releases.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.