dml-dashboard binds to loopback by default. Keep that default when possible: the dashboard can expose source, repository metadata, logs, remote resource identifiers, and execution controls to the browser.
A non-loopback binding requires --allow-remote and uses an ephemeral bearer token printed at startup. Treat that token like a password, do not put the token-bearing URL in shared logs, and use a trusted network or an authenticated reverse proxy. The token protects the dashboard application; it does not repair the known trust limitations of persisted DaggerML objects or executor inputs.
Dashboard responses redact credential-like fields, environment values, authorization data, and presigned URL query parameters. SSH environment-file contents are never displayed. Script reads are constrained to resources derived from persisted execution state; log reads use only canonical CloudWatch streams derived from trusted persisted cache keys and never read executor-local files. Rendered scripts and CloudWatch logs can still contain secrets written by user code.
Home exposes project paths already stored in the dashboard’s registered-project configuration. It shows shortened path context and discloses the full registered path on pointer hover, keyboard focus, and through assistive technology. Aggregate requests cannot supply or resolve arbitrary paths. A project read failure is reduced to a bounded, project-scoped diagnostic without exception text, tracebacks, credentials, or additional internal paths.
Project routes carry a registered project ID and concrete commit ID, not a filesystem path. Invalid, unknown, unavailable, or out-of-revision requests must retain that requested scope while rendering only their safe dashboard error; they must not fall back to HEAD or disclose other repository paths or resources.
The adapter field is persisted in each runnable. When the runnable executes, the runtime passes that field to shutil.which() and then launches the returned path with subprocess.run(). It does not check that the field names a registered adapter executable. An absolute path is accepted as well as a name resolved through PATH.
For example, on a shared execution host, suppose an attacker can place this executable at /tmp/dml-adapter:
#!/bin/sh
touch /tmp/dml-adapter-ran
printf '%s\n' '{"status":"failed","error":"attacker adapter ran"}'They can provide a runnable whose adapter is /tmp/dml-adapter. When that runnable is executed, DaggerML launches /tmp/dml-adapter; the marker file demonstrates that the executable ran. The adapter request is JSON on standard input, so this is arbitrary executable selection, not shell interpolation of request content.
S3Store.untar() rejects member names that are absolute or contain path traversal, but it accepts symlink and hardlink members. An archive can first create a symlink named link to /tmp/outside, then contain a regular file named link/payload. Both member names pass validation because they are under the destination. During extraction, the second member is written through the symlink to /tmp/outside/payload.
Do not create tarballs with symlink or hardlink members for use with S3Store.untar().
DaggerML uses hash-derived names for stored artifacts and other managed objects, but it does not recompute and compare those hashes when it reads them. Overwriting a known object or ref can therefore replace the data DaggerML uses without a hash mismatch being detected. This includes script source: overwritten script bytes can later be executed by a script worker.
Never manually overwrite DaggerML-managed objects or refs. Humans and automated agents must use DaggerML tooling to write and update them.
When materializing a remote CAS object graph, DaggerML decodes each downloaded object and follows its references before verifying that the object’s content produces the requested local object ref. The later local materialization rejects an identity mismatch, so the corrupt object is not persisted, but it may already have caused additional remote object requests. A remote store that can serve arbitrary bytes under known CAS keys can therefore cause unnecessary dependency traversal and remote-read work before rejection.
Treat a configured remote object store as trusted for availability and object integrity. Limit its credentials and request budget accordingly.
The SSH executor passes every supplied flags entry directly to the local ssh command. OpenSSH options such as ProxyCommand run a local command before the SSH connection is made.
For example, an SSH runnable with flags=["-oProxyCommand=touch /tmp/dml-proxy-command"] causes the local SSH client to run touch /tmp/dml-proxy-command. The command is run on the host executing DaggerML, not the remote SSH host.
Use only SSH flags you control. Do not pass untrusted values as SSH flags.