Security
The gpu-train security model — loopback bind, bearer-token auth, dashboard obfuscation, the local credential store, and cost safety.
gpu-train is a single-user, local control plane. It assumes it runs on a machine you
trust and talks outbound to providers, W&B, and artifact sinks.
Network exposure
- The dashboard/API server (
gpu-train serve) binds to127.0.0.1by default. - It rejects any request whose
Hostheader isn't loopback (anti-DNS-rebinding). - CORS is restricted to loopback origins; WebSocket upgrades validate
HostandOrigin.
Because the server can submit and cancel jobs, an unauthenticated, internet-exposed instance
would be a remote-code-execution and cost risk. The loopback defaults plus a bearer token
prevent this. For remote access, put it behind an authenticating reverse proxy or an SSH tunnel
and set GPU_TRAIN_ALLOWED_HOSTS to the proxy host.
Bearer-token auth (default on)
gpu-train serve generates a token, persists it to ~/.gpu-train/server_token (chmod 600),
prints it, and opens the browser at /#token=…. The dashboard stores it and sends
Authorization: Bearer <token> on every API call; the checkpoint download link and the log
WebSocket accept a ?token= query param (headers aren't possible there). The static shell,
/health, and /api stay open so the login gate can load. Token comparison is constant-time.
gpu-train serve # generate + print a token, require it
gpu-train serve --token my-secret # bring your own (or GPU_TRAIN_SERVER_TOKEN=…)
gpu-train serve --no-auth # open, loopback-only (old behavior)Dashboard obfuscation
Release builds run javascript-obfuscator over the dashboard's Next.js app/shared chunks
(conservative settings: hex identifiers, base64 string-array, string splitting; runtime chunks
skipped so React keeps working). CI asserts there are no source maps, no cleartext control-plane
identifiers, and a minimum count of obfuscated identifiers, plus a serve smoke test. The Python
SDK ships as readable source — only the shipped UI bundle is obfuscated.
Secrets
- Credentials are referenced via
secret_refURIs (env://,file://,store://) and resolved at runtime. The package never logs secret values. - Keys entered in the dashboard are written to
~/.gpu-train/credentials.json(chmod 600), returned masked (last 4 chars), and read back only by the control plane viastore://. This includes S3 (secret_access_key) and GCS (service_account_json) sink credentials. - Secrets injected into remote training (e.g.
WANDB_API_KEY,HF_TOKEN) are written to owner-only files on the rented box, and known values are redacted from stored/streamed logs. - Environment variables win: a credential configured via
env://is read-only in the UI.
See Credentials & secrets for the resolvers and store schema.
Cost safety
- Instances are terminated on job completion/failure, idle timeout,
kill_all(), control-plane exit (atexit), and server shutdown. - On startup the control plane reconciles and terminates instances orphaned by a prior crash.
See Cost safety for the guardrails, and the repository's
SECURITY.md for the canonical model.