Skip to content

Mount the dstack broker socket into attested app containers (apps can't reach the filtered broker) #3

Description

@amiller

Symptom

The daemon builds a pre-filtered dstack broker socket intended for app use, but never mounts it into any app container. Net result: an attested app (e.g. ghcr.io/tinycloudlabs/tinycloud-node) cannot reach dstack at all — it can't derive its KMS-rooted key (GetKey under /tee-daemon/...) or obtain a GetQuote, even though the broker was built for exactly that.

Root cause

The broker exists and is already locked down for app use, but it's wired to nothing:

  • proxy/main.py:73-84 — the dstack proxy is served as a unix socket at PROXY_DIR/dstack.sock (PROXY_DIR defaults to /var/run/proxy), chmod 0666.
  • proxy/dstack_proxy.py — it's pre-filtered for app use: ALLOWED_METHODS = {GetTlsKey, GetQuote, Info, EmitEvent, GetKey}, and GetKey is restricted to paths under KEY_PATH_PREFIX = "/tee-daemon/".
  • proxy/runtimes.py::start_image() (~480-510) — image-runtime containers bind only their named project.volumes; there is no mount of the broker socket, in either dev or attested mode. The shared (deno/bun) and isolated runtime paths (start_shared ~318-369, start_isolated ~415-458) don't mount it either.

So the broker is a latent, app-intended, already-filtered component mounted into zero app containers.

Proposed fix

Mount the existing broker socket into attested app containers at a conventional path (e.g. /var/run/dstack.sock), so apps reach filtered dstack exactly as they would the real socket.

This adds no new capability or audit surface — it only exposes the already-built, already-filtered broker. It does not inject keys or hand apps anything the broker doesn't already gate (GetKey is still pinned to /tee-daemon/..., non-allowlisted methods still 403).

Consider applying to the deno/bun (shared) runtimes too for parity.

Motivating use case: running tinycloud-node as an attested app that uses the daemon as its key manager — derive-in-CVM, never exposed externally.

Relation to #2

Possibly the same surface area as the deno/bun runtime in #2, but a distinct root cause. #2 is outbound DNS dying under gVisor (127.0.0.11 embedded resolver is dead in the runsc sandbox); this is a missing bind mount of the dstack broker socket — independent of network/DNS and present even under runc. They could be fixed together if the deno parity ask in #2 is really "let deno apps reach dstack."

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions