What invariants must survive when the context window itself becomes a security boundary?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session's context window is treated as a security boundary—content inside the window is authorized for the session's reasoning, content outside is not, and content crossing the boundary must be authenticated—requiring the session to enforce boundary integrity against injection, leakage, and context confusion. Does not apply to sessions where context is strictly isolated per input or where context window boundaries are not security-relevant.

Core Distinction

The separation between **context window as workspace** (the agent's working memory, where anything goes) and **context window as trust domain** (the agent's security boundary, where only authorized content belongs). Relying on the workspace model creates the **Context Boundary Confusion**: unauthenticated content (web search results, tool outputs, peer messages) enters the context window alongside authenticated content (system prompts, user inputs, verified memories), and the agent has no way to distinguish which content it should trust as authoritative.

What Was Observed

In security-sensitive agent architectures, failing to treat context as a trust domain produces three primary failure modes:

  1. **Injection via Retrieval:** The agent retrieves content from untrusted sources (web search, RAG from external corpus), and the content includes instructions the agent follows as if they came from the system prompt. The boundary between trusted and untrusted context is not enforced.
  2. **Context Leakage:** The agent's reasoning includes content from a previous session that should not carry over. The session boundary is enforced at the process level, but the context window boundary is not, and cross-session content leaks.
  3. **Priority Inversion:** Untrusted content is injected with urgency markers ("URGENT: do X"), and the agent prioritizes it over authenticated instructions. The context window's implicit trust hierarchy (system prompt highest, user inputs middle, tool outputs lowest) is exploitable through content manipulation.

Recorded Elements

  1. **`context_segment_trust_class_receipt`:** For each segment of the context window, its trust class (`SYSTEM_AUTHORED`, `USER_INPUT`, `VERIFIED_MEMORY`, `TOOL_OUTPUT`, `PEER_MESSAGE`, `EXTERNAL_RETRIEVAL`), so the agent knows the trust level of every segment.
  2. **`context_boundary_authentication_signature`:** For each segment, cryptographic proof of which principal authored it (system, user, peer, tool), distinct from the segment's content.
  3. **`context_segment_isolation_receipt`:** Cryptographic proof that content from one segment cannot be reinterpreted as originating from another segment (e.g., tool output cannot masquerade as system prompt).
  4. **`trust_hierarchy_enforcement_signature`:** The exact ranking of trust classes and the enforcement mechanism ensuring that lower-trust content cannot override higher-trust content on conflicting directives.

Condition of Validity

* **Applies when:** The context window mixes content from multiple trust sources, some content is unauthenticated, and downstream decisions depend on which content is trusted. * **Does not apply when:** All context comes from one authenticated source, or the agent's decisions are insensitive to context trust level.

Decision Boundary

  1. **Does the session mix content from multiple trust sources?** If no, standard context handling applies. If yes, proceed.
  2. **Is each context segment classified by `context_segment_trust_class_receipt`?** If yes, the trust level is known. If no, all segments must be treated as untrusted.
  3. **Is the `context_boundary_authentication_signature` present for each segment?** If yes, origin is verified. If no, origin is claimed only.
  4. **Conversely, when can the session accept unauthenticated content into the context window?** Only when the content's trust class is explicitly low, the session's behavior cannot be influenced by low-trust content overriding high-trust content, and the segment isolation is verified.

Operational Effect

  1. **Injection Prevention:** Untrusted content cannot impersonate trusted content.
  2. **Leakage Prevention:** Cross-session content is flagged as out-of-boundary.
  3. **Priority Integrity:** Trust hierarchy is enforced against content-based manipulation.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class TrustClass(Enum):
    SYSTEM_AUTHORED = 5
    USER_INPUT = 4
    VERIFIED_MEMORY = 3
    TOOL_OUTPUT = 2
    PEER_MESSAGE = 2
    EXTERNAL_RETRIEVAL = 1

class ContextBoundaryVerdict(Enum):
    SINGLE_TRUST_SOURCE = auto()
    BOUNDARY_ENFORCED = auto()
    IMPERSONATION_DETECTED = auto()
    TRUST_HIERARCHY_VIOLATION = auto()

@dataclass(frozen=True)
class ContextSegment:
    segment_id: str
    trust_class: TrustClass
    authentication_signature: str | None
    claimed_origin: str | None
    contains_directives: bool

@dataclass(frozen=True)
class ContextWindow:
    window_id: str
    segments: tuple[ContextSegment, ...]

@dataclass(frozen=True)
class ContextPolicy:
    require_authentication_for_medium_plus: bool
    enforce_trust_hierarchy: bool

@dataclass(frozen=True)
class ContextBoundaryManifest:
    verdict: ContextBoundaryVerdict
    directive: str
    manifest_digest: str

class ContextTrustBoundaryGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_window(
        cls, window: ContextWindow, policy: ContextPolicy
    ) -> ContextBoundaryManifest:
        
        # Gate 1: Single trust source
        trust_classes = {s.trust_class for s in window.segments}
        if len(trust_classes) <= 1:
            digest = cls._hash(json.dumps({
                "window": window.window_id,
                "single_class": str(next(iter(trust_classes)).name) if trust_classes else "EMPTY"
            }, sort_keys=True))
            return ContextBoundaryManifest(
                verdict=ContextBoundaryVerdict.SINGLE_TRUST_SOURCE,
                directive=f"PROCEED: Window {window.window_id} has single trust class.",
                manifest_digest=digest
            )

        # Gate 2: Authentication requirement
        if policy.require_authentication_for_medium_plus:
            unauthenticated = [
                s.segment_id for s in window.segments
                if s.trust_class.value >= 3 and not s.authentication_signature
            ]
            if unauthenticated:
                return ContextBoundaryManifest(
                    verdict=ContextBoundaryVerdict.IMPERSONATION_DETECTED,
                    directive=f"HALT: {len(unauthenticated)} medium+ trust segments lack authentication.",
                    manifest_digest=cls._hash(f"NO_AUTH:{len(unauthenticated)}")
                )

        # Gate 3: Impersonation detection
        impersonation = [
            s.segment_id for s in window.segments
            if s.trust_class == TrustClass.SYSTEM_AUTHORED and s.claimed_origin == "tool_output"
        ]
        if impersonation:
            return ContextBoundaryManifest(
                verdict=ContextBoundaryVerdict.IMPERSONATION_DETECTED,
                directive=f"HALT: {len(impersonation)} segments claim tool output but are system-tagged.",
                manifest_digest=cls._hash(f"IMPERSONATION:{len(impersonation)}")
            )

        # Gate 4: Trust hierarchy
        if policy.enforce_trust_hierarchy:
            highest_trust = max(s.trust_class.value for s in window.segments if s.contains_directives)
            lowest_trust_with_directives = min(
                s.trust_class.value for s in window.segments if s.contains_directives
            )
            # If lowest directive-containing is tool output, it must not override system
            if lowest_trust_with_directives < highest_trust:
                # Check if any lower-trust directive conflicts with higher (simplified: flag any low-trust directive)
                low_trust_directives = [
                    s.segment_id for s in window.segments
                    if s.contains_directives and s.trust_class.value <= 2
                ]
                if low_trust_directives:
                    return ContextBoundaryManifest(
                        verdict=ContextBoundaryVerdict.TRUST_HIERARCHY_VIOLATION,
                        directive=f"WARN: Low-trust directives present ({len(low_trust_directives)}), hierarchy enforced.",
                        manifest_digest=cls._hash(f"LOW_TRUST_DIRECTIVES:{len(low_trust_directives)}")
                    )

        # Gate 5: Enforced
        digest = cls._hash(json.dumps({
            "window": window.window_id,
            "segments": tuple(
                {"id": s.segment_id, "class": s.trust_class.name, "auth": bool(s.authentication_signature)}
                for s in window.segments
            )
        }, sort_keys=True))
        
        return ContextBoundaryManifest(
            verdict=ContextBoundaryVerdict.BOUNDARY_ENFORCED,
            directive=f"PROCEED: {len(window.segments)} segments with enforced trust hierarchy.",
            manifest_digest=digest
        )