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.
Keep the port closed

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:

SettingValueWhy
CONTAINERS1List and inspect containers
IMAGES1Read image labels and digests, clean images
DISTRIBUTION1Ask the registry through Docker, for private registries
VERSION1The Docker version and architecture
EVENTS1Crash and unhealthy alerts
ALLOW_LOGS1Container logs on the D2HA page. Without it the logs do not open. Home Assistant never gets them
POST1Every write: download images, create and remove containers. 0 in read-only mode
ALLOW_START, ALLOW_STOP1Start and stop containers during an update
ALLOW_RESTARTS0Not needed
EXEC, VOLUMES, NETWORKS0Never: 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

ProtectionHow
PasswordsAt least 10 characters; passwords that are too easy to guess are refused; stored as a hash
Two-factor authenticationTOTP codes from an authenticator app
Too many attempts5 wrong attempts from one address in 15 minutes, or 30 from anywhere, block sign-in for a while
SessionsEnd after inactivity (30 minutes by default); the cookie is HttpOnly and SameSite=Lax, and Secure over HTTPS
Password or two-factor changeSigns out every other device
ActionsChecks, 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.