Skip to content

01. The data-access problem with agents

Before designing the discipline, we feel why agents change the data-access problem. The data-access patterns the industry built for ordinary APIs over thirty years do most of what is needed; the LLM in the middle changes enough to require a different posture.


A platform engineer at a Bengaluru fintech runs an audit of a support agent. The agent is rated highly by users and produces excellent answers. The audit asks one question: of all the customer accounts the agent has touched in the past month, how many were not the account belonging to the user the agent was helping? The answer surprises everyone: 1,247 cases out of 312,000 conversations. Each case is small — a single field, a single account number, a single sentence — but the rate is real. The agent was not hacked. The model was not jailbroken. The agent ran with a credential broad enough to read any account, and the model occasionally reached for the wrong record when the user's question was ambiguous.

This is not a model failure or a security failure in the classic sense. It is a data-access governance failure: the agent's authority was wider than its operation required, and the model's behaviour under ambiguity occasionally exercised the unnecessary breadth. The standard API discipline (role-based access control, OAuth scopes, audit logs) was in place. The agent was still leaking.

This chapter is the reframe that explains why.


Why ordinary access controls are not enough

Three properties of agent calls differ from ordinary API calls in ways that matter for data access.

1. The instruction is in natural language

An ordinary API client passes structured arguments — GET /accounts/12345. The client is code; the request is unambiguous. An agent's tool call is constructed by an LLM from natural-language input. The LLM interprets what the user meant and chooses arguments. Sometimes the interpretation is wrong; the structured call is well-formed but targets the wrong record. The structured access control sees a valid call and lets it through. The data access governance has to enforce whether this specific call was authorised — not just whether the credential could in principle make this call.

2. The credential is reused across many intents

An ordinary API client gets a credential for a specific purpose: read its own user's profile, write to its own user's data. The credential's scope matches the client's purpose. An agent's credential is one credential serving many user intents within a session. A single tool call's credential authorises every read the agent might do; the agent may do thirty reads per conversation across thirty different intents. The scope-to-intent matching that ordinary clients get for free, agents need to build per-call.

3. The data the model sees has scope of its own

In an ordinary API call, the response goes to the caller. The model is different — the response enters the LLM's context window, where it influences subsequent decisions, may be paraphrased into responses to users, and may be retained in conversation memory. Data that touches the context is, for some practical purposes, now part of every subsequent generation in that conversation. The access governance has to think about what enters the model, not just what is returned to the user.

These three properties compound. The natural-language instruction means the agent occasionally targets the wrong record; the broad credential means the data layer does not refuse; the context-window persistence means once the wrong data is in, it shapes everything downstream.


The reframe

Pin this sentence:

The model is not the security boundary. The data layer is.

The boundary the platform can defend is the boundary at which data is fetched. Above that boundary, the model can be confused, manipulated, or wrong; below it, the data layer's enforcement is what bounds the worst case. Most discipline in this module is about putting the right enforcement at that boundary.

Two corollaries:

Per-call enforcement, not per-credential. A credential that could read a million records does not mean a specific call should. The data layer needs to enforce the per-call scope, not assume the credential's scope is the right answer.

Defence in depth at the data layer. The agent's prompt may be well-designed; the model may be careful; the tool wrapper may validate. Each layer is helpful. None alone is sufficient. The data layer is the floor below which the system cannot fall.


What the chapter-opening case shows

The 1,247 leaks were not the agent failing dramatically. They were small slips — a wrong field, a wrong record, a wrong account — each individually plausible, in aggregate a real problem. Three patterns produced them:

  • Ambiguous user input — the user said "my last order" without specifying which order; the agent picked one, sometimes wrong.
  • Coreference drift — the conversation had referenced two accounts; the agent confused which was "current."
  • Tool argument generation — the LLM produced an account number that looked plausible but was for a different account.

A tighter prompt would help. A better model would help. A more careful tool description would help. None would fix the underlying issue: the agent could reach 312,000 accounts when it should have been able to reach 1 — the user's own account. The data layer's posture was wrong. With per-call scope binding the active user's account, all 1,247 slips would have produced refusals, not leaks.


What ordinary API discipline gets right

To stay calibrated: the ordinary API access discipline is mostly correct and the agent platform should adopt it. Specifically:

  • Authentication and identity. Every call carries an identity. Standard.
  • Role-based access control. Roles bound the set of operations a credential can perform. Standard.
  • OAuth-style scopes. Scopes narrow credentials by capability. Standard.
  • Audit logs. Every access is logged. Standard, though chapter 07 will deepen what to capture for agents.
  • Encryption at rest and in transit. Standard.

What the agent platform adds on top of these:

  • Per-call scope resolution that narrows credentials to the operation's data scope, not just its capability scope (chapter 04).
  • Purpose binding that names why the call is happening, with the data layer recognising purposes (chapter 03).
  • PII-aware audit for the context window, not just for the response (chapter 07).
  • Context-aware retention that recognises data in a conversation may persist across many calls (chapter 06).
  • Leak detection tuned for agents — anomaly patterns specific to agent behaviour (chapter 08).

The discipline is the same shape as the API discipline; it sits one layer deeper.


The cost of getting this wrong

Three categories of cost.

Regulatory. GDPR, the DPDP Act, HIPAA, sectoral rules — most data-protection regimes assume that data access is purposeful. An agent reading the wrong patient's record is an unauthorised disclosure under most of them. The fines and contractual penalties are real.

Reputational. The 1,247-case incident, if it surfaced publicly, would be a "AI leaks customer data" headline. The model did not leak; the access posture did. The distinction is lost on press.

Operational. Each leak is a notification obligation, an investigation, sometimes a customer-impact resolution. Even if the leak is small per case, the per-case operational cost is large.

A platform that processes 312,000 conversations per month and has the chapter-opening leak rate is producing several thousand notification events per year if every leak is properly detected and reported. The cost of not having per-call scope and the cost of having the consequences of unmanaged access are both large.


Where the discipline lives

This module's discipline is implemented in three layers, working together.

The data layer itself. The storage system (database, vector store, document store) enforces the per-call scope at the deepest layer. Even if every layer above it is bypassed, the data layer refuses out-of-scope access.

The access mediator. A service or library that sits between the agent's tool wrappers and the data layer, resolving scope per call, applying PII filters, emitting audit. Often part of the tool boundary (module 19) or part of the model gateway (02_ai_infrastructure/01).

The agent runtime. The agent's tool wrappers and prompt design make correct behaviour possible — clear tool descriptions, narrow tool arguments, structured user-intent disambiguation. The runtime is not the security boundary, but it reduces the load the lower boundaries carry.

The chapters of this module move from policy (what the discipline says) to implementation (where each policy lives), with cross-references to the modules above.


What this module does not solve

  • Prompt injection. A clever attacker may convince the agent to act differently. Module 01_prompt_injection_security covers this; this module bounds the worst case once the agent is acting.
  • Malicious insiders. A human with valid credentials to query the data is outside the agent's access path. Their threat model is general data-access governance, not specifically agent-related.
  • Compromised infrastructure. If the data store is compromised at the storage layer, all of this discipline is undermined. That is general security; the agent platform inherits it from the data platform.
  • Bad data. Wrong, stale, or fabricated data in the source is not a governance issue; this discipline ensures it is accessed correctly, not that it is correct.

The discipline is precise about its scope: governing which data the agent can reach, for what purpose, with what audit. It is one layer of defence; it is the load-bearing layer for the agent-specific failures.


How to recognise the missing-discipline pattern in the wild

Walk into an agent platform; ask these questions. Three or more "no" answers means the discipline is missing.

  • Does every read or write by the agent specify a purpose the data layer recognises?
  • Does the credential the agent uses for a call have access narrower than its theoretical maximum?
  • Does the audit log per call record what data was accessed, for what purpose, by which user identity?
  • Does the data layer's storage enforce the per-call scope independently of the agent layer's claims?
  • Does the platform detect anomalous access patterns (more accounts than usual, cross-tenant reaches, off-hours queries)?
  • Is the retention policy on access logs explicit, with deletion on schedule?
  • Does the platform have an erasure workflow for right-to-be-forgotten requests?
  • Has the team rehearsed what they would do if a leak were detected today?

Interview Q&A

Q1. Why is "the model is not the security boundary" the load-bearing reframe of this module? Because the model is non-deterministic and can be wrong, confused, or manipulated. A security posture that relies on the model behaving correctly will fail in proportion to how often the model is wrong — which is non-trivial in production. The data layer's enforcement is the floor below which the system cannot fall regardless of the model's behaviour. Putting the boundary at the data layer means the worst-case agent error produces a refusal, not a leak. Wrong-answer notes: "the prompt should be careful" is the model-as-boundary error.

Q2. Walk through the chapter-opening 1,247-case incident. What was the failure? The agent's credential authorised reading any customer's account. The model occasionally reached for the wrong account — due to ambiguous user input, coreference drift, or argument-generation slips. The data layer accepted those reads because the credential authorised them. The failure is not in the model's per-case behaviour (which was occasionally wrong, as models are); it is in the data layer's posture, which did not bind reads to the active user's account. The fix is per-call scope: the credential resolved per call to the smallest record set the operation requires. Wrong-answer notes: "fine-tune the model to be more careful" misses that the per-call scope is the structural fix.

Q3. How does the agent's context window change the data-access problem compared to an ordinary API client? The data the model receives in response enters its context window and influences every subsequent generation in the conversation. An ordinary API client receives data and uses it for one purpose; the agent receives data and it becomes part of every prompt that follows in the conversation. Implication: data that enters the context has persistence and reach beyond the single call; the access governance has to consider what is fetched into the model, not just what is returned to the user. Wrong-answer notes: "it's the same as an API" misses the persistence and the cross-turn reach.

Q4. The team says "we have OAuth scopes and audit logs; isn't that enough?" Those are the foundation, and they are necessary. They are not sufficient for the agent case because they govern capability, not per-call data scope. The OAuth scope customers:read lets the agent read any customer; the agent should read only this user's records this call. Per-call scope resolution is the addition. Audit logs are good but need to record the per-call scope and purpose, not just the credential and endpoint. The discipline this module builds extends OAuth and audit with purpose binding, per-call narrowing, and access-pattern detection. Wrong-answer notes: "OAuth + audit is enough" produces the chapter-opening incident.


What to do differently after reading this

  • Stop thinking "the model is safe" and start thinking "the data layer enforces what the model can reach."
  • For every agent call, identify the smallest data scope that satisfies the operation. That is the per-call scope target.
  • Treat the context window as a data-leak path. What enters the context is subject to the same governance as what is returned to the user.
  • Adopt ordinary API discipline as the foundation and add the agent-specific layers (purpose, per-call scope, PII-aware audit).
  • Stand up the missing-discipline diagnostic from this chapter. Three "no" answers is the call to start the work.

Bridge. With the reframe in place, the first technical move is to classify the data. Not every field needs the strictest treatment; not every field can have the loosest. The next chapter builds the data tiers — public, internal, sensitive, regulated — and what changes in handling at each. → 02-classification-and-data-tiers.md