Repository navigation
Description
Problem
ContextProvider instances are trusted framework plugins, but there is no first-class contract for attaching integrity and confidentiality labels to the messages they add to SessionContext. This makes it difficult for providers that wrap retrieved or remembered external data to integrate consistently with SecureAgentConfig without routing the data through a tool or implementing custom preprocessing.
The existing context-provider trust model remains valid: provider code itself is trusted and has access to the conversation and session state. The missing capability is a standard way for a trusted provider to describe the provenance and restrictions of the data it injects.
Use Case and Evidence
Memory, retrieval, and search providers may return a mixture of locally trusted records and externally sourced content. Applications using FIDES need to express, at message or content-item granularity, that provider-injected data is untrusted, private, or identity-scoped so that the cumulative context label and downstream tool policy reflect those restrictions.
Today providers can add ordinary Message objects, and SessionContext.extend_messages(...) adds source attribution, but SecureAgentConfig does not define an enforcement contract for provider-supplied labels. LabeledMessage exists, but it is not integrated into the context-provider assembly pipeline.
Desired Outcome
Define an opt-in, first-class provider-message labeling contract that allows trusted context providers to attach restriction-only integrity and confidentiality information. SecureAgentConfig should consume the labels after provider context has been assembled, preserve them through supported history and transport paths, and update the cumulative FIDES context label consistently.
The design should explicitly define defaults for unlabeled provider messages, how trusted local configuration may establish authority, and how caller- or remote-supplied labels are prevented from reducing restrictions.
Alternatives Considered
- Continue treating all context providers as trusted and require each provider/application to manually sanitize or hide retrieved data. This remains the current documented model but does not provide consistent FIDES propagation.
- Route provider data through FIDES-labeled tools. This works but changes provider architecture and can add unnecessary model/tool turns.
- Use
LabeledMessagedirectly. This lacks an integrated post-provider enforcement point and clear authenticity, serialization, and compatibility rules.
Proposed Direction
- Add a provider-facing message/content labeling API, likely using the existing
ContentLabelvocabulary. - Apply labels only after all providers have run, before the first model call.
- Treat labels carried by ordinary messages as restriction-only unless trusted local configuration establishes them as authoritative.
- Decide and document the compatibility default for unlabeled provider messages.
- Preserve labels across history providers and supported transports.
- Add coverage for mixed-trust provider output, forged label downgrades, provider ordering, streaming/non-streaming parity, and history restoration.
Scope and Non-Goals
In scope: provider-injected message/content labels and their interaction with SecureAgentConfig, history, and transports.
Non-goals: sandboxing untrusted provider code, changing the documented rule that ContextProvider implementations are trusted plugins, automatic semantic classification of retrieved text, or exposing hidden FIDES values to providers.
Language
Python
Contribution Intent
I can help with implementation or testing
Acknowledgements
- I searched existing issues and did not find a duplicate.
- I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
eavanvalkenburg commentedon Oct 26, 2026
/plan Design an opt-in, restriction-only provenance-label seam for non-history context-provider messages. Preserve the trusted-plugin boundary and restored history labels, prevent label weakening, and define persistence/transport behavior. Keep this follow-up separate from #9652; do not treat trusted Python providers as sandboxed untrusted code.
eavanvalkenburg commentedon Nov 5, 2026
/plan Design an opt-in, restriction-only provenance-label seam for non-history context-provider messages. Preserve the trusted-plugin boundary and restored history labels, prevent label weakening, and define persistence/transport behavior. Keep this follow-up separate from #9652; do not treat trusted Python providers as sandboxed untrusted code.
github-actions commentedon Nov 5, 2026
Summary
You want a design for an opt-in way for trusted context providers (memory, retrieval, search) to say "this injected message is untrusted / private / identity-scoped", so FIDES (the framework's integrity/confidentiality label system) updates its running context label. Labels may only make things more restrictive. This is kept separate from #9652. Providers stay trusted plugins; this is not sandboxing. This is Python-only. I did not run code and did not look at open PRs.
What the code does today
SessionContext.extend_messagescopies each message and only adds an_attributionmarker (source_id,source_type, optionalorigin_session_ids). See_sessions.py.SecureAgentConfigis itself a context provider and itsbefore_runonly adds tools, instructions and middleware (security.py). It never reads other providers' messages.Agentrunsbefore_runfor providers in list order (_agents.py). A provider listed afterSecureAgentConfigadds messages it can't see. So there is currently no "after all providers" point inside this pipeline._update_context_labelin the tool middleware, usingcombine_labels(most-restrictive wins). The existing tool rule is the model to copy: embeddedsecurity_labelvalues can only restrict a fallback, and full labels are accepted only from identity-stamped framework producers (_AUTHORITATIVE_SECURITY_LABEL).LabeledMessageexists but is unused by the provider pipeline. Persisted/restored history messages carryadditional_properties;_split_service_call_messagesre-identifies provider messages via_attributionwhen splitting service-call messages.Recommendation
Code changes are warranted, kept small, as an opt-in, experimental (FIDES feature) addition, plus documentation of the trust model. Existing workarounds (routing data through labeled tools, manual sanitizing) work but force extra tool turns and don't update the context label consistently, so they are not an adequate general answer. Because this touches persistence and transports, I suggest an ADR first (per
docs/decisions/) and maintainer agreement before coding, as you noted.Proposed plan
Label carrier (restriction-only). Let providers pass an optional label through
extend_messages(..., label=ContentLabel), stored under a reserved key inadditional_properties(e.g.security_label, same name the tool path uses). No new trust: any value there is treated as a claim that can only restrict.Single enforcement point after all providers. Apply labels in one place that runs after the provider loop finishes and before the first model call (in
Agent's context assembly, or a chat middleware thatSecureAgentConfigregisters). Don't rely onSecureAgentConfig.before_runordering. Only active whenSecureAgentConfigis configured; otherwise behavior is unchanged.No weakening. Effective label for a message =
combine_labels(default_for_unlabeled, claimed_label)per message/content item. Never replace a stricter baseline with a weaker claim. Confidentiality principals (identity scope) follow the existingPRINCIPAL_METADATA_KEYhandling.Defaults for unlabeled provider messages. Decision needed: keep today's behavior (no change to cumulative label) as the compatible default, with an opt-in config such as
unlabeled_provider_integrity=UNTRUSTEDand a per-source_idmapping set by trusted local configuration (this is the only way to establish a stronger-than-default claim such as "trusted"). Default must be fail-compatible; I suggest not raising trust from message data ever.Cumulative label. Fold each effective label into the session's context label once, at assembly time, and persist it in the existing security session state, so streaming and non-streaming runs behave identically.
Persistence and transport.
source_ids).context_labelstate).Docs. State clearly that providers remain trusted code, that labels are provenance metadata not a sandbox, and that provider-injected hidden values aren't exposed to providers.
Tests
SecureAgentConfig.Done when
Labeled provider messages raise the context label before the first model call, no input can lower it, and unconfigured agents behave exactly as today.
Open questions I'd like settled in the ADR
No changes have been made; this is a proposal.
eavanvalkenburg commentedon Nov 13, 2026
Fixed in #9876