Build a Privacy Filter Before Your AI Agent Remembers User Actions A developer outlines a privacy filter for AI agents that record user actions, emphasizing the need to capture minimal event streams and apply strict redaction and retention policies. The guide proposes a five-job filter covering event allowlisting, sensitive data detection, purpose binding, retention, and retrieval control, with a TypeScript example for implementation. AI agents are starting to remember more than chats. They can watch clicks, typed text, app switches, browser context, files, tool calls, and workflow history. That memory can make an agent feel useful fast, but it can also turn a helpful feature into a quiet privacy incident. If you are building an AI product, do not start with “how much can we capture?” Start with “what is the smallest event stream that still helps the user?” This guide shows a practical privacy filter you can place between raw user activity and agent memory. Recent AI tooling trends point in the same direction: agents are moving from chat boxes into operating systems, browsers, IDEs, customer support tools, analytics dashboards, and workflow automation platforms. The more useful the agent becomes, the more context it wants. That creates a new engineering problem. Traditional app logs record requests and errors. Agent memory records intent, context, and behavior. A raw event can include: This is not just observability. It is a privacy boundary. The practical trigger is simple: computer-use agents and workflow agents now need history to resume work, personalize answers, and automate multi-step tasks. But developers, security reviewers, and buyers are asking harder questions about PII, retention, auditability, user consent, and whether agent traces can leak private business data. Most teams already have logs, traces, analytics events, and support transcripts. So when they add agent memory, they often reuse the same pattern: That is easy to ship. It is also too broad. Agent memory needs a stricter path because it may be used to generate future answers or actions. A normal log line might be seen by engineers. A memory item might be read by a model, combined with other data, and used to make a decision. The safer pattern is: Raw event → privacy filter → purpose check → redacted memory → retention policy → retrieval policy The privacy filter is not a prompt. It is application code that decides what the agent is allowed to remember. A good privacy filter has five jobs. | Job | Question it answers | Example | |---|---|---| | Event allowlist | Should this event be captured at all? | Save “opened invoice page,” not every mouse coordinate. | | Sensitive data detection | Does the payload contain PII, secrets, or regulated data? | Detect emails, API keys, card-like numbers, tokens. | | Purpose binding | Why is this memory needed? | Resume task, improve support, audit approval. | | Retention control | How long can this memory live? | 48 hours for raw traces, 30 days for redacted task summaries. | | Retrieval control | Who or what can read it later? | Only the same user, tenant, role, and task type. | The filter should run before indexing, summarization, embedding, analytics export, or model calls. Do not start with redaction. Start with event classes. Redaction helps when you must keep data. Classification helps you avoid collecting data in the first place. A simple event taxonomy might look like this: | Event class | Risk | Store by default? | Notes | |---|---|---|---| | Navigation event | Low | Yes, redacted | Page type, not full URL if it contains IDs. | | Tool call metadata | Medium | Yes | Store tool name, status, cost, policy result. | | User typed text | High | No | Store only if explicitly needed and redacted. | | Screen content | High | No | Prefer structured app state over screenshots. | | File content | High | No | Store references and hashes, not full content. | | Approval decision | Medium | Yes | Keep reviewer, action, timestamp, and reason. | | Secret or credential | Critical | Never | Block and alert if detected. | Here is a small TypeScript example: type EventClass = | "navigation" | "tool call" | "typed text" | "screen content" | "file content" | "approval" | "secret"; type CaptureDecision = "store" | "redact then store" | "summarize only" | "drop"; const capturePolicy: Record