Security

What the agent sends, and what it can't do.

The DockTail agent runs next to your containers with the Docker socket mounted. That deserves a plain list, not a badge. Everything below is verifiable in the agent's source.

Summary

Open source

The whole agent, Cloud reporting included, is AGPL.

Outbound only

The agent dials out over WSS. Nothing dials in. No ports.

Metadata only

The protocol has no exec, deploy, or shell message types.

Credentials stay home

Cloud never receives a Tailscale key, token, or OAuth client.

Details

01

The connection

Cloud reporting is opt-in. Without DOCKTAIL_CLOUD_KEY set, the agent opens no connection and runs exactly as it did before Cloud existed. Remove the variable and it is gone again.

With a key, the agent dials wss://ingest.docktail.org and keeps that one WebSocket open. Everything travels over it in both directions. The control plane never connects to your host, so there is no inbound port to open, forward, or firewall.

02

What Cloud cannot do

The wire protocol is metadata-only. There is no message type for executing a command, deploying, opening a shell, or editing a compose file. This is enforced by the shape of the protocol, not by a permission flag that could be flipped.

  • Nothing the agent receives is executed on the host on behalf of Cloud.
  • Cloud cannot aim a probe. Configuration chooses the shape of a check (TCP or HTTP, a path, an expected status); the destination always comes from the agent's own Docker discovery.
  • Cloud cannot read your Tailscale credentials. When it asks whether the Tailscale control plane agrees a service is advertised and approved, the agent reads the Tailscale API locally and answers with metadata. No OAuth client, API key, or Tailscale token is ever sent, and Cloud stores none.
  • Cloud cannot burn your Tailscale API quota. The agent enforces its own minimum interval between control-plane reads and re-serves its previous answer if asked sooner.

03

What is sent

Operational metadata about the host and its containers. The complete list:

  • Snapshots of DockTail-managed services: name, tailnet FQDN, image and tag, ports, compose project, Funnel exposure, and state, including stopped containers.
  • A read-only inventory of the host's other containers: name, image, state and health, ports, CPU and memory. They are listed, not probed, unless you explicitly watch one.
  • Docker failure events: exit codes, OOM kills, health-status changes, restart loops.
  • Local check results, with latency, against the container's own Docker IP.
  • Tailscale control-plane service state, when Cloud asks for it and the host has credentials.
  • Host vitals read from /proc and /sys: CPU, memory, swap, load average, temperature where exposed.
  • The agent's own version, Docker engine ID, Tailscale node ID, and tailnet name.
  • Bounded log tails on incidents. See below.

Not sent: environment variables, volumes or their contents, container images, anything from inside a container beyond the log tail, and nothing at all from containers without docktail.* labels beyond the inventory line above.

Incident log tails

When a service fails, the agent captures the last lines of its container log so the incident carries the reason. This is the one place where application output leaves the host, so it is bounded on three sides.

  • Redacted on the host before sending: Authorization and Bearer headers, passwords, tokens, API keys, credential URLs, JWTs, and private-key blocks. Redaction is best-effort pattern matching; it cannot recognise every application-specific secret.
  • Capped in lines and bytes per incident, and retained for a limited time. The current limits are in the docs.
  • Switchable: on by default, off with one toggle for the whole workspace or for individual services. The setting is enforced by the ingest service, so an agent cannot send what the workspace turned off.

04

Keys and your account

A workspace key (dtc_…) is a rollout credential, not a permanent password.

  • Stored as a SHA-256 hash. The plaintext is shown once, when you create it.
  • Bound to hosts by Docker engine fingerprint. A key accepts new hosts only while its enrollment window is open; after that it keeps authenticating the hosts it enrolled and rejects any new one until you reopen it.
  • Revoking a key denies every host bound to it.
  • Use separate keys for unrelated environments. Never bake one into an image.

The service itself:

  • Sign-in is passwordless: email magic link, Google, or GitHub. There is no password for us to lose.
  • Alert channel configuration (webhook URLs, bot tokens) is encrypted at rest.
  • Payments are handled by Stripe. Card details never touch our servers.
  • The service is hosted in the EU.

05

Found something?

Email [email protected] with what you found and how to reproduce it. You will get a reply from a human, and a fix or an honest timeline. Please do not open a public issue for a vulnerability before we have had a chance to look.

For the agent itself, the source is the reference: github.com/marvinvr/docktail.

Read the code, then decide.

The reporting module is a directory in the agent repository, not a separate binary. If this page and the code disagree, the code is right and we want to know.