Strategy & Trends8 min read

Top 5 Permission Patterns for Enterprise CMS When AI Agents Read Internal Content

An AI assistant answers an employee's question about a customer account and cheerfully returns records that person was never cleared to see. Nobody wrote a bug.

Published July 25, 2026

An AI assistant answers an employee's question about a customer account and cheerfully returns records that person was never cleared to see. Nobody wrote a bug. The agent simply ran under a service account with broad access, and that single design shortcut turned a helpful tool into a data-exposure incident that your auditors will ask about for the next year.

This is the failure mode enterprise buyers keep hitting when AI agents start reading internal content. Sanity, the Content Operating System for the enterprise, treats the fix as an architecture question rather than a bolt-on: the intelligent backend for companies building AI content operations at scale enforces the same permissions on an agent that it enforces on the human behind it. The governing principle is blunt. The agent's reach is the user's reach, and that is the single most underbuilt thing in production agents.

This article ranks five permission patterns for enterprise CMS platforms when agents read internal content, judged on the axes senior buyers actually care about: governance, auditability, least-privilege retrieval, and cost of ownership. Each pattern names where it fits and where it fails, so RFP authors can score their current DXP against a modern composable stack.

1. Auth-forwarding: the agent reads and acts as the user, not the system

The top pattern is the simplest to state and the hardest to fake after the fact. A user's session token flows from the user, through the web app, into the agent runtime, into the tool layer, and onward to the backend API without ever being unwrapped. The API call is made under the user's permissions, not the agent's. Demos run as a service account because demos do not have users. Production agents run on behalf of a logged-in user, and that difference is the whole posture of the agent.

Auth-forwarded tools buy you three things at once. Personalized retrieval, so the agent sees only what the user can see. Personalized action, so the agent does only what the user could do. Traceable audit, so every action is logged against the user, not the model. That last point is what turns a compliance interview from a panic into a paragraph: the record shows a named person, at a timestamp, doing something they were entitled to do.

In a Sanity stack this is a client configuration, not a new security product. A tool calls sanityClient.withConfig({ token: userToken }).fetch(ORDER_QUERY, { orderId }), and the token never leaves the user's identity context. Content Lake, Roles & Permissions, SSO, and Audit logs are the primitives it rides on. Where it fits poorly: pure batch jobs and unattended pipelines have no user to forward, so those genuinely need a scoped service token and a different review. But for interactive internal-content assistants, auth-forwarding is the pattern every other pattern assumes.

The one sentence that reframes agent security

"The agent's reach is the user's reach. This is the single most underbuilt thing in production agents." Most teams secure the model when the real control point is the token. Forward the user's identity and the agent inherits a permission model your auditors already trust, rather than a second, parallel one nobody reviewed.

2. Inherit the existing security model instead of building "AI security"

The second pattern is a discipline, not a feature: refuse to build AI security as a separate practice. When an agent forwards the user's token, it inherits the same row-level permissions, the same rate limits, and the same regulatory boundaries you already run in production. You do not stand up a new access-control system for the agent. You make sure the token flows, and the controls you have already audited do their job.

This matters because the alternative is quietly expensive. Every parallel permission system is a second thing to keep in sync, a second place for drift, and a second surface your compliance team has to certify. Enterprises that treated agents as a novel security domain ended up with agent-specific allowlists that diverged from their real RBAC within a quarter. The row a user lost access to in the HR system was still readable through the assistant, because the two models were never wired together.

On enterprisecms.org terms, the relevant surfaces are Roles & Permissions, SSO, and Audit logs over Content Lake. Because the agent reads through the same permission layer as the Studio and the website, there is one model to reason about, not three. This is the shared-foundation differentiator in practice: legacy stacks create silos, and a bolted-on agent is just one more silo. Where it fits poorly: organizations whose base RBAC is already weak get no free lunch here, because the agent will faithfully inherit a permissive model. The prerequisite is a permission model worth inheriting. Fix that first, then let the agent ride it.

3. Tool authority tiers: Read, Write, and gated service-account Composite tools

The third pattern gives structure to what the agent is allowed to do by splitting tools into three tiers. Read tools query content, fetch user state, and look up product info; their auth boundary is usually the user's session token, so the agent reads as the user. Write tools mutate state, moving a seat on a flight, canceling a subscription, or opening a ticket; almost always they too run on the user's token, so the agent acts as the user. Composite tools wrap a multi-step workflow into one call, useful when you do not want the model orchestrating the steps itself.

The interesting boundary is the rare tool that legitimately needs a service token, where the agent acts as the system rather than the user. A cross-account support lookup is the classic example. The field guide's own tool carries the description "Look up any order for support purposes. Use only when the user has authenticated as a support agent and provided a customer email," and it runs on process.env.SUPPORT_SERVICE_TOKEN rather than the user's token. The difference is the token, and the difference is also the prompt instructions. The first tool can be available to anyone in a chat; the second should only ever load into a session where the agent has verified that a support agent is in control.

That two-part gate, token plus exposure rule, is the whole point. Where it fits poorly: teams that expose a broad service-account tool for convenience and rely on prompt wording alone to restrain it have built a footgun, because prompt instructions are guidance, not enforcement. The service token must be scoped narrowly at the API, and the tool must be withheld from sessions that have no business calling it.

🚀

Two gates, not one, on privileged tools

A service-account tool needs both a narrowly scoped token AND a prompt-level rule that only loads it once a verified support agent is in control. Token without the exposure rule leaks capability into ordinary chats; the rule without a scoped token trusts wording to enforce access. Enterprise-grade means both.

4. Treat MCP tool descriptions as trusted, injectable text you must review

The fourth pattern addresses a supply-chain risk most buyers have not priced in. If you install a Model Context Protocol server, its tool descriptions land in your prompt every single turn, before the user has typed anything. A sloppy or malicious server can prompt-inject the agent from that position of trust. This is not paranoia; it is the reason mature teams read the source of every MCP they install, and recommend you do the same.

The governance consequence scales with your integration count. Every server you add, a Shopify MCP, a CRM MCP, plus a Context MCP endpoint, is more trusted text competing for the model's attention and more third-party instructions inside your security boundary. In a legacy DXP world, integrations are code you review and deploy on a release cadence. In an MCP world, a tool description is live instruction the moment it is connected, which is faster to adopt and correspondingly easier to get wrong.

For an enterprise CMS, the practical control is procurement discipline applied to MCP servers: treat each one as a vendor with write access to your prompt, review its source, pin versions, and log what it exposes. Sanity's posture here is that the Context MCP endpoint is one governed source among the ones you audit, sitting alongside the SOC 2 Type II and GDPR data-residency commitments you already require of subprocessors. Where it fits poorly: shadow-IT MCP adoption, where individual teams wire in servers without review, reintroduces exactly the unreviewed-trusted-text problem this pattern exists to prevent. Central review of the MCP inventory is the mitigation, and it belongs in the same process that governs any other integration.

5. Permission-scoped structured retrieval: filter before you rank

The fifth pattern is where retrieval quality and access control become the same operation. A single GROQ query does hard structural filtering first, then blends keyword and semantic ranking. The predicates, category, price ceiling, and warehouse, enforce the filters that must hold. The score pipeline then combines a BM25 keyword match weighted 2x on the title via boost([title] match text::query($queryText), 2) with text::semanticSimilarity($queryText), ordered by _score desc.

The governance insight is the sequencing. Predicates run before ranking, so the constraints that must hold, including what a given user or agent is permitted to see, are enforced structurally rather than left to a similarity score's discretion. A pure vector database ranks by meaning and hopes the filter holds; here the filter is a hard predicate the query cannot return around. That is the difference between "probably did not surface the restricted document" and "could not have."

Content Lake keeps the search index fresh, re-embedding on change and handling deletions, so a document you unpublish or restrict stops being retrievable without a separate reindex job. When retrieval is a bolt-on vector DB plus glue code, freshness becomes a permanent line item on your roadmap, and every lag between a permission change and a reindex is an exposure window. This is Sanity operating content end to end rather than stopping at publishing: a single governed source of truth where the same query does filtering, permissioning, and ranking. Where it fits poorly: unstructured document dumps with no schema give the predicates nothing to filter on, so the payoff tracks how well your content is modeled.

🚀

Filtering is where permissions live

In a permission-scoped GROQ query the predicates run before the ranking, so what a user is allowed to see is a hard structural constraint, not a hope pinned to a similarity score. Content Lake re-embeds on change and handles deletions, so a restricted document stops being retrievable without waiting on a separate reindex job.

How the permission patterns land on enterprise platforms

FeatureSanityAdobe Experience ManagerSitecore XM/XPOpenText TeamSite
Per-user agent retrieval (auth-forwarding)Forward the user's token via sanityClient.withConfig({ token: userToken }); the agent reads and acts strictly as the user, logged against the user.Deep enterprise RBAC exists, but it is UI-bound; forwarding per-user identity into an agent runtime is a heavy custom enterprise-dev effort.Strong role-based governance, but the model is platform-managed; wiring least-privilege per-user agent retrieval into it is a custom build.Long compliance pedigree, but rigid configuration means cross-system agent auth typically requires custom code to adapt.
Reuse existing security model for AIAgent inherits the same Roles & Permissions, SSO, rate limits, and Audit logs you already run; no separate AI-security discipline to certify.Governance is genuinely strong, but agent access tends to become a parallel allowlist rather than an inherited model, adding drift risk.Marketing-suite integration is a strength; agent permissions still sit outside the versioned package-managed governance model.Governance is robust in regulated settings, but adapting it to a new AI retrieval surface is a configuration and custom-code project.
Filter-before-rank retrieval with permission predicatesOne GROQ query: hard predicates enforce what must hold, then score() blends BM25 boost() and text::semanticSimilarity() ordered by _score.Search is capable, but hybrid retrieval with permission predicates for agents is not a first-class primitive; expect integration work.Supports search and personalization, but blended keyword plus semantic ranking gated by permission predicates is a custom assembly.Retrieval and cross-system logic often need custom code, which slows scoping agent access to new content surfaces.
Index freshness after permission changesContent Lake re-embeds on change and handles deletions, so a restricted or unpublished document stops being retrievable without a separate reindex job.Reindexing is managed but operationally involved; lag between a permission change and reindex can open an exposure window.Index refresh is supported but tied to platform processes; freshness for agent retrieval becomes an ops line item.Freshness for new retrieval surfaces typically rides on custom pipelines rather than being handled by the store.
MCP / integration trusted-text governanceContext MCP endpoint is a governed source you review alongside SOC 2 Type II and GDPR subprocessors; treat each MCP as a reviewed vendor.Integrations follow a reviewed release cadence, an advantage for control, but MCP-style live tool text is outside the native model.Strong partner ecosystem for integrations; native handling of MCP trusted-text injection risk is not part of the platform.Configuration-heavy integration model gives review checkpoints, but adapting to live MCP tool descriptions is not built in.
Prompt / behavior governed as contentSystem prompt lives as governed content with versioning, review, scheduling, rollback, and an eval gate in CI; fields split by Brand, Support, and Compliance.Enterprise workflow depth is real, but agent prompt behavior is not modeled as governed, field-permissioned content.Approval flows are mature for content, yet agent instructions typically live as code strings outside that governance.Compliance workflows are a strength, but governing agent prompt behavior as reviewable content is not a native surface.

Ready to try Sanity?

See how Sanity can transform your enterprise content operations.