Skip to content

Send a persisted device id with lease requests - #428

Merged
ffilippopoulos merged 2 commits into
masterfrom
agent/device-id
Oct 20, 2026
Merged

ffilippopoulos merged 2 commits into
masterfrom
agent/device-id

Conversation

@ffilippopoulos

@ffilippopoulos ffilippopoulos commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

The agent sends a device id with every lease request, so that servers keep a lease per user and device (#427).

  • The id is a random UUID, created on first start and kept in the file set with the new -device-id-file flag, /var/lib/wiresteward/device-id by default, next to the token. The file is synced with its directory, written with mode 0600 and is the same after restarts. It is created exclusively, so two first starts end up with the id that is stored.
  • The agent does not start when the id cannot be read or created, or when the directory of the token cannot be created: agent.NewAgent returns an error, before any device is set up, and the agent exits. agent.Options has a new DeviceIDFile, which is required.
  • A file written by hand can hold the UUID with or without dashes, in either case, with braces, a urn:uuid: prefix or a byte order mark. Other content fails the start and is not replaced. An empty file, which a crash can leave behind, is replaced.
  • devicemanager.New and NewWithBackend take the device id, and it is sent as DeviceID in the request. The field is omitted from the JSON when empty, so the body is what servers without device ids receive.
  • The User-Agent of the agent is wiresteward-agent/<version> (<os>; <arch>). The servers show it as the client of a peer.
  • Android: the app keeps the id in its files directory and sends wiresteward-android/<versionName> (Android <release>; <abi>). Mobile.start takes a StartOptions in place of its string arguments, with defaults for an empty listen address, log level and user agent.
  • README: a new "Device id" section, which says that the file must not be copied between machines or kept in an image, as machines that share an id share a lease.

The systemd and launchd examples run as root, so the default location is writable. An agent run as another user needs -device-id-file and -token-file set to writable places.

Tests: the id file (creation, mode, stability, the accepted spellings, other content, an empty file, 16 concurrent first starts, exclusive creation, unreadable and unwritable locations, no leftover temporary files), the agent end to end against a fake lease server (the request carries the stored id and the user agent, a restart sends the same id, NewAgent refuses to start without an id or a token directory and sets up no device), the id in the lease request, the user agent format, and the Android start options. go test -race ./..., go vet, the darwin, arm and mipsle builds, the android module tests and the debug APK pass. The Android build has not been run on a device. The fsync calls are not covered by a test.

The agent keeps a device id, a random UUID, in the file set with
-device-id-file, /var/lib/wiresteward/device-id by default, and sends it as
the DeviceID of every lease request. The id is created and stored on first
start and is the same after restarts.

The agent does not start when the id cannot be read or created, so a client
never runs with an id that it cannot keep. NewAgent returns an error in that
case, before any device is set up.

The User-Agent of the agent includes the operating system and the
architecture. The Android app passes its own, with the app and Android
versions and the ABI, to the agent and keeps the id in its files directory.
@ffilippopoulos
ffilippopoulos marked this pull request as ready for review October 19, 2026 13:37
Sync the device id file and its directory before the id is used, so that a
crash cannot leave an empty file.

Create the file exclusively, so that two first starts of the agent end up
with the id that is stored, and read it again when it was created by the
other one.

Accept an id written as a UUID with or without dashes, in either case, with
braces, a urn:uuid: prefix or a byte order mark. Fail on other content
instead of replacing it, and only replace an empty file.

Fail to start when the directory of the token cannot be created, as the
token cannot be stored.

Document that the id file must not be copied to another machine or kept in
an image.

Replace the string arguments of the Android Start with StartOptions, and
default its empty user agent, listen address and log level.
@ffilippopoulos
ffilippopoulos merged commit d41f70e into master Oct 20, 2026
10 checks passed
@ffilippopoulos
ffilippopoulos deleted the agent/device-id branch October 20, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants