feat(agent)!: expose active package policy - #1937
Conversation
Expose the validated active package-broker policy through the shared authenticated GET /v1/policy route. Return a structured unavailable error without leaking policy source or file-security details. This requires now-policy-api and now-policy-server-template 0.4.0 from Devolutions/now-libraries#93 before the change can ship. Issue: Devolutions/now-libraries#93 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Implementation notes:
Validation on exact head All commands passed. The skipped test is an existing host-specific check whose local WindowsApps CI run https://github.com/Devolutions/devolutions-gateway/actions/runs/33828611066 passed all 42 checks, including locked Linux/Windows tests and Clippy, Windows Agent builds, and the Agent policy end-to-end test under LocalSystem. Copilot's exact-head review generated zero findings and left zero unresolved threads. Its Note LLM-assisted content (no human feedback). |
There was a problem hiding this comment.
Pull request overview
Adds authenticated active-policy inspection to the Agent’s package broker.
Changes:
- Implements
GET /v1/policywith structured responses. - Reuses connection authentication and adds snapshot/concurrency tests.
- Remains blocked on publishing and committing the 0.4.0 dependencies.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
crates/now-package-broker/src/server/mod.rs |
Implements and tests policy retrieval. |
crates/now-package-broker/src/auth.rs |
Exposes connection-level authentication for the endpoint. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Return a generic policy-unavailable message so clients cannot infer whether the active policy is file-backed, missing, or corrupt. Issue: Devolutions/now-libraries#93 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adopt the final shared server trait and keep policy-domain conversions owned by the broker after the compatibility feature removal. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Record the registry graph after removing the obsolete policy compatibility features so locked CI can resolve the manifest consistently. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exercise the policy HTTP contract from the repository integration tests while keeping authentication and snapshot-locking invariants beside the broker implementation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Launch the Agent through its CLI and issue HTTP requests over a real Tokio named-pipe client. Build the test Agent with the development signature bypass while requiring the matching debug configuration opt-in. Remove the in-process broker test harness and its testsuite dependencies; retain authentication and snapshot-locking invariants as broker unit tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Move privileged policy endpoint coverage into a dedicated tester so the active-policy path cannot silently skip in normal test runs. Run it as LocalSystem in CI with a development-only signature bypass. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use the official policy contract releases while preserving the Phase 1 read-only endpoint and existing YAML policy loading. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The custom 405 response violates HTTP requirements by omitting the Allow header.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 12/13 changed files
- Comments generated: 1
- Review effort level: Balanced
Include the mandatory Allow header when Phase 1 rejects mutation methods on the policy endpoint. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add authenticated policy management and validation for the package broker. Persist JSON policies atomically with secure path, ACL, concurrency, receipt, watcher, and audit checks while preserving stable runtime snapshots. Stacked on #1937. Uses the contract from Devolutions/now-libraries#99. UniGetUI policy management depends on this API. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove package-policy YAML discovery and parsing so unsupported files fail instead of being silently accepted. Issue: #1847 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
It silently removes released YAML policy compatibility and rewrites the corresponding historical changelog entry.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
CHANGELOG.md:48
- This edits the already-published 2026.2.4 release entry to claim that release supported JSON only, although the implementation shipped there accepted JSON, YAML, and YML. Keep the historical entry accurate; if YAML support is intentionally removed now, record that in the new release's notes instead.
- Files reviewed: 16/17 changed files
- Comments generated: 1
- Review effort level: Balanced
Keep the 2026.2.4 changelog accurate while the current PR documents the intentional JSON-only migration. Issue: #1847 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Create the LocalSystem policy fixture directly under ProgramData so every ancestor satisfies the production policy-path checks. Canonicalize the ordinary-file fixture before comparing it with its handle-resolved path on Windows runners that expose an 8.3 temp path. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep warning-only validation valid at the diagnostic cap and bind receipts to canonical semantic warning identities rather than raw-input locations. Report contract-compatible diagnostic paths and arguments while preserving bounded deterministic validation. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject equal policy validity timestamps because ValidUntil must be strictly later than ValidFrom. Advance the validator version so receipts issued under the previous semantics cannot be reused. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Expose only PolicyStore validation so every valid public result carries its keyed receipt. Keep receipt-less raw and committed-policy validation private to the containing store implementation. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject exact duplicates in set-backed draft fields before canonicalization. Authenticate protected policy routes once before body extraction and require the request-scoped marker in handlers. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reobserve published policies through the original configured path so watcher reloads derive the same fingerprint and retain returned store tokens. Exercise Create and Update through the real storage backend for ordinary and verbatim Windows paths. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Create the LocalSystem policy fixture directly under ProgramData so every ancestor satisfies the production policy-path checks. Canonicalize the ordinary-file fixture before comparing it with its handle-resolved path on Windows runners that expose an 8.3 temp path. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep warning-only validation valid at the diagnostic cap and bind receipts to canonical semantic warning identities rather than raw-input locations. Report contract-compatible diagnostic paths and arguments while preserving bounded deterministic validation. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject equal policy validity timestamps because ValidUntil must be strictly later than ValidFrom. Advance the validator version so receipts issued under the previous semantics cannot be reused. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Expose only PolicyStore validation so every valid public result carries its keyed receipt. Keep receipt-less raw and committed-policy validation private to the containing store implementation. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject exact duplicates in set-backed draft fields before canonicalization. Authenticate protected policy routes once before body extraction and require the request-scoped marker in handlers. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reobserve published policies through the original configured path so watcher reloads derive the same fingerprint and retain returned store tokens. Exercise Create and Update through the real storage backend for ordinary and verbatim Windows paths. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject prerelease-only bounds when prerelease matching is disabled and no stable version can satisfy the range. Advance the validator version so receipts issued under the previous semantics cannot be reused. Issue: #1937 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Exposes the validated active package-broker policy through the authenticated
GET /v1/policyroute. Clients receive a stable snapshot, while an unavailable policy returns the shared structured 404 response without exposing policy source or file-security details.Uses the official
now-policy0.3.0,now-policy-api0.4.0, andnow-policy-server-template0.4.0 releases. Phase 1 remains read-only: policy management, validation, and replacement routes are not exposed.Package policy files are now JSON-only. Deployments using
.yamlor.ymlpolicy files must convert them to.json; unsupported extensions and YAML content are rejected rather than silently parsed.Coordinated stack: Devolutions/now-libraries#93 defines the shared contract, this PR implements the Agent endpoint, and Devolutions/UniGetUI#5292 consumes it. Keep this PR open while Phase 2 #1963 is restacked and the full stack is finalized.
BREAKING CHANGE: Package broker policy files must use JSON; YAML and YML are no longer discovered or parsed.
Issue: Devolutions/now-libraries#93
Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com