Skip to main content

Module service

Module service 

Source
Expand description

Registering daemon run with the operating system, so that a home host resumes work by itself after a reboot with nobody logged in.

Journey 5 is the whole of the requirement: “the machine reboots with nobody logged in; the boot-start service starts the agent, which reads the user access token from the machine-scoped secret store”. Everything in this file exists to make that sentence true on Windows, macOS, and Linux, and to make service status say so — or say precisely why not.

§The shape: render, then apply

A service manager is the one dependency a cargo test run cannot have. So this module is split in two, and the split is the reason most of it is testable on a developer’s laptop whatever OS that laptop runs:

  • Rendering is pure. ServiceDefinition turns an InstallPlan into the exact text the platform consumes — a systemd unit, a launchd property list, a Task Scheduler XML document, or a canonical descriptor of the Windows service parameters. No cfg, no privileges, no I/O. A Windows developer renders and asserts the systemd unit; a Linux CI leg renders and asserts the launchd plist.
  • Applying is behind ServiceControl, one trait with a backend per platform and a public in-memory double (RecordingControls) that f3 and this crate’s own tests drive without touching the host.

ServiceOperations is the layer above both, and it is where the logic that is not platform-specific lives: refusing an install while the single-instance lock is held, recording the resolved absolute binary path, detecting a stale one, switching start mode without reinstalling, and uninstalling without deleting a byte of configuration, secrets, or cache.

§Two domains, not two products

--start-at boot and --start-at login are the same daemon registered in two different domains:

bootlogin
Windowsa service in the Service Control Manager, LocalSystema Task Scheduler task with a logon trigger, running at LeastPrivilege
macOSa LaunchDaemon in /Library/LaunchDaemonsa LaunchAgent in ~/Library/LaunchAgents
Linuxa system unit in /etc/systemd/systema user unit in ~/.config/systemd/user

The Windows row is the one that is not symmetric, and it is worth saying why rather than leaving a reader to wonder. Windows services cannot start at logon. Service trigger-start covers domain join, an IP address becoming available, a device arriving, a firewall port event and a group-policy change; there is no logon trigger, and there is no user-session service type this product could use instead. Task Scheduler is the mechanism Windows actually provides for “run this when the operator signs in”, so that is what --start-at login uses there. It is registered, inspected, and removed through the same ServiceControl trait as everything else, so nothing above this module has to know.

§What the account can reach, and why it is not more

05-infrastructure.md requires “a least-privilege account that can read the machine-scoped secret store and write its configured cache and runtime directories”. Those two clauses pull in opposite directions on every platform, and the resolution is recorded per platform in docs/service-account.md and checked by review_least_privilege, which reads the rendered definition back and reports anything it grants beyond the requirement.

The Windows resolution is the one that surprises people. d2 protects the machine-scoped store with D:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;OW) and documents that the DACL is the access control, because a machine-scope DPAPI blob is decryptable by any process on the host. NT AUTHORITY\ LocalService and NT AUTHORITY\NetworkService — the two accounts a “least privilege service” reflex reaches for — are named by none of those three ACEs and therefore cannot read the token at all. Widening the DACL to reach them would grant every service on the host read access to the one credential this product holds, which is strictly worse than running as LocalSystem. secrets.rs is not this task’s file and is not widened; the service runs as LocalSystem, and review_least_privilege records the account together with the reason it is the minimum that satisfies the requirement rather than pretending it is small.

§What is deliberately not claimed

A reboot is not something a test suite can have. Every assertion here is about configuration a boot-time start depends on — the start type, the account, the recorded absolute path, the restart policy the service manager reports back — and about a store that is readable outside any login session, which d2 proves separately. That the machine actually comes back up and the agent actually resumes is human gate 3 in 06-migration-rollout.md, and nothing in this file is evidence for it.

Structs§

HostControls
The real service managers of the host this binary was built for.
InstallPlan
Everything a backend needs, resolved and validated.
InstallRecord
What service install wrote down, and what service status reads back.
InstallRequest
What service install was asked for, before anything has been resolved.
Installed
What install did.
PrivilegeFinding
One thing the review has to say about a definition.
PrivilegeReview
What a definition actually grants, measured against the requirement.
RecordingControls
A ControlFactory that registers nothing and remembers everything.
Registration
What a service manager says about a registration it holds.
RestartPolicy
The restart-on-failure policy, and the bound on how fast it may retry.
RunnerRootRefusal
One policy’s last runner-root refusal, as service status reports it.
ServiceDefinition
One platform’s definition of the registration, as text.
ServiceDirectories
The four directories the registration was installed against.
ServiceIdentity
What the operating system calls this registration.
ServiceOperations
Install, uninstall, inspect, and switch start mode.
ServiceShutdown
A stop request delivered by the Windows Service Control Manager.
ServiceStatus
Everything service status reports.
StartModeChange
What set_start_mode did.
StatusProblem
One thing service status has to report as wrong.
TaskPrincipal
The account a Task Scheduler task runs as.
Uninstalled
What uninstall did — and, as importantly, what it did not.
WindowsServiceSpec
How CreateServiceW should be called, in a form that can be reviewed, asserted, and printed on any platform.

Enums§

BinaryPath
What became of the absolute path install recorded.
DefinitionKind
Which of the four things a platform reads.
FindingKind
Whether a finding is about too much authority or too little.
ServiceAccount
The account a registration runs under.
ServiceError
Something went wrong installing, inspecting, or removing the registration.

Constants§

CONTACT_FILE
The file the daemon touches after every successful GitHub call, inside state/.
DAEMON_ARGUMENTS
The arguments the installed command line carries.
DESCRIPTION
One line of explanation, for the same three places.
DISPLAY_NAME
What an operator sees in services.msc, launchctl list, or systemctl status.
LAUNCH_AGENTS_SUBDIR
Where a LaunchAgent lives, under the operator’s home directory.
LAUNCH_DAEMONS_DIR
Where a LaunchDaemon lives.
LOG_FILE_STEM
The rotating diagnostic log the daemon writes, inside logs/.
RECORD_FILE
The file install writes and status reads, inside config/.
RECORD_SCHEMA_VERSION
The version of InstallRecord on disk.
ROOT_REFUSAL_FILE
The agent’s last runner-root refusal, for service status to report.
SERVICE_NAME
The product’s own service name, on every platform that wants a short one.
START_LIMIT_BURST
How many consecutive failures the platform tolerates before it stops retrying.
SYSTEMD_HARDENING
The hardening directives every unit carries, in the order they are rendered.
SYSTEMD_SYSTEM_DIR
Where a systemd system unit lives.
SYSTEMD_USER_SUBDIR
Where a systemd user unit lives, under the operator’s home directory.
WINDOWS_SCM_HOST_ARGUMENT
Hidden CLI marker carried only by Windows boot-service registrations.

Traits§

ControlFactory
Chooses the control for a start mode.
ServiceControl
One platform’s service manager, for one start-mode domain.

Functions§

clear_runner_root_refusal
Clears one policy’s entry, because that policy placed a runner.
contact_path
Where the heartbeat lives.
executable_from_command_line
Reads the executable back out of a command line quoted by [quote_argument].
host_definition_kind
Which manager holds a given start-mode domain on the platform this binary was built for.
inspect_binary
Decides what became of a recorded path.
last_github_contact
Reads the last successful GitHub contact, or reports that none was recorded.
launchd_plist
Renders the launchd property list for this plan.
record_github_contact
Records that GitHub was reached successfully, for service status to report.
record_runner_root_refusal
Records that one policy could not use its runner root.
review_least_privilege
Reads a definition back and reports what it grants.
root_refusal_path
Where the refusals live.
runner_root_refusals
Every policy whose runner root refused it and has not since succeeded.
systemd_unit
Renders the systemd unit for this plan.
windows_scheduled_task_xml
Renders the Task Scheduler document for a --start-at login registration.
windows_service_spec
Derives the Windows service parameters from a plan.