Security
D2HA can update containers, so treat it like an admin panel. The example setup is private by default; these are the parts that keep it so.
Who can reach it
- The example publishes D2HA on
127.0.0.1: Home Assistant on the same host, a reverse proxy or a tunnel can reach it, the rest of the network cannot. - From outside, put it behind HTTPS and an access layer: a VPN, Cloudflare Access, an authenticating reverse proxy.
- Turn on two-factor authentication in Settings → Account and security.
D2HA reads the visitor address from the CF-Connecting-IP header when there is one, for the sign-in limits. Keep port 12021 reachable only from the machine itself or your proxy, so nobody can send that header directly.
The socket proxy
With the example, D2HA reaches Docker through linuxserver/socket-proxy on an internal network with no way out, and the proxy mounts the socket read-only. It allows only what D2HA needs:
| Setting | Value | Why |
|---|---|---|
CONTAINERS | 1 | List and inspect containers |
IMAGES | 1 | Read image labels and digests, clean images |
DISTRIBUTION | 1 | Ask the registry through Docker, for private registries |
VERSION | 1 | The Docker version and architecture |
EVENTS | 1 | Crash and unhealthy alerts |
ALLOW_LOGS | 1 | Container logs on the D2HA page. Without it the logs do not open. Home Assistant never gets them |
POST | 1 | Every write: download images, create and remove containers. 0 in read-only mode |
ALLOW_START, ALLOW_STOP | 1 | Start and stop containers during an update |
ALLOW_RESTARTS | 0 | Not needed |
EXEC, VOLUMES, NETWORKS | 0 | Never: no commands inside containers, no volumes or networks |
D2HA recognises the proxy from DOCKER_HOST and never updates it: update it yourself with docker compose pull.
Read-only mode
With updates enabled the proxy must allow creating containers, so a stolen session could still create one. If you only want notifications and logs, set both:
D2HA_READ_ONLY: "true" # on d2ha
POST: 0 # on docker-proxy
Then D2HA shows no update or cleanup buttons, the API refuses them with read_only, and Home Assistant has no Install, Update all or Clean images.
Sign-in and sessions
| Protection | How |
|---|---|
| Passwords | At least 10 characters; passwords that are too easy to guess are refused; stored as a hash |
| Two-factor authentication | TOTP codes from an authenticator app |
| Too many attempts | 5 wrong attempts from one address in 15 minutes, or 30 from anywhere, block sign-in for a while |
| Sessions | End after inactivity (30 minutes by default); the cookie is HttpOnly and SameSite=Lax, and Secure over HTTPS |
| Password or two-factor change | Signs out every other device |
| Actions | Checks, updates and cleanup: at most 30 per minute per address. Every change from the web interface needs a CSRF token |
The API token
The token for Home Assistant is shown once and stored only as a hash. It can read containers and start checks, updates and cleanup, but it cannot read logs. Replace it with New token or turn it off with Revoke at any time.
In the browser
- No requests to other sites: no CDN, fonts or trackers. A strict Content Security Policy enforces it.
- Environment variables, commands and secrets of your containers are never shown.
- Release notes from GitHub are shown with a safe subset of Markdown: any HTML in them is removed.
Reporting a problem
Found a security problem? Please open a private security advisory instead of a public issue.
Something wrong or missing on this page? Open an issue.