Skip to content

fix(agent): harden policy source matching and broker pipe handling - #2020

Merged
Benoît Cortier (CBenoit) merged 13 commits into
masterfrom
cbenoit-harden-broker-policy-sources
Sep 30, 2026
Merged

Benoît Cortier (CBenoit) merged 13 commits into
masterfrom
cbenoit-harden-broker-policy-sources

Conversation

@CBenoit

@CBenoit Benoît Cortier (CBenoit) commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Package source names are now matched more strictly. PowerShell and PowerShell7 source names use Unicode-aware, case-insensitive literal matching, while other package managers keep ASCII case-insensitive matching. The broker rejects requests whose source name has leading or trailing whitespace or default-ignorable code points before evaluating them. For PowerShell managers it also rejects wildcard characters (*, ?, [, ], and backtick). Policy validation rejects rules that use those spellings, and the validator version is now now-package-broker-policy-validator/11. Generated PowerShell commands pin the invariant culture so repository lookup does not depend on the host locale.

The broker also cleans up verified leftovers from an interrupted policy-store write probe instead of failing on them. Each named pipe connection's deadline now starts when the connection is accepted.

These are the general broker fixes from #1982, which will be closed. Its policy consent helper and write-authorization gate are not included.

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 review overview

🟡 Changes recommended

PowerShell lookup semantics can diverge from policy matching, and validation reporting has unresolved contract and indexing defects.

Review effort: Balanced
Findings: 2 High severity · 2 Medium severity

Open (4)
What changed in this PR

Hardens package-source policy matching, interrupted probe cleanup, and named-pipe deadlines.

Changes:

  • Adds stricter source-name validation and PowerShell-specific Unicode matching.
  • Recovers trusted write-probe remnants.
  • Starts connection deadlines at acceptance.
File Description
Cargo.lock Records the normalization dependency.
crates/​now-package-broker/​Cargo.toml Adds Unicode normalization support.
crates/​now-package-broker/​src/​evaluator/​matching.rs Applies manager-specific source matching.
crates/​now-package-broker/​src/​evaluator/​mod.rs Defines source-name ambiguity checks.
crates/​now-package-broker/​src/​evaluator/​tests.rs Tests source matching and rejection.
crates/​now-package-broker/​src/​evaluator/​wildcard.rs Implements Unicode matching helpers.
crates/​now-package-broker/​src/​pipe.rs Anchors deadlines at connection acceptance.
crates/​now-package-broker/​src/​policy_store/​validation.rs Rejects ambiguous policy source names.
crates/​now-package-broker/​src/​policy_store/​windows.rs Recovers and cleans probe remnants.
crates/​now-package-broker/​src/​server/​mod.rs Rejects ambiguous request sources.

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

Comment thread crates/now-package-broker/src/evaluator/mod.rs
Comment thread crates/now-package-broker/src/evaluator/wildcard.rs
Comment thread crates/now-package-broker/src/policy_store/validation.rs Outdated
Comment thread crates/now-package-broker/src/policy_store/windows.rs

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 review overview

🔵 Needs a closer look

A Windows test has an incorrect Unicode casing expectation, and validation findings can report the wrong source-name index.

Review effort: Balanced
Findings: None

Resolved since last review (4)
Previously missed (2)

In code that hasn't changed since last review

Medium severity Preserve submitted array indices when reporting invalid source names

crates/​now-package-broker/​src/​policy_store/​validation.rs:443

source_index is derived from iterating the deserialized BTreeSet, not from the submitted JSON array, so sorting/deduplication can make this pointer identify the wrong element. For example, if the invalid spelling is second in input but sorts first, the finding reports /0. Validate against the raw SourceNames array to preserve indices, or report the collection path without an index.

Low severity Correct SAFETY rationale for UTF-16 CompareStringOrdinal operands

crates/​now-package-broker/​src/​evaluator/​wildcard.rs:33

The operands passed to CompareStringOrdinal are UTF-16 vectors, not UTF-8 strings, so this SAFETY rationale describes the wrong representation. Use the same accurate rationale as the existing call in policy_security.rs:217.

This issue also appears on line 91 of the same file.

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 review overview

🔵 Needs a closer look

Security-sensitive Unicode matching and Windows filesystem recovery semantics warrant final human validation.

Review effort: Balanced
Findings: None

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>
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>
Retire only verified protected probe remnants after an interrupted write-capability check, and open probe files delete-on-close so an interrupted probe does not leave them behind.

Salvaged from 7b1446a (policy_store/windows.rs only).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Start the per-connection deadline when the pipe client is accepted rather than when the spawned task first runs, so scheduling delay under load does not extend how long a client can hold a connection slot.

Salvaged from the generic part of 7abc416.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
PowerShell resolves -Repository through WildcardPattern using the current culture, so wildcard syntax or a host locale could select repositories that policy evaluation never matched. Reject PowerShell wildcard characters in request and policy source names, and pin generated PowerShell scripts to the invariant culture.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bump the policy validator version for the new source-name rejections, and make the probe recovery test fail on unexpected fixture errors instead of skipping.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
SourceNames is deserialized into a sorted set, so an element index could point at the wrong submitted entry. Report the SourceNames collection instead, and correct the CompareStringOrdinal safety rationale.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@CBenoit
Benoît Cortier (CBenoit) force-pushed the cbenoit-harden-broker-policy-sources branch from 3142c73 to d786332 Compare September 30, 2026 16:51
@CBenoit
Benoît Cortier (CBenoit) merged commit f52641f into master Sep 30, 2026
134 of 138 checks passed
@CBenoit
Benoît Cortier (CBenoit) deleted the cbenoit-harden-broker-policy-sources branch September 30, 2026 17:55
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