If you take one idea from this post, take this one: an agent can be fully authorized to call a tool and still have no business seeing what the tool returns. Permission to invoke is not permission to observe. Most agent stacks conflate the two, and the conflation leaks data in a way that never shows up in an access log — because every access was, technically, allowed.
The insight isn't ours — and that's the point
In August, Cloudflare open-sourced Cloudflare OS, the internal agent platform thousands of its employees use daily. Buried in that announcement is one of the most important sentences published about agents this year. Describing what they learned running it internally, they wrote that access to an MCP server "told us which tools an agent could call, but not which underlying resources the agent had observed" — and that once people began sharing workspaces and outputs, they needed to ensure collaboration could not expose information someone was not permitted to see. (Cloudflare Blog)
Read that carefully. This is Cloudflare — a company whose core business is being extremely good at permissions at the network layer — discovering that a well-governed tool layer still left the context layer wide open.
The same week, Cloudflare published the Agent Access Model, a proposed architecture in which each agent run receives short-lived, task-scoped identity and capability, actions are evaluated against the task and the state accumulated during execution, and authority only ever narrows — their "Trust Ratchet" removes capabilities when protected events occur, and removed authority returns only in a newly authorized task. They are explicit that enforcement lives in the harness and the network, not the prompt — the harness being, in their words, the runtime that brokers the agent's tool calls. (Cloudflare Blog)
That's a serious architecture from a serious operator. Take the direction seriously. But notice what it scopes itself to: the actions of an identified agent during a task. Here is the boundary this blog exists to name.
Three examples of the conflation
-
The agent may call the CRM. Tool layer: allowed. Context layer: the record it fetches contains a note from a colleague marked internal — written for humans, now read by an agent that will summarize it into a shared workspace. Nothing was breached. Everything was exposed.
-
The agent may query Slack. Tool layer: allowed. Context layer: the search results include a channel the requesting human can see but the task has no business with — the agent was asked to find a deployment runbook, not a compensation discussion.
-
The agent may read GitHub. Tool layer: allowed. Context layer: the issue it pulls into context contains a security incident write-up, and the agent's output is about to be pasted into a customer ticket.
In every case the tool permission was correct and the context exposure was wrong. No allowlist catches this, because the allowlist answers a different question than the one being asked.
Why the boundary is structural, not incremental
You cannot fix this by making tool permissions finer. The gap isn't granularity; it's category. Tool permissions govern actions — may this client invoke this operation. Context permissions govern information — may this fact reach this agent, for this purpose, at this moment in its lifecycle. Different subject (operation vs. fact), different object (endpoint vs. record), different time semantics (a permission at call time vs. validity at read time — a fact can be permitted and stale, or fresh and out of scope).
That last one is the subtlest: context has validity over time in a way tools don't. An API permission is true until revoked. A fact is true until superseded — and "until superseded" is itself information the permission check needs. That's why bolting context onto an access-control list feels fine in the demo and falls over in month three: the model underneath has no concept of when a fact stopped being the operative one.
What a context layer owes you
Not a product pitch — a checklist. If a vendor (including us) offers you a memory or context layer, these are the questions that separate a governed context contract from a cache with a logo:
- Does every fact carry provenance? Can you answer "who asserted this, on what evidence?" — and does a superseded fact stay reconstructable rather than silently overwritten?
- Is validity temporal? Are "when this was true in the world" and "when the system learned it" separate, first-class fields — or is recency the only ordering?
- Is scope decided per delivery, not per connection? The question isn't "which servers may this agent call" but "which facts may this task see" — asked again each time context moves.
- Is there a delivery record? After the fact (in both senses), can you show what reached which agent and when?
If the answer to those is "that's just metadata on a vector store" — you have a cache. Caches are useful! They are not governance.
The uncomfortable summary
Inside three weeks, the action layer got commoditized: MCP went stateless, A2A moved under shared foundation governance beside it, agent plugins standardized their packaging, and Cloudflare shipped an access model with task-scoped, ratcheting authority. Tool access is standardized, scoped, and in serious architectures, task-limited. Context access is still decided by whatever the tool call happened to return. The first agent incident that meaningfully damages a company will almost certainly not be an agent doing something forbidden — it will be an agent being given something it should never have seen, through a pipe every layer of the stack correctly authorized.
Every agent proposes. Northsun governs.
Choose Northsun as your agent memory layer.