Skip to content

Add ifc label for get_me tool#2432

Open
JoannaaKL wants to merge 4 commits intomainfrom
add-get_me-metadata
Open

Add ifc label for get_me tool#2432
JoannaaKL wants to merge 4 commits intomainfrom
add-get_me-metadata

Conversation

@JoannaaKL
Copy link
Copy Markdown
Contributor

@JoannaaKL JoannaaKL commented May 6, 2026

Summary

Adds Information Flow Control (IFC) labels to the get_me tool response, gated behind insiders mode. This is groundwork for FIDES integration — labelling tool outputs with integrity and confidentiality metadata so downstream consumers can enforce information flow policies.

Why

FIDES requires each tool's output to carry a security label describing its integrity (trusted vs untrusted) and confidentiality (who can read it). The get_me tool is the first to get this treatment. Labels are returned in CallToolResult.Meta["ifc"] only when the server runs in insiders/experimental mode, keeping the stable API surface unchanged.

What changed

  • Added pkg/ifc/ package with lattice types for IFC labels:
    • lattice.go — core lattice interface, confidentiality/integrity enums, product lattice, inverse lattice
    • readers_lattice.go — powerset lattice over reader sets, ReadersSecurityLabel with JSON marshaling
    • labelling_engine_readers.goLabelGetMe() returning a public-trusted label
  • get_me handler in context_tools.go sets result.Meta["ifc"] when InsidersMode is enabled
  • Added Test_GetMe_IFC_InsidersMode verifying the label is present/absent based on insiders flag

MCP impact

  • Tool schema or behavior changed
    • get_me result now includes _meta.ifc with {"integrity": "high", "confidentiality": ["public"]} in insiders mode only. No change to tool definition schema or stable behavior.

Security / limits

  • No security or limits impact

Tool renaming

  • I am not renaming tools as part of this PR

Note: if you are renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Not needed

@JoannaaKL JoannaaKL changed the title Add ifc labels Add ifc label for get_me tool May 6, 2026
@JoannaaKL JoannaaKL marked this pull request as ready for review May 6, 2026 14:01
@JoannaaKL JoannaaKL requested a review from a team as a code owner May 6, 2026 14:01
Copilot AI review requested due to automatic review settings May 6, 2026 14:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an IFC (Information Flow Control) label to the get_me tool’s call result metadata when InsidersMode is enabled, backed by a new pkg/ifc package implementing lattice structures and reader-based confidentiality labels.

Changes:

  • Introduces a new pkg/ifc package with core lattice types, inverse lattice support, and a reader-set powerset lattice used to construct IFC labels.
  • Adds a LabelGetMe() helper that returns a “public + trusted” readers-based security label.
  • Updates get_me to include the IFC label in CallToolResult.Meta in insiders mode, and adds a focused test to validate meta behavior.
Show a summary per file
File Description
pkg/ifc/readers_lattice.go Adds reader-set powerset lattice and ReadersSecurityLabel (incl. JSON serialization) for reader-based confidentiality.
pkg/ifc/lattice.go Adds generic lattice interfaces and basic confidentiality/integrity lattice implementations plus product/inverse lattice helpers.
pkg/ifc/labelling_engine_readers.go Adds LabelGetMe() helper for the get_me tool’s IFC label.
pkg/github/context_tools.go Conditionally attaches the IFC label to get_me call result metadata when insiders mode is enabled.
pkg/github/context_tools_test.go Adds tests asserting get_me includes/omits IFC meta depending on insiders mode.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 7

Comment thread pkg/ifc/readers_lattice.go Outdated
Comment on lines +194 to +203
func (p *PowersetLattice[T]) Leq(other *PowersetLattice[T]) bool {
return p.subset.IsSubset(other.subset)
}

func (p *PowersetLattice[T]) Join(other *PowersetLattice[T]) *PowersetLattice[T] {
return &PowersetLattice[T]{
subset: p.subset.Union(other.subset),
universe: p.universe,
}
}
Comment on lines +312 to +321
finiteSet, ok := l.Confidentiality.Inner.subset.(*FiniteReaderSet[string])
if !ok {
return nil
}

readers := make([]string, 0, len(finiteSet.members))
for reader := range finiteSet.members {
readers = append(readers, reader)
}
return readers
Comment thread pkg/ifc/readers_lattice.go Outdated
Comment thread pkg/ifc/readers_lattice.go Outdated
Comment on lines +107 to +113
result := MarshalledTextResult(minimalUser)
if deps.GetFlags(ctx).InsidersMode {
result.Meta = mcp.Meta{
"ifc": ifc.LabelGetMe(),
}
}
return result, nil, nil
Comment on lines +156 to +165
// PowersetLattice is a powerset lattice that can represent either a finite set or the universal set.
// subset and universe are represented using the ReaderSet interface.
// T must be comparable to be used as a map key.
type PowersetLattice[T comparable] struct {
subset ReaderSet[T]
universe ReaderSet[T]
}

// NewPowersetLattice constructs a PowersetLattice, checking that
// subset ⊆ universe.
…tion, and tests

- Fix grammar in ReadersSecurityLabelFromDict godoc
- Sort GetReaders and FiniteReaderSet.String output for determinism
- Fix godoc example to use UniversalReaders for public label
- Panic on unsupported ReaderSet types in Union/Intersection/IsSubset
- Add universe mismatch validation in PowersetLattice Join/Meet/Leq
- Add comprehensive unit tests for pkg/ifc (lattice laws, serialization, panics)
result := MarshalledTextResult(minimalUser)
if deps.GetFlags(ctx).InsidersMode {
result.Meta = mcp.Meta{
"ifc": ifc.LabelGetMe(),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Heads-up: the wire format here is _meta.ifc with {integrity: "high"|"low", confidentiality: ["public"|...]}, but original spec _meta.ifc_label with {integrity: "trusted"|"untrusted", confidentiality: {readers: [...]}}. I'm fine matching your shape on the cli side), but should we update the issues to lock in ifc + high/low + flat list as the contract before we annotate more tools?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also this assigns result.Meta outright. If MarshalledTextResult ever starts populating Meta (or another decorator runs before this), we'd silently clobber it. cheaper to be defensive now and merge into an existing map than to debug later, something like if result.Meta == nil { result.Meta = mcp.Meta{} }; result.Meta["ifc"] = ifc.LabelGetMe(). wdyt?

package ifc

// LabelGetMe returns a label for get_me: trusted, universal readers.
func LabelGetMe() ReadersSecurityLabel {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

handler-level test in context_tools_test.go covers the integration nicely. Worth a one-liner unit test in pkg/ifc too. assert.True(t, LabelGetMe().IsHighIntegrity() && LabelGetMe().IsPublicConfidentiality())

I think it is very cheap to add now, and as labelling_engine_readers.go grows (LabelListIssues, LabelGetFileContents, …) we'll have a single place tracking per-tool label correctness without spinning up the full handler.

Copy link
Copy Markdown
Member

@gokhanarkan gokhanarkan left a comment

Choose a reason for hiding this comment

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

Some comments to make sure we align on the spec!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants