Commit 883f58d
authored
Add ifc label for issue_read tool (#2457)
* Add ifc label for search_issues tool
Emits an IFC SecurityLabel on the search_issues tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me
in #2432, list_issues in #2453, and get_file_contents in #2454.
Search results may span multiple repositories, so the label is the IFC
join of the per-repository labels:
- Integrity is always untrusted (issues are user-authored).
- If any matched repository is public, the joined readers are
["public"] (the public side dominates the lub).
- Otherwise the joined readers are the intersection of the
collaborator sets across all matched private repositories.
- Empty result sets are labelled public-untrusted (no data leaked).
The shared searchHandler in search_utils.go gains an additive variadic
'searchOption' hook so SearchIssues can attach _meta.ifc without
duplicating the search call. SearchPullRequests is unaffected; it does
not pass any options.
If any per-repository visibility or collaborators lookup fails the label
is omitted entirely, consistent with get_file_contents, to avoid
misclassifying the result.
Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.
Note: this PR is chained on #2454 (gokhanarkan/fides-get-file-contents)
because it depends on the FetchRepoIsPrivate and FetchRepoCollaborators
helpers introduced there. GitHub will retarget the base to main once
#2454 merges.
* search_issues: address Copilot review findings
- LabelSearchIssues now returns (SecurityLabel, bool); the bool is
false when len(repoVisibilities) != len(readerSets), so callers can
omit the label rather than emit one computed from inconsistent
inputs.
- searchIssuesIFCPostProcess no longer substitutes [owner] when the
collaborators API returns an empty list. The substitution was
inconsistent with the cross-repo intersection semantics: the owner
could appear in another matched private repo's collaborator list and
thereby widen the joined reader set incorrectly. Empty collaborator
sets are now passed through unchanged.
- Add a subtest exercising the collaborators-failure branch (500 on
/repos/{owner}/{repo}/collaborators), asserting the tool still
succeeds and result.Meta["ifc"] is absent.
- Extend the LabelSearchIssues table tests with the slice-length
mismatch case.
Addresses the three Copilot findings on #2456.
* search_issues: flip IFC join to intersection (private wins)
Address Joanna's review feedback on #2456: a reader of a multi-repo result
must be authorised to read every matched private repository, so the IFC
join is the meet (intersection over private repos) rather than the join.
Public matches contribute the universe set and drop out of the
intersection without shrinking it.
- LabelSearchIssues: collect only the private reader sets, then intersect.
Empty result and all-public remain public-untrusted.
- TestLabelSearchIssues: flip the mixed public+private expectation and add
a 'two private + one public' case to lock in the new semantics.
- Test_SearchIssues_IFC_InsidersMode: mixed subtest now expects the
private repo's reader set instead of public.
* Add ifc label for issue_read tool
Emits an IFC SecurityLabel on the issue_read tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me
in #2432, list_issues in #2453, get_file_contents in #2454, and
search_issues in #2456.
issue_read operates on a single issue in a single repository so the
label has the same per-repo semantics as list_issues; the helper
ifc.LabelListIssues is reused directly. Integrity is always untrusted
(issue contents, comments, and label descriptions are user-authored).
Public repos are labelled PublicUntrusted; private repos are labelled
PrivateUntrusted with the repository's collaborator logins, falling
back to [owner] when the collaborators lookup fails.
The IssueRead handler dispatches to four sub-functions (GetIssue,
GetIssueComments, GetSubIssues, GetIssueLabels). The IFC label is
attached at the dispatch site via a single attachIFC closure, so all
four method branches emit the label without changes to the underlying
helpers. Visibility-lookup failures cause the label to be omitted
entirely (consistent with get_file_contents and search_issues).
A future cleanup PR can extract attachIFC into a shared helper now that
get_file_contents, search_issues, and issue_read use near-identical
closures; intentionally not bundled here to keep the diff minimal.
Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.
Note: chained on #2456 (gokhanarkan/fides-search-issues), which is in
turn chained on #2454. GitHub will retarget the base to main once those
merge.
* issue_read: simplify attachIFC by dropping unused lazy-cache
Address Joanna's review feedback on #2457: the dispatch switch returns
on exactly one branch, so attachIFC runs at most once per request. The
ifcLabelKnown / ifcIsPrivate / ifcReaders cache variables were never
reused across calls and only added complexity.
Inline the visibility and collaborators lookups directly into the
closure and drop the cache. Behaviour is identical; a follow-up can
add real per-request caching across handlers if needed.1 parent 9ad99c5 commit 883f58d
2 files changed
Lines changed: 156 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
296 | 296 | | |
297 | 297 | | |
298 | 298 | | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
299 | 330 | | |
300 | 331 | | |
301 | 332 | | |
302 | | - | |
| 333 | + | |
303 | 334 | | |
304 | 335 | | |
305 | | - | |
| 336 | + | |
306 | 337 | | |
307 | 338 | | |
308 | | - | |
| 339 | + | |
309 | 340 | | |
310 | 341 | | |
311 | | - | |
| 342 | + | |
312 | 343 | | |
313 | 344 | | |
314 | 345 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
278 | 399 | | |
279 | 400 | | |
280 | 401 | | |
| |||
0 commit comments