Skip to content

Engineer's Guide to Zero Data Retention (ZDR) for AI Agent Security

Learn how to architect a stateless, Zero Data Retention (ZDR) integration layer for AI agents to pass enterprise security audits and prevent data leaks.

Riya Sethi Riya Sethi · · 15 min read
Engineer's Guide to Zero Data Retention (ZDR) for AI Agent Security

Zero Data Retention (ZDR) for AI agent security is an architectural design pattern where the integration middleware processes third-party API payloads entirely in memory, never writing them to persistent storage, databases, log files, or caching layers. When an AI agent reads a Salesforce contact, updates a BambooHR record, or writes a Xero journal entry, the raw payload flows through your infrastructure once and is discarded the millisecond the response is delivered. No copies. No retention windows. No expanded SOC 2 scope.

That is the architectural bar enterprise buyers now demand. If you are building AI agents that read and write to external systems, your data retention architecture dictates whether your product passes InfoSec procurement or dies in legal review. Contractual promises are no longer enough. If you cannot prove ZDR at the code level, your deal will be blocked.

This guide details the exact engineering blueprints senior engineers use to ship stateless AI agent architectures that pass procurement in days, not quarters. We will cover the mechanics of building a stateless API proxy, normalizing rate limits via IETF standards without holding state, securing Model Context Protocol (MCP) servers, and managing OAuth lifecycles without logging sensitive context.

The Enterprise Security Reality: Why ZDR Is Mandatory for AI Agents

The core rule of enterprise AI integration is simple: Do not store data you do not own.

AI agents are transitioning from read-only assistants to autonomous systems capable of executing multi-step workflows. As agents gain write access to upstream SaaS platforms, the integration middleware becomes a primary attack vector. Agent adoption has completely outrun agent governance, and the security gap is widening rapidly.

According to a 2026 Gravitee survey of over 900 executives, 88% of organizations reported confirmed or suspected AI agent security incidents in the past year, with that number climbing to 92.7% in the healthcare sector. MintMCP's compilation of industry data shows an even wider gap: while 82% of enterprises are deploying AI agents, only 44% have any formal AI security policy in place to govern them.

The governance failures get worse when agents start taking action. Kiteworks' 2026 Data Security and Compliance Risk Forecast found that 63% of organizations cannot enforce purpose limitations on their agents, and 60% cannot terminate a misbehaving agent once it starts executing tasks. Meanwhile, a Gartner survey of 302 cybersecurity leaders reported that 69% of organizations suspect or have confirmed the use of prohibited generative AI tools inside their networks.

Here is what those numbers mean for your product roadmap. When your Account Executive moves a six-figure deal to the finish line, the buyer's InfoSec team will send a Standardized Information Gathering (SIG) questionnaire covering vendor risk across dozens of categories. They will ask exactly where their data goes.

If your architecture relies on a sync-and-store model—where you pull data from Salesforce, store it in your managed database, and then feed it to your LLM—you immediately trigger a high-risk vendor assessment. Caching regulated data in your middleware introduces three immediate engineering and business blockers:

  • SOC 2 Scope Creep: Every database, cache, and message queue that touches the data must be audited, encrypted, and monitored. You have inherited compliance obligations you cannot economically discharge.
  • Data Strikethrough Liabilities: If a user deletes a record in the upstream SaaS, you are legally obligated to purge it from your cache immediately to comply with GDPR and CCPA.
  • Procurement Death: Enterprise security teams will actively block deals if they discover their sensitive data rests on unverified third-party infrastructure.

Stateless architecture is how you make the scope disappear. If you never write the payload, you cannot leak the payload. If you cannot leak the payload, InfoSec has nothing left to flag.

For a deeper look into the compliance differences between caching and stateless systems, review our analysis on Zero Data Retention for AI Agents: Why Pass-Through Architecture Wins.

Contractual vs. Architectural ZDR: Escaping the 30-Day Trap

True Zero Data Retention is enforced by code, not just by Terms of Service.

Many engineering teams assume they have achieved ZDR because their LLM provider promised not to use API inputs for model training, or they have an MSA appendix stating data won't be retained beyond a support window. This is a dangerous misunderstanding of enterprise compliance.

Contractual ZDR is merely a legal promise; it does not describe what actually happens to a payload at runtime. Architectural ZDR is a technical guarantee: the payload is held in a request-scoped memory buffer, transformed, forwarded, and garbage-collected. No persistence layer is involved at any point.

The distinction matters because of default settings you probably do not know about. For example, CData Software notes that standard API configurations at most major LLM providers retain data for 30 days for abuse monitoring. True zero retention is usually an opt-in feature that must be explicitly configured. If your middleware processes a highly sensitive financial document and passes it to an LLM endpoint with default settings, that data sits on a third-party server for a month.

Furthermore, ZDR applies at two distinct layers that engineering teams constantly conflate:

  1. The model provider layer: Whether the LLM vendor logs your prompts and completions.
  2. The data connectivity layer: Whether your integration platform caches third-party API responses.

Configuring ZDR at one layer does not extend it to the other. Your prompts to Claude can be ephemeral while your integration middleware is quietly writing every Salesforce Account object it fetches into a database table. Enterprise security teams check both. Your architecture has to answer both.

Warning

Reality check: If your vendor cannot show you the exact code path where a third-party payload is discarded, you do not have architectural ZDR. You have a marketing claim. Treat it accordingly during your own vendor reviews.

Blueprint for a Stateless API Proxy Architecture

A stateless API proxy decouples compute from data storage, ensuring payloads exist only in ephemeral memory during transit.

Building an in-memory proxy requires disciplined engineering. You cannot rely on standard web framework defaults, which often log request bodies or buffer large payloads to disk when memory thresholds are exceeded. A stateless proxy for AI agent integrations has three hard requirements:

  1. Compute must be decoupled from storage: The service that handles the request must have no persistent database attached to it that touches payloads. Use ephemeral execution environments with read-only file systems to physically prevent the application from writing temporary files.
  2. Payloads must live in request-scoped memory only: No global caches, no queue-based buffering of raw responses, and no log lines that echo response bodies.
  3. Auxiliary state must be strictly separated: Tokens, mappings, and configurations must be separated from customer payloads. These are different security zones with different retention rules.

Consider the architectural difference visualized below:

flowchart TD
    subgraph Stateful ["Stateful Architecture (High Risk)"]
        A1["AI Agent"] --> B1["Integration Middleware"]
        B1 --> C1["Database Cache"]
        B1 --> D1["Upstream SaaS"]
        C1 -.->|"Data lingering at rest"| B1
    end

    subgraph Stateless ["Stateless ZDR Architecture (Secure)"]
        A2["AI Agent"] --> B2["In-Memory Proxy"]
        B2 --> D2["Upstream SaaS"]
        B2 -.->|"Payload discarded immediately"| A2
    end

And here is the reference topology for how a single request flows through this secure architecture:

sequenceDiagram
    participant Agent as AI Agent
    participant Proxy as "Stateless Proxy (ZDR)"
    participant Vault as Token Vault
    participant Upstream as "Upstream SaaS API"

    Agent->>Proxy: Tool call (e.g., get_contact)
    Proxy->>Vault: Fetch OAuth token (encrypted at rest)
    Vault-->>Proxy: Access token (in-memory)
    Proxy->>Upstream: HTTPS request with token
    Upstream-->>Proxy: JSON payload
    Note over Proxy: Transform + normalize in memory
    Proxy-->>Agent: Normalized response
    Note over Proxy: Buffer released, no persistence

When implementing this, you must explicitly handle data streams to avoid accidental retention in memory dumps or garbage collection pauses. Never buffer entire JSON payloads into memory if they exceed a few megabytes. Use stream pipelines to pipe the incoming request directly to the upstream SaaS API.

Here is an example of a stateless proxy handler using Node.js streams to handle large payloads safely:

// Example: Stateless proxy handler using Node.js streams for large payloads
import https from 'https';
import { pipeline } from 'stream/promises';
 
export async function statelessProxyHandler(req, res, upstreamUrl, oauthToken) {
  // 1. Strip sensitive headers from incoming request
  const safeHeaders = filterHeaders(req.headers);
  
  // 2. Attach the secure OAuth token from your vault
  safeHeaders['Authorization'] = `Bearer ${oauthToken}`;
 
  const options = {
    method: req.method,
    headers: safeHeaders,
  };
 
  return new Promise((resolve, reject) => {
    const upstreamReq = https.request(upstreamUrl, options, async (upstreamRes) => {
      // 3. Pass status and safe headers back to the caller
      res.writeHead(upstreamRes.statusCode, filterHeaders(upstreamRes.headers));
      
      try {
        // 4. Pipe the response directly without buffering in memory
        await pipeline(upstreamRes, res);
        resolve();
      } catch (err) {
        reject(err);
      }
    });
 
    upstreamReq.on('error', reject);
 
    // 5. Pipe the incoming request body to the upstream
    req.pipe(upstreamReq);
  });
}

For standard, non-streaming requests where you need to transform the payload before returning it to the agent, a minimal TypeScript handler that respects ZDR rules looks like this:

import { fetch } from 'undici';
 
export async function proxyGetContact(req: Request): Promise<Response> {
  const { tenantId, contactId } = await req.json();
 
  // Token fetch: credential store, not payload store
  const token = await tokenVault.getAccessToken(tenantId);
 
  const upstream = await fetch(
    `https://api.example.com/v1/contacts/${contactId}`,
    { headers: { Authorization: `Bearer ${token}` } }
  );
 
  // Payload lives only in this function scope
  const raw = await upstream.json();
  const normalized = normalizeContact(raw);
 
  // Log metadata only. NEVER log `raw` or `normalized`.
  logger.info({
    tenantId,
    upstream: 'example',
    status: upstream.status,
    latencyMs: performance.now(),
  });
 
  return Response.json(normalized);
}

A few critical things worth calling out for engineers who inherit this pattern:

  • Structured logging must be metadata-only: The most common ZDR regression is a well-meaning engineer adding logger.debug({ response: raw }) during a production incident and shipping it. Configure your application loggers to strip all HTTP bodies and query parameters. Log only metadata: timestamps, HTTP status codes, latency, and integration IDs.
  • APM traces are payload channels too: Datadog, New Relic, and Sentry will happily capture request and response bodies if you let them. Turn off body capture globally, then opt-in per-endpoint only for non-customer routes.
  • Backpressure through streaming, not buffering: If you must handle large paginated responses, stream them through the transform stage rather than accumulating them in memory or on disk.

For a deeper walkthrough of what to eliminate from your logging and tracing stack, see our guide on How to Ensure Zero Data Retention When Processing Third-Party API Payloads.

Handling Rate Limits and Errors Without Caching

In a ZDR architecture, the middleware cannot hold state to implement automatic retries or exponential backoff.

Rate limits are where naive ZDR implementations break. One of the hardest engineering challenges in building a stateless proxy is dealing with upstream API rate limits (HTTP 429). In a traditional stateful system, if Salesforce returns a 429 Too Many Requests, the middleware drops the payload into a message queue, waits for the reset window, and retries the request.

You cannot do this in a ZDR system. Storing the payload in a queue constitutes data retention. If the payload contains protected health information (PHI) and sits in a retry queue for five minutes, you have violated HIPAA and expanded your compliance footprint. The illusion of a self-healing proxy comes at the cost of your security attestation.

The correct pattern is to push retry responsibility to the caller and give them the information they need to make good decisions. Truto solves this by operating as a pure pass-through layer. Truto does not retry, throttle, or apply backoff on rate limit errors. When an upstream API returns an HTTP 429, Truto passes that exact error back to the calling AI agent.

However, because every SaaS platform formats rate limit headers differently, Truto does something more useful than silent retries: it normalizes upstream rate limit information into standardized headers per the IETF specification on every response.

Header Meaning
ratelimit-limit The total request quota in the current window (ceiling).
ratelimit-remaining The number of requests left in the current window.
ratelimit-reset The time (in seconds) until the quota resets.

This leaves the responsibility of retry logic and backoff exactly where it belongs: with the caller. The AI agent framework orchestrating the workflow must hold the context and decide how to proceed. Here is how a Python caller handles this:

# Example: Python caller-side retry logic reading IETF normalized headers
import time
import requests
 
def execute_agent_tool(url, payload, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(url, json=payload)
        
        if response.status_code == 429:
            # Read the normalized IETF headers provided by the pass-through proxy
            reset_seconds = int(response.headers.get('ratelimit-reset', 5))
            print(f"Rate limited. Waiting {reset_seconds} seconds...")
            time.sleep(reset_seconds)
            continue
            
        response.raise_for_status()
        return response.json()
        
    raise Exception("Max retries exceeded after rate limit")

And here is the equivalent pattern in TypeScript:

// Example: TypeScript caller-side retry logic
async function callWithRetry(url: string, opts: RequestInit, attempt = 0) {
  const res = await fetch(url, opts);
 
  if (res.status === 429 && attempt < 3) {
    // Read the normalized IETF headers
    const reset = Number(res.headers.get('ratelimit-reset') ?? '5');
    await sleep(reset * 1000);
    return callWithRetry(url, opts, attempt + 1);
  }
 
  return res;
}

This inverts the usual middleware convenience trade-off. You lose the illusion of a self-healing proxy, but you gain a system where every retry is auditable, every backoff decision is made with full context, and no request payload is ever spooled to persistent storage waiting for a retry window.

Securing the Model Context Protocol (MCP) Layer

The Model Context Protocol (MCP) standardizes how AI agents connect to external tools, but it requires strict architectural boundaries to maintain ZDR.

MCP is rapidly becoming the connective tissue between LLMs and external systems. It operates via JSON-RPC over standard input/output (stdio) or Server-Sent Events (SSE). It defines how agents discover tools, invoke them, and receive structured results. It also introduces a new architectural surface where ZDR can either be enforced or quietly violated.

To maintain ZDR at the MCP layer, the server must dynamically generate tool schemas from the upstream API definitions without logging the actual schemas or the data passing through them. An MCP server needs to do three things without persisting customer payloads:

  1. Generate tool definitions from schemas, not from data: Pull OpenAPI or GraphQL schemas at build or config time, cache the schema (not the data), and expose the resulting tools via JSON-RPC.
  2. Handle tool invocations through the same stateless proxy: When an agent calls a tool, the MCP server receives the arguments from the LLM, translates them into the upstream SaaS API format, fires the HTTP request, and translates the response back to the LLM. At no point should the MCP server write the arguments or the response to a database.
  3. Propagate errors, not absorb them: Rate limits, auth failures, and validation errors bubble up to the LLM in a normalized form so the agent can decide what to do next.
flowchart LR
    A[LLM Agent] -->|JSON-RPC tool call| B[MCP Server]
    B -->|Schema lookup| C[(Schema Cache)]
    B -->|Auth + forward| D[Stateless Proxy]
    D -->|HTTPS| E[Upstream SaaS API]
    E -->|Response| D
    D -->|Normalized result| B
    B -->|Tool result| A

Notice what is missing from that diagram: any box labeled "payload cache," "response store," or "agent memory". The MCP layer is a translation and routing layer, not a data layer.

Warning

Beware of default MCP logging and convenience caching. Many open-source MCP SDKs default to logging all JSON-RPC payloads for debugging purposes. If an agent passes a customer's social security number as a tool argument, and your MCP server logs it to standard output, you have breached ZDR. Always configure MCP servers to run with strict log redaction in production. Furthermore, do not use the MCP server as a convenience cache for "recently fetched" objects. Once you cache one Salesforce contact for 60 seconds, your architecture is no longer stateless.

Truto provides native support for MCP tool generation from API schemas while guaranteeing Zero Data Retention. The platform acts as a secure boundary, translating the LLM's intent into normalized API calls and piping the results back entirely in memory. For a full protocol-level walkthrough, read our MCP Server Security & Zero Data Retention: 2026 Implementation Guide.

OAuth Token Lifecycle Management in a ZDR World

Managing authentication securely requires separating the persistent state of tokens from the ephemeral state of data payloads.

To interact with third-party APIs, your integration layer must authenticate using OAuth 2.0. This presents a paradox: how do you maintain a stateless architecture when you must store persistent access tokens and refresh tokens to keep customer connections alive?

The solution is strict boundary isolation. The system that stores and rotates OAuth tokens must be entirely decoupled from the system that processes the API payloads. The operating principles are:

  • Segregate credentials from payloads: Tokens live in an encrypted store with its own access controls, audit trail, and rotation policy. Payloads live in nothing.
  • Refresh ahead of expiry, not on failure: A background scheduler refreshes tokens shortly before they expire so agent requests never see a mid-flight 401. This avoids the anti-pattern of retrying failed requests after a token refresh, which requires spooling the failed payload somewhere.
  • Never log token values: Log token IDs, tenant IDs, expiry timestamps, and refresh events. Never log the token string itself.
  • Use short-lived access tokens with longer-lived refresh tokens: This is standard OAuth best practice, but especially important when your compliance posture is "we hold as little as possible for as short as possible."

Truto handles secure OAuth token lifecycles by managing the state of the connection without ever touching the state of the data. The platform schedules work ahead of token expiry, proactively exchanging refresh tokens for new access tokens. This ensures that when the AI agent fires a request, the proxy layer always has a valid token ready to inject into the authorization header in-memory.

sequenceDiagram
    participant Agent as AI Agent
    participant Proxy as ZDR Proxy
    participant Vault as Token Vault
    participant Upstream as SaaS API

    Note over Vault, Upstream: Background process schedules refresh before expiry
    Vault->>Upstream: Exchange refresh token
    Upstream-->>Vault: New access token

    Agent->>Proxy: Execute Tool (Payload)
    Proxy->>Vault: Fetch active token (In-memory)
    Vault-->>Proxy: Access Token
    Proxy->>Upstream: Forward Request + Payload + Token
    Upstream-->>Proxy: Response Data
    Proxy-->>Agent: Response Data
    Note over Proxy: Payload dropped from memory

By centralizing token management and decentralizing data processing into a stateless proxy, engineering teams can offer enterprise-grade AI integrations without the compliance nightmare of data retention. To understand the nuances of token rotation at scale, see What is OAuth Token Management? The B2B SaaS Guide.

Tip

Practical rule: Ask yourself, "If someone dumped every table in my integration platform tomorrow, what customer data would leak?" In a true ZDR architecture, the answer is: encrypted OAuth credentials and connection metadata. Nothing else.

What This Buys You in an Enterprise Sale

The technical patterns above compress into a small number of statements your security team can put in front of a CISO:

  • Third-party API payloads are processed in memory and never persisted.
  • Rate limit errors are surfaced to the caller with IETF-standard headers, so retry behavior is explicit and auditable.
  • MCP tool generation happens from schemas, not from cached customer data.
  • OAuth tokens are the only durable customer-linked data, and they live in a credential store physically isolated from payload paths.
  • Logs, traces, and APM data contain metadata only, never request or response bodies.

That set of claims is what turns a 90-day InfoSec review into a 90-minute one. It is also what keeps your SOC 2 and HIPAA scope small enough to actually maintain as your product grows.

Strategic Next Steps for Engineering Teams

Deploying AI agents into enterprise environments is no longer just an AI challenge; it is a security and integration challenge. The companies that win enterprise deals are the ones that can explicitly prove their architecture does not retain customer data.

Start with an honest audit. Grep your codebase for every place a third-party payload could be persisted: database writes, queue publishes, log statements, cache sets, object storage writes, and APM captures. Every one of those is a potential ZDR violation waiting to be discovered by an auditor.

Then, shift your rate limit logic. Stop trying to absorb 429s in your proxy layer. Normalize the headers and push the retry responsibility back to the AI agent framework.

Finally, decide where you want to spend engineering effort. Building a stateless proxy layer, an MCP server, a token vault, and a rate limit normalization layer is real work, and keeping it compliant across dozens of upstream APIs is a full-time discipline. Adopt unified APIs that are built from the ground up for pass-through processing, ensuring your SOC 2 scope remains small and defensible.

FAQ

What does zero data retention mean for AI agent security?
Zero Data Retention (ZDR) means the integration middleware processes third-party API payloads entirely in request-scoped memory. It acts as a stateless proxy, ensuring that regulated enterprise data is never written to databases, caches, queues, or log files.
Is a contractual ZDR promise from a vendor enough to pass InfoSec review?
No. Enterprise security teams increasingly ask for architectural proof, not just contractual language. If a vendor cannot show the specific code path where payloads are discarded and cannot demonstrate that logs and traces exclude response bodies, the ZDR claim will not survive a rigorous review.
Why is caching API data bad for enterprise AI deals?
Caching regulated data expands your SOC 2, HIPAA, and GDPR scope while creating massive liability. Enterprise InfoSec teams will actively block deals if they discover their sensitive data rests on unverified third-party infrastructure.
How should a stateless proxy handle HTTP 429 rate limit errors?
A stateless proxy should pass HTTP 429 rate limit errors directly back to the calling agent. By normalizing upstream limits into IETF headers (ratelimit-limit, ratelimit-reset), the caller can implement its own exponential backoff without the middleware holding state in a retry queue.
How do you manage OAuth tokens without violating ZDR?
Segregate credentials from payloads. OAuth access and refresh tokens are securely stored in an encrypted vault and rotated automatically via a background scheduler ahead of expiry. The actual data payloads remain entirely ephemeral in the proxy layer.

More from our Blog