Ops & agents

Releases and self-update

Every release is signed, verified and installed without touching a running VM.

flash self-update is FlashVMM's built-in update channel: it fetches one Ed25519-signed release manifest, verifies the signature against a key compiled into the binary before reading any field, checks every artifact against the SHA-256 and size inside that manifest, and installs with an atomic rename(): Linux binaries and guest bundles file by file, a signed .pkg on macOS and an .msi on Windows.

The updater is the installed flash itself, so there is no second program to install or keep current. Installation is designed around long-lived VMs: a running flashvm keeps executing the image it started with, and a new guest bundle lands beside the old one. See Self-update and Security.

Key facts

Runs onLinux (x86_64, arm64), macOS (Apple silicon), Windows (x64, arm64)
InterfacesCLI flash self-update · MCP flash_cli(args: ["self-update", ...])
Manifestupdate-manifest.json + detached update-manifest.json.sig, schema_version 1
SignatureEd25519, verified before parsing; trust anchor compiled in, plus a second key during a rotation window
Per-artifact checkSHA-256 and byte size from inside the signed manifest
OrderingAnti-rollback floor on the manifest's updated_at; never-downgrade per artifact
UnattendedOff by default (Windows' one-line install turns it on); --install-timer arms a systemd timer on Linux, a launchd daemon on macOS, a SYSTEM scheduled task on Windows; --interval default 15min

How it works

Verify, then parse

  1. flash downloads the manifest and its signature from the release channel.
  2. It verifies the Ed25519 signature against the key built into this binary. An unsigned or wrongly signed manifest never reaches the JSON parser. The channel URL moves where the manifest is fetched from; the trusted key is fixed at build time.
  3. It compares the manifest's updated_at with the newest manifest this machine has accepted (stored as last-manifest-ts in the state directory) and accepts it when it is the same age or newer.
  4. Every path in the manifest is channel-relative, so each download comes from the same channel the manifest did.
  5. Each artifact is downloaded, checked against its signed SHA-256 and size, and installed. An artifact older than what is installed is left as it is.

What each OS installs

Each OS uses its native install mechanism:

  • Linux updates each binary (flash, flashvm, the daemons) by writing the verified file beside it and renaming it into place. The guest bundle for the host's own architecture (kernel and root filesystem) carries a monotonic serial recorded in bundle.json, installs into a new versioned directory under /opt/flashvm/bundles, and the current symlink is swung onto it with rename(). The GPU engine and the flash demo files update the same way, one signed tarball per architecture.
  • macOS downloads the release .pkg named in the manifest's installers list, then checks it a second time with pkgutil --check-signature for FlashVMM's Developer ID Installer certificate before handing it to the system installer.
  • Windows downloads the release .msi from the same signed list and installs it with msiexec.

Running VMs carry on

rename() replaces a directory entry while the old file stays alive for every process that has it open. A running flashvm keeps executing the binary it was started from, and the next flash run starts the new one. A VM holding the old root filesystem keeps it, because the old bundle directory is never written to. Nothing is signalled and nothing restarts, so a sleeping or parked VM wakes exactly as it slept.

Ownership

When a package manager owns the binary, or a machine-managed systemd unit runs the install, self-update names that owner and leaves the version to it; --force updates anyway and says what it overrode.

Interfaces

CLI

flash self-update --show-trust     # channel and the SHA-256 fingerprint of the trusted key
flash self-update --status         # installed against published, changes nothing
flash self-update --dry-run        # what would change
flash self-update                  # verify and install
flash self-update --install-timer --interval 1h   # run it unattended (as root / Administrator)

MCP

flash_cli(args: ["self-update", "--status"])
flash_cli(args: ["self-update"])

REST

GET /v1/flashvm/version    # a running VM's binary and the artifact formats it speaks
GET /v1/version            # flashhostd, flashpoold, flashgpud and the controller report theirs

Contract: self-update exits with an error and installs nothing when the signature does not verify, the manifest is older than the accepted floor, or an artifact's SHA-256 or size differs from the manifest.

Guarantees

  • Signed end to end. Every byte installed is covered by one Ed25519 signature checked against a compiled-in key.
  • Always forward. The anti-rollback floor and per-artifact version check keep every machine moving to newer releases.
  • Atomic. Each file and each bundle switches in a single rename().
  • Zero disruption. Running, sleeping and pooled VMs keep the binary and bundle they started with.
  • Your schedule. Updates run when you run them, or on the timer you arm.

What it does

Related