You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implements the operator decision on #7 (per-project broker socket + name-based derivation). See #7 for the design rationale and the runnable demo.
Change
proxy/dstack_proxy.py + proxy/main.py:
DstackProxy.__init__ takes a project_id. GetKey no longer trusts a caller-supplied path:
Read a name field from the request body (key name, no slashes).
Construct the path server-side: /tee-daemon/projects/<project_id>/<name>.
Reject any name containing /, .., or a leading . (defense-in-depth; there should be no path to traverse).
If a legacy path is supplied, ignore it (or 400 — see acceptance).
The daemon binds one filtered proxy per project at /var/run/broker/<project>/dstack.sock instead of a single shared dstack.sock.
proxy/deploy.py: mount only the project's own socket dir into that project's container at /run/broker/ (replace the shared BROKER_VOLUME_NAME mount with a per-project mount).
Acceptance
A tenant for project A requesting name=master derives /tee-daemon/projects/A/master; the same request from project B derives /tee-daemon/projects/B/master — different keys, no cross-talk.
A tenant for project A that sends path=/tee-daemon/projects/B/... (old-style) CANNOT derive B's key — the field is ignored (or 400).
name with .. or / is rejected.
Existing single-project deploys still work (project_id defaults sanely).
Add a proxy unit test mirroring the demo's two assertions (own-key works; cross-project denied).
Runnable local demo of this exact mechanism (vulnerable→fixed): see the operator briefing linked from #7. The fixed-mode proxy in the demo is the reference implementation for the name-based construction.
Implements the operator decision on #7 (per-project broker socket + name-based derivation). See #7 for the design rationale and the runnable demo.
Change
proxy/dstack_proxy.py+proxy/main.py:DstackProxy.__init__takes aproject_id. GetKey no longer trusts a caller-suppliedpath:namefield from the request body (key name, no slashes)./tee-daemon/projects/<project_id>/<name>.namecontaining/,.., or a leading.(defense-in-depth; there should be no path to traverse).pathis supplied, ignore it (or 400 — see acceptance)./var/run/broker/<project>/dstack.sockinstead of a single shareddstack.sock.proxy/deploy.py: mount only the project's own socket dir into that project's container at/run/broker/(replace the sharedBROKER_VOLUME_NAMEmount with a per-project mount).Acceptance
name=masterderives/tee-daemon/projects/A/master; the same request from project B derives/tee-daemon/projects/B/master— different keys, no cross-talk.path=/tee-daemon/projects/B/...(old-style) CANNOT derive B's key — the field is ignored (or 400).namewith..or/is rejected.Reference
Runnable local demo of this exact mechanism (vulnerable→fixed): see the operator briefing linked from #7. The fixed-mode proxy in the demo is the reference implementation for the
name-based construction.