0033. Agent self-elevating bootstrap installer + fixed install location¶
- Status: accepted
- Date: 2026-07-03
Context and Problem Statement¶
A non-technical relative onboards their own PC. Today the dashboard hands them a ZIP
(kenny-agent.exe + install.bat + README.txt, ADR-0012); they must unzip it, then
right-click install.bat → "Run as Administrator". Double-clicking without elevation
fails silently, and because there is no fixed install location the exe and the
enroll-token-bearing kenny-agent.config.json land wherever the ZIP was extracted (usually
Downloads). This is the sharpest onboarding friction in the whole system.
We want a one-double-click, one-UAC-prompt install without giving up the property ADR-0013 depends on: the single binary owns its whole lifecycle (stop → swap → restart), which is what server-triggered self-update needs.
Considered Options¶
- Self-elevating bootstrap inside the binary: a new
setupsubcommand that elevates via UAC at runtime, copies the binary into a fixed%ProgramFiles%\kenny, and runsinstallfrom there. Per-agent config rides in akenny-agent.setup.jsonsidecar next to the exe. - External installer (Inno/NSIS/MSI/MSIX) that registers the service.
- winget package.
Decision Outcome¶
Chosen option: self-elevating bootstrap inside the binary, because it removes the unzip-and-right-click ritual while staying fully compatible with the ADR-0013 self-update model. MSI/MSIX want to own versioning and would fight the in-place swap; winget points at a public release and cannot carry the per-agent enroll token + server URL + pinned server key that the bundle exists to deliver. A bootstrap keeps "the binary owns its lifecycle" and needs no external toolchain in CI.
setupsubcommand (Windows; a no-op stub elsewhere). It resolves the connection config from CLI flags or thekenny-agent.setup.jsonsidecar (flags win), then: checks token elevation; if not elevated, relaunches itself elevated viaShellExecuteExWverbrunas(the UAC prompt) and waits; once elevated, creates%ProgramFiles%\kenny, copies the running exe there, and invokes that copied binary's existinginstall— so the serviceexecutable_pathandkenny-agent.config.jsonresolve to the fixed location, notDownloads. After a successful install it deletes the source sidecar (it carries the one-time enroll token). The agent's Ed25519 key stays in%ProgramData%\kenny(ADR-0023), untouched by relocation or self-update.- Embedded application manifest stays
asInvoker(plus long-path + per-monitor-v2 DPI), notrequireAdministrator. The same binary launches the tray in the standard-user interactive session (ADR-0011/0018); a require-admin manifest would make that launch fail. Elevation is therefore requested programmatically, only on thesetuppath. - Bundle shape: the server ships
kenny-agent.exe+setup.bat(one line:kenny-agent.exe setup) +kenny-agent.setup.json+README.txt. The base exe is shipped unmodified, so its optional Authenticode signature (ADR-0012,release.yml) stays valid; the per-agent secrets ride in the JSON sidecar rather than being baked into the exe (which would break signing) or a secret-bearing.bat.
Consequences¶
- Good, because onboarding is one double-click and one UAC approval; nothing to unzip, no "Run as Administrator" instruction, and a fixed, predictable install location.
- Good, because it composes with ADR-0013 self-update unchanged and needs no MSI/MSIX/winget toolchain — the binary still owns its lifecycle.
- Good, because a signed base exe + JSON sidecar keeps code-signing meaningful while still delivering per-agent config.
- Bad, because UAC elevation, the copy into Program Files, and the service install can only be
runtime-verified on real Windows; they are compile-verified via
cargo check --target x86_64-pc-windows-gnuand exercised by the self-hosted Windows e2e, with the off-Windows path returning "only supported on Windows". Config resolution (resolve_setup_config) is portable and unit-tested on Linux CI. - Bad, because the enroll token now sits in a plaintext sidecar next to the exe until setup
runs; it is single-use, TLS-delivered, and deleted after install — the same trust profile
as the previous
install.bat, which also carried it in cleartext.
More Information¶
- Relates to ADR-0012 (prebuilt binary + config injection; the sidecar is the injection
channel) and ADR-0013 (Windows service + self-update;
setupwrapsinstall). - No wire-contract change: frames, tool schemas, and fixtures are untouched.
- Implementation:
kenny-agent/src/setup.rs,config.rs,main.rs,service.rs(uninstall also removes the install dir),build.rs(manifest); server bundle inkenny-server/kenny_server/distribution.py.