feat(agent): opt-in interactive-session launch for visible GUI/browser tests#69
Open
EliorMachlev wants to merge 2 commits into
Open
feat(agent): opt-in interactive-session launch for visible GUI/browser tests#69EliorMachlev wants to merge 2 commits into
EliorMachlev wants to merge 2 commits into
Conversation
…r tests Add Agent:LaunchInInteractiveSession (Enabled=false, LocalSystemOnly=true by default) to launch the whole agent in the active console session (Session 1) instead of the service's non-interactive Session 0, so GUI processes it spawns downstream (e.g. a Selenium/NUnit browser) are visible on the logged-in desktop. This is a deliberate, opt-in isolation downgrade. Crossing the session boundary needs WTSQueryUserToken -> SeTcbPrivilege, i.e. the service must run as LocalSystem (or an account granted a LocalSystem-equivalent privilege), plus a logged-in console session. Every precondition failure (wrong identity, no console session, missing privilege) logs a prominent warning and falls back to a normal Session 0 (headless) launch, so the service never fails because of this setting. Because the shipped default identity lacks the privilege, the feature is effectively double opt-in. The interop (InteractiveSessionLauncher) does the CreateProcessAsUser launch with stdout/stderr pipe redirection (preserving SEVERE counting and secret redaction) and places the agent tree in a kill-on-close Job Object so stop/restart still reaps the browser/build children. Environment sanitization still applies. The default (disabled) path is unchanged. Docs: configuration.html gains a settings row pair, a JSON sample, and an Interactive-session section with a top security warning and a prerequisites table for both LocalSystem and non-LocalSystem modes. Security.md marks reports stemming from enabling this feature out of scope. Interop is compile-verified and covered by config-binding tests only; the CreateProcessAsUser path is not exercisable in CI (no interactive session / privilege), same class as the TPM code path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ges, and open items Note InteractiveSessionLauncher.cs in the Agent-process source layout and the Agent:LaunchInInteractiveSession key axis, add PR #69 to recent merges, and flag the CreateProcessAsUser path under "Not yet verified against real infra" (compile-verified only; needs autologon + LocalSystem, untestable in CI). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an opt-in
Agent:LaunchInInteractiveSessionsetting that launches the whole agent in the active console session (Session 1) instead of the service's non-interactive Session 0 — so GUI processes it spawns downstream (e.g. a Selenium/NUnit browser) are visible on the logged-in desktop.Why it's gated the way it is
This is a deliberate, opt-in isolation downgrade. A Windows service always runs in Session 0; crossing into the interactive session needs
WTSQueryUserToken→SeTcbPrivilege, i.e. the service must run as LocalSystem (or an account granted a LocalSystem-equivalent privilege), plus a user logged into the console.LocalSystemOnly: true(default) → attempt only when the service is LocalSystem.LocalSystemOnly: false→ also attempt under a non-LocalSystem account grantedSeTcbPrivilege(discouraged — that privilege is LocalSystem-equivalent, so it hides risk rather than reducing it).Every precondition failure (wrong identity, no console session, missing privilege) logs a prominent warning and falls back to a normal Session 0 (headless) launch — the service never fails because of this setting. Because the shipped default identity (
NT SERVICE\Jenkins) lacks the privilege, the feature is effectively double opt-in: flipping the flag alone does nothing until the service identity is also reconfigured.How
InteractiveSessionLauncherdoes theCreateProcessAsUserlaunch with stdout/stderr pipe redirection (preserving SEVERE counting + secret redaction) and places the agent tree in a kill-on-close Job Object so stop/restart still reaps the browser/build children.Hardening:SanitizeEnvironmentstill applies.AgentProcessLauncherdispatches to the interop only when enabled; the default (disabled) path is unchanged.Docs / policy
docs/configuration.html: settings rows, JSON sample, and an Interactive-session launch section with a top security warning and a prerequisites table for both LocalSystem and non-LocalSystem modes.Security.md: reports stemming from enabling this feature are marked out of scope (a defect where it acts without being enabled, or fails to fall back safely, remains in scope).Testing
dotnet test -c Release -p:RestoreLockedMode=true→ 178/178 pass; config-binding test extended to cover the new nested keys + defaults.CreateProcessAsUserpath is not exercisable in CI (no interactive session / privilege), same class as the TPM code path — it needs manual validation on a box with autologon + the service set to LocalSystem.🤖 Generated with Claude Code