Add ifc label for list_issues tool#2453
Open
gokhanarkan wants to merge 2 commits into
Open
Conversation
Emits an IFC SecurityLabel on the list_issues tool result when the InsidersMode flag is enabled, mirroring the pattern landed for get_me in #2432. Public repositories are labelled PublicUntrusted; private repositories are labelled PrivateUntrusted with the repository owner as a placeholder reader (full collaborator enumeration is intentionally deferred to a follow-up shared helper). A new IsPrivate field is added to the ListIssues GraphQL query types so visibility is available without a second round trip. Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Information Flow Control (IFC) _meta.ifc labeling to the list_issues MCP tool output when InsidersMode is enabled, matching the existing get_me pattern and enabling downstream enforcement/telemetry to reason about tool-output integrity/confidentiality.
Changes:
- Added reusable IFC label constructors in
pkg/ifc(public/private × trusted/untrusted) and refactoredLabelGetMe()to delegate toPublicTrusted(). - Extended
list_issuesGraphQL query types to fetch repositoryisPrivate, and emits an IFC label ontoCallToolResult.Meta["ifc"]in insiders mode. - Added
Test_ListIssues_IFC_InsidersModeand updated existing list_issues GraphQL test fixtures/query strings to includeisPrivate.
Show a summary per file
| File | Description |
|---|---|
pkg/ifc/ifc.go |
Adds shared IFC label constructors and a LabelListIssues helper used by tools to attach consistent labels. |
pkg/github/issues.go |
Fetches repository.isPrivate in list_issues queries and conditionally attaches _meta.ifc when InsidersMode is enabled. |
pkg/github/issues_test.go |
Updates list_issues GraphQL expectations for isPrivate and adds coverage for IFC meta emission in insiders mode. |
Copilot's findings
- Files reviewed: 3/3 changed files
- Comments generated: 0
JoannaaKL
reviewed
May 12, 2026
| // repository's collaborator logins. Using [owner] as a | ||
| // placeholder until a shared visibility/collaborators helper | ||
| // lands (tracked under copilot-mcp-core#1623). | ||
| var readers []string |
Contributor
There was a problem hiding this comment.
Let's populate the readers set too, for now we don't have to cache them (we can add it in a follow up pr). Repo collaborators will be fetched only for private repos
Addresses Joanna's review feedback: for private repositories, populate the IFC confidentiality reader set with the repository's collaborator logins instead of the [owner] placeholder. Adds an exported FetchRepoCollaborators helper in pkg/github/repositories.go that paginates through Repositories.ListCollaborators. Mirrors the helper in github-mcp-server-remote (without the cache for now; cache can land in a follow-up). The lookup is invoked only for private repos under InsidersMode; if it fails we fall back to [owner] so the reader set is never empty for a private repo.
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.
Emits an IFC
SecurityLabelon thelist_issuestool result when theInsidersModeflag is enabled, mirroring the pattern landed forget_mein #2432.Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389. This is one of the ingress tools listed in #1623's tool table.
What this PR does
_meta.ifconto thelist_issuesCallToolResultwhendeps.GetFlags(ctx).InsidersModeis true. No behaviour change when the flag is off.PublicUntrusted()(issue contents are attacker-controllable, so integrity isuntrusted; readers are["public"]).PrivateUntrusted([owner])as a placeholder for the reader set. See limitation below.IsPrivatefield to all fourListIssues*Query*GraphQL types so visibility is available without an extra REST round trip.IssueQueryResultgains aGetIsPrivate() boolmethod.New shared helpers
Adds four general label constructors in
pkg/ifc/ifc.goto seed reuse for upcoming ingress tools (get_file_contents,search_issues, …):PublicTrusted()PublicUntrusted()PrivateTrusted([]string)PrivateUntrusted([]string)LabelGetMe()is refactored to delegate toPublicTrusted(); output is byte-for-byte identical (covered by the existingTest_GetMe_IFC_InsidersModetest). Flagging this for reviewers in case duplication concerns come up — happy to slim back to a singleLabelListIssueshelper if preferred.Known limitation (called out for reviewers)
For private repositories, the confidentiality reader set is currently
[owner]rather than the full collaborator list. Fetching collaborators requires a paginated REST call perlist_issuesinvocation; rather than bake that into this PR, I'd like to land a shared visibility/collaborators helper in a follow-up thatget_file_contentsandsearch_issuescan also share. There's aTODO(fides)comment at the call site.Tests
Test_ListIssues_IFC_InsidersModemirrorsTest_GetMe_IFC_InsidersModewith three subtests:result.Meta == nil.integrity=untrusted,confidentiality=["public"].integrity=untrusted,confidentiality=["<owner>"].Existing
Test_ListIssuesGraphQL query strings and mock responses were updated to include the newisPrivatefield.Validation
go test -race ./...— green.gofmt -sclean;go vet ./...clean../script/lintitself fails locally with a pre-existing golangci-lint Go-version mismatch unrelated to this change.)