Skip to content

feat(agent,agent-installer): add policy consent helper - #1982

Open
Benoît Cortier (CBenoit) wants to merge 25 commits into
cbenoit-policy-e2e-supportfrom
cbenoit-agent-policy-consent-helper
Open

Benoît Cortier (CBenoit) wants to merge 25 commits into
cbenoit-policy-e2e-supportfrom
cbenoit-agent-policy-consent-helper

Conversation

@CBenoit

Copy link
Copy Markdown
Member

Adds an Agent-installed consent helper that lets supported UniGetUI installations request protected policy updates with explicit elevation consent.

The helper authenticates the running UniGetUI and Agent images, preserves policy validation and conflict semantics, and is installed and discovered through the Agent MSI for both default per-user and all-users UniGetUI deployments.

Issue: #1963

@CBenoit

Copy link
Copy Markdown
Member Author

Implementation notes:

  • Keeps the private UniGetUI elevation protocol at version 2.0 and forwards only the official policy replacement fields.
  • Authenticates retained UniGetUI and Agent process/image identities, current or transition signer pins, fresh whole-chain revocation status, product/version identity, LocalSystem broker identity, and protected trusted-writer installation paths.
  • Pins the connected Agent mapped image and every custom installation-directory ancestor against reparse or untrusted-writer replacement before policy data is sent.
  • Installs and signs one x64/ARM64 NativeAOT helper through the Agent MSI and publishes transactional machine discovery values.
  • Verified with 53 helper tests, 76 installer tests, full locked Rust workspace tests and Clippy, i686 broker compilation, ARM64 managed compilation, and an x64 NativeAOT PE/no-CLR/manifest/size check.
  • Local ARM64 NativeAOT linking remains unavailable because this workstation lacks the MSVC ARM64 C++ tools; CI retains the ARM64 NativeAOT build.
  • Signer provenance was verified from signed UniGetUI 2026.2.7 and 3.3.7 release artifacts and recorded beside both SPKI pins.

Note

Human-tuned, LLM-assisted content.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Version parsing and cancellation handling can reject valid callers or return incorrect protocol outcomes.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds an elevated Agent policy-consent helper that authenticates UniGetUI and the Agent broker before forwarding policy updates.

Changes:

  • Adds the NativeAOT consent helper, protocol, authentication, and tests.
  • Restricts broker policy writes to the installed helper.
  • Packages, signs, registers, and tests the helper in CI.
File summaries
File Description
package/AgentWindowsManaged/Resources/Includes.cs Shares helper discovery constants.
package/AgentWindowsManaged/Program.cs Installs and registers the helper.
package/AgentWindowsManaged/DevolutionsAgent.csproj Links the shared contract.
package/AgentWindowsManaged.Tests/PackageBrokerInstallerTests.cs Tests registry discovery.
package/AgentPolicyConsent/Protocol.cs Defines helper framing and validation.
package/AgentPolicyConsent/Program.cs Implements the helper workflow.
package/AgentPolicyConsent/PolicyConsentContract.cs Defines identity and signer constants.
package/AgentPolicyConsent/PeerTrust.cs Authenticates UI and broker processes.
package/AgentPolicyConsent/DevolutionsAgentPolicyConsent.csproj Configures the NativeAOT executable.
package/AgentPolicyConsent/BrokerClient.cs Forwards policy updates to the broker.
package/AgentPolicyConsent/app.manifest Requires administrator elevation.
package/AgentPolicyConsent.Tests/ProtocolTests.cs Tests protocol and trust behavior.
package/AgentPolicyConsent.Tests/DevolutionsAgentPolicyConsent.Tests.csproj Configures helper tests.
crates/now-package-broker/src/server/mod.rs Applies helper-specific write authentication.
crates/now-package-broker/src/auth.rs Validates the installed helper identity.
ci/package-agent-windows.ps1 Adds the helper to MSI packaging.
.github/workflows/package.yml Signs and repackages the helper.
.github/workflows/ci.yml Builds and tests the helper.
Review details
  • Files reviewed: 18/18 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread package/AgentPolicyConsent/BrokerClient.cs
Comment thread package/AgentPolicyConsent/PeerTrust.cs Outdated
Comment thread package/AgentPolicyConsent/DevolutionsAgentPolicyConsent.csproj Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Helper credential validation does not conform to the canonical policy API character restrictions.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

package/AgentPolicyConsent/Protocol.cs:71

  • These fields are policy-store credentials, but IsCredential accepts every printable ASCII character after the first one. The canonical policy API restricts store tokens and validation receipts to [A-Za-z0-9._~:-] (now-libraries management.rs, PolicyStoreToken/PolicyValidationReceipt), so values containing spaces, quotes, slashes, etc. pass this protocol boundary and are only rejected later by the broker. Apply the canonical character rule here (and to returned store tokens) so malformed helper requests fail as protocol errors rather than entering the privileged write path.
  • Files reviewed: 18/18 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Security-critical native authentication, elevation, protocol, and multi-architecture packaging changes warrant final human review.

Review details
  • Files reviewed: 18/18 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@CBenoit
Benoît Cortier (CBenoit) force-pushed the cbenoit-agent-policy-consent-helper branch from d2f50f3 to c1f0a22 Compare September 15, 2026 18:29
@CBenoit
Benoît Cortier (CBenoit) removed this pull request from stack #1976 September 18, 2026 07:26
@CBenoit
Benoît Cortier (CBenoit) force-pushed the cbenoit-agent-policy-consent-helper branch from 4c39cb0 to c13d2a1 Compare September 20, 2026 09:12
Install one protected NativeAOT helper that authenticates retained UniGetUI and Agent process identities before forwarding bounded policy replacement requests. Preserve protocol 2.0 conflict and uncertainty semantics while integrating transactional discovery, signing, and packaging.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Require fresh whole-chain WinTrust revocation status before authorizing the UniGetUI parent or Agent broker. Bound broker trust retrieval to the existing exchange timeout and reject all pre-dispatch authentication failures.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Authenticate the connected Agent through its retained mapped image and an allowed Devolutions signer before sending policy data. Pin the protected installation directory chain against reparse and untrusted-writer replacement, including custom install locations, and record the evidence behind both UniGetUI signer pins.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve timeout responses during broker authentication, accept prerelease UniGetUI versions, and suppress the helper console window. Mark ARM64 discovery registry components as 64-bit so WiX can package them beneath ProgramFiles64Folder.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Apply the canonical policy API safe-ASCII character set to helper credentials before a privileged request is dispatched.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Accept only current-signed UniGetUI hosts from version 2026.2.7. Remove transition signer discovery while retaining protected helper authorization and ARM64 installer coverage.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Publish the configured broker pipe through the protected helper discovery key so consent writes work with custom local pipe names. Reject malformed discovery and oversized requests before dispatch.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Document the required NativeAOT consent helper publish and packaging argument for local Agent MSI builds.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject remote-provider parent images before retaining them for policy consent. Document every required local Agent package artifact argument.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve the retained UniGetUI image path before trusting its local volume. Keep already-correct package inputs absolute while the MSI build changes directories.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the bounded broker connection lifetime aligned with the consent helper's two-minute policy replacement exchange.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep ordinary pipe capture and requests bounded to 30 seconds. Allow the two-minute exchange only after the exact consent helper is authorized.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep unauthenticated and ordinary pipe connections at 30 seconds. Extend only a successfully authorized consent-helper policy write to the two-minute exchange limit.

Issue: #1963

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retire only verified protected probe remnants after an interrupted
capability check, and require retained Agent ancestor handles to remain
expected directories.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use Unicode-aware literal matching for source names so a policy deny
uses the same case semantics as PowerShell repository lookup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Normalize source names before ordinal matching so policy evaluation uses
the same canonical repository identity as PowerShell.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject source spellings containing default-ignorable characters before
PowerShell can resolve them to a different policy identity.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject default-ignorable source spellings before policy evaluation and
command construction can disagree.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Carry the ordinary pipe deadline through client capture and serving so
unauthenticated clients cannot reserve a connection slot twice as long.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject noncanonical source spellings before policy matching so PowerShell
repository trimming cannot bypass a source-specific rule.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Apply PowerShell source canonicalization only to PowerShell so other
package managers retain their own source identity semantics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject policy source spellings that cannot safely match package requests
before they can create unusable source-specific rules.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exercise ambiguous SourceNames with a valid PowerShell rule so the
regression protects the shared policy-validation predicate.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Publish consent-helper discovery and configured broker-pipe values to the
32-bit registry view so supported x86 consumers find the protected helper.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove the obsolete warning acknowledgement field so helper replacement
requests match the released policy API after the parent rebase.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@CBenoit
Benoît Cortier (CBenoit) force-pushed the cbenoit-agent-policy-consent-helper branch from c13d2a1 to 1145f0c Compare September 30, 2026 06:57

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

Development

Successfully merging this pull request may close these issues.

2 participants