Skip to content

feat: device identity templates, per-user state and retire-on-uninstall for virtual desktops - #246

Open
shubham-stepsecurity wants to merge 2 commits into
step-security:mainfrom
shubham-stepsecurity:sm/vdi-device-identity-v2
Open

shubham-stepsecurity wants to merge 2 commits into
step-security:mainfrom
shubham-stepsecurity:sm/vdi-device-identity-v2

Conversation

@shubham-stepsecurity

Copy link
Copy Markdown
Member

Builds on #243 (one stable device ID across root and user runs), which includes #236 (configurable device IDs). Review those first; this PR contains their commits plus one on top.

What

Makes the agent fit pooled, ephemeral virtual desktop fleets (VDI / Azure Virtual Desktop): hosts rebuilt on a schedule, several logged-in users at once, deleted without notice.

  • Identity templates on top of the configurable device id. device_id (config.json, MSI DEVICEID, bootstrap file, configure --device-id) now also accepts a template over {serial}, {hostname} and {user}, and the STEPSEC_DEVICE_ID environment variable overrides it at run time. {hostname}-{user} gives every user of a shared host their own device while a rebuilt host keeps its record; {user} follows a developer across hosts. Configured ids are sanitized for the backend's key formats; a plain literal and the default serial path are unchanged. serial_number keeps the real hardware serial and the payload gains device_id_source.
  • Multi-session hosts. When the template contains {user}, per-run state (run-gate cache, delta scan state, Node scan cache, run metrics) lives under <install dir>/users/<user> and the single-instance lock is per user, so concurrent sessions scan side by side as separate devices. The Windows scheduled task is registered with MultipleInstancesPolicy=Parallel in that case so a second session's instance is not dropped. A {user} template under a service account (SYSTEM, LOCAL SERVICE, machine accounts) is incomplete: the run is skipped with a log line instead of reporting under a made-up id, and the same predicate now flags Windows service accounts as no_user_logged_in.
  • Retire on uninstall. uninstall --retire, or retire_on_uninstall: true in config (MSI RETIREONUNINSTALL=1, bootstrap key), posts a best-effort retire to the backend before the scheduler job is removed, for every per-user identity the install has state for. --no-retire suppresses it and the MSI passes it on a major upgrade; a failure (offline, older backend) is a warning that never blocks the uninstall.
  • Docs. New docs/deploying-on-virtual-desktops.md (template semantics, rebuild and reuse rules, provisioning, retire hooks, troubleshooting); MSI, Intune and SCCM guides updated.

Testing

  • go build, go vet (darwin, windows, linux), go test ./... (51 packages), golangci-lint, gofmt, go mod tidy with no drift.
  • Identity vectors in internal/device/testdata/identity_vectors.json are shared with the Windows loader's PowerShell resolver in the agent-api branch (Pester, 17 tests).
  • Exercised on a Windows 11 multi-session VM: two local users produced users\dev1 and users\dev2 state dirs and the device ids <host>-dev1 / <host>-dev2 registered on the backend; configure show under SYSTEM reports the identity as incomplete; the task carries the INTERACTIVE principal with the parallel instance policy.
  • The MSI smoke workflow installs with DEVICEID={hostname} and asserts the config and configure show output.

Notes

…ll on top of the configurable device id resolver

This branch has not been deployed

No deployments
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.

1 participant