Skip to main content

FlashNode

The open host agent of the FlashML system. Install FlashNode on a machine you own, and it can safely execute distributed ML tasks for the FlashML network — earning contribution credits for verified useful work.

FlashNode is one of three components in the FlashML system by Zolli Labs:

  • flashnode (this repo) — open host agent installed by resource contributors. Because it runs on someone else's machine and executes third-party workloads, it must be inspectable, minimal, and explicit about permissions — which is why it is open source.
  • flashruntime — the open workload protocol and execution layer.
  • flashml-cloud (private) — the managed control plane and dashboard.

Read docs/SYSTEM_OVERVIEW.md for the full product architecture, and AGENTS.md if you are an AI coding agent working in this repo.

Status

Pre-release; the device executor works today (July 2026). A machine with this agent can join a FlashRuntime coordinator over outbound HTTP, pull leased tasks, execute them, relay training checkpoints, and commit verified results. Two profiles:

  • Device profile (flashnode work) — the pull-based executor for laptops/workstations. Implemented.
  • Kubernetes profile (flashnode agent) — per-node telemetry reporter inside managed pools (DaemonSet); KubeRay owns workload pods there. Implemented.

What it does today

pip install -e .                      # plus: pip install -e ../flashruntime
flashnode work --coordinator http://<coordinator>:8100
# optional hardening / pool config:
#   FLASHNODE_JOIN_CODE=...          join-code-gated pools
#   --runner docker + FLASHNODE_ALLOWED_IMAGES=img:tag,...   container tier
#   FLASHNODE_WORKDIR=$HOME/.cache/flashnode   (macOS + colima: VM-visible workdirs)
#   FLASHNODE_WORKDIR=C:\Users\<you>\.flashnode  (Windows: must be under a
#                                                 directory Docker Desktop shares)

If the coordinator enforces per-machine authentication (FLASHML_NODE_TOKENS set server-side), save the bearer token you were given before running work:

flashnode login --coordinator http://<coordinator>:8100 --token <token>
flashnode work --coordinator http://<coordinator>:8100   # reads the saved token automatically
flashnode logout --coordinator http://<coordinator>:8100 # forget it locally (does not revoke server-side)

login/logout write to a per-coordinator credential store at ~/.flashnode/credentials.json (override with FLASHNODE_CREDENTIALS), keyed by coordinator URL so one machine can hold separate tokens for separate pools. The file is written with mode 0600 on every save. A missing or unparseable file is treated as "no saved token" rather than a crash. CoordinatorClient sends the saved token as a bearer header on every request to that coordinator once it's saved — there is nothing else to configure. Token issuance is still manual and out-of-band today (the coordinator operator hands you the token; there is no self-service signup or browser device flow yet), and flashnode logout only removes the local copy — the operator revokes access by removing your token from the coordinator's configuration.

  • Stable node identity; registers with capabilities (CPU, RAM, arch, GPU) and re-registers automatically if the coordinator restarts.
  • Outbound-only HTTP — no inbound ports, no router configuration.
  • Claims task leases, renews them with attempt heartbeats, and stops work the moment a lease is refused (the coordinator's idempotent commit rejects late duplicates regardless — defense in depth).
  • Two execution tiers behind one interface: SubprocessRunner (allowlisted Python modules, wall-clock timeout, scrubbed environment — agent secrets never reach task code) and DockerRunner (allowlisted images, --network none, cpu/memory limits, read-only rootfs, uid mapping).
  • Downloads shared input artifacts; uploads outputs with sha256 for the coordinator's commit-time validation.
  • Checkpoint courier: tasks stay network-isolated, so the agent fetches the task's latest valid checkpoint before a run (resume) and ships each new checkpoint file during it — a task killed on this machine resumes from its checkpoint on another.

Still to come: Ed25519-signed identity, admission benchmarks (benchmark/), richer telemetry (telemetry/), gVisor/Kata isolation tiers, and the join/status/leave UX.

Security contract

  • Outbound-only control connection; no inbound SSH or public ports.
  • Signed node identity; short-lived session credentials.
  • Allowlisted or signed workload images only.
  • Non-root execution; no host Docker socket, device passthrough, or privileged mode.
  • The agent shows exactly which limits and permissions apply to a workload before executing it.
  • Complete event logging of task assignment, image digest, permissions, and artifact commits.

Supported host class (initial): x86-64 Linux, macOS (Docker Desktop or Colima), or Windows (Docker Desktop with the WSL2 backend), Python 3.10+, ≥4 CPU cores, ≥8 GB RAM, stable outbound internet.

Windows note: flashnode work used to crash immediately on Windows (os.getuid/os.getgid don't exist there). It now omits --user on Windows instead, relying on the curated images' own non-root USER declaration for non-root execution — see docs/guides/donate-a-machine.md in flashruntime for the full picture, including honest caveats: Windows support is constructed-argv-verified (tests fake the platform), not yet execution-verified against a real Windows machine.

Package layout

Working today:

flashnode/
├── agent/       # CLI (`work`, `agent`), K8s-profile daemon, kube helper
├── identity/    # stable node ID (Ed25519 signing: planned); credentials.py
│                #   is the per-coordinator bearer-token store behind
│                #   `flashnode login`/`logout`
├── inventory/   # capability discovery (psutil + K8s allocatable)
└── executor/    # the device work cycle:
    ├── client.py         # stdlib outbound HTTP: leases, artifacts, checkpoints
    ├── runner.py         # Tier 1: allowlisted subprocess, scrubbed env
    ├── docker_runner.py  # Tier 2: allowlisted containers, network-none
    └── loop.py           # claim → run (heartbeating) → relay ckpts → commit

Scaffolds awaiting their vertical slice: benchmark/ (admission probes), telemetry/ (rich metrics), artifacts/ (local caching), config/ (host-owner policy).

License

Apache-2.0. Contributions via Developer Certificate of Origin (git commit -s).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flashnode-0.2.1.tar.gz (78.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flashnode-0.2.1-py3-none-any.whl (57.4 kB view details)

Uploaded Python 3

File details

Details for the file flashnode-0.2.1.tar.gz.

File metadata

  • Download URL: flashnode-0.2.1.tar.gz
  • Upload date:
  • Size: 78.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for flashnode-0.2.1.tar.gz
Algorithm Hash digest
SHA256 bc549198134fa02e2e243d052eb4b4f863c8dbcea5fc505c758cf3d6e161732e
MD5 d443ad90d81cf593c4edf09ac79fd58e
BLAKE2b-256 8b583e7003c529628f27a45cadf41ee15d1a6df16f2bff9d24997fa03d593f6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for flashnode-0.2.1.tar.gz:

Publisher: release-flashnode.yml on Zolli-Labs/flashml

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flashnode-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: flashnode-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 57.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for flashnode-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ce797777fe8a97ecb4945041d90cbe27a44c0b9214015ce9af9ba40b1e5961d8
MD5 8b2af5ee16b8e8968d246a8b4685152f
BLAKE2b-256 4f2851cdecd7c2dcc831ccf36cb89acda588af7968e0298006cf2cf4f68242cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for flashnode-0.2.1-py3-none-any.whl:

Publisher: release-flashnode.yml on Zolli-Labs/flashml

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page