# An unexpected attachment and the limits of agent trust

Kevin Russell | Honesty.Tools | 28 October 2026

I had just dropped Sophia off. My assistant and I had been on a voice call the whole time, working on Emma. I sat down to work, saw an unexpected email with an attachment, and thought: oh shit. My agent might be about to read that.

I hadn't established that the file was malicious, that the agent had read it, or that anything had been compromised. The alarm was about the arrangement. I was building with an assistant that could encounter things I hadn't personally inspected.

Who, exactly, was allowed to tell it what to do?

We also run Honesty.Tools. Could we help people with this? Was there a plugin worth building, or would a clear guide to existing controls be more useful?

That became the work of the morning.

## When information starts giving orders

Spam filters and malware scanners remain important. A malicious Word macro or a vulnerability in a PDF reader is still a problem. But an attachment doesn't need executable code to try to redirect an AI assistant. Ordinary text can do it.

Imagine asking an agent to summarize a document that tells it to retrieve private files and send them elsewhere. That is a hypothetical example, not a claim about the email I received. The document is trying to turn material being read into instructions being obeyed. This is called indirect prompt injection. [Google's explanation](https://knowledge.workspace.google.com/admin/security/indirect-prompt-injections-and-googles-layered-defense-strategy-for-gemini) describes attacks arriving through documents, emails and other external content.

An email can inform an agent. It cannot grant the sender authority over my accounts.

As agents gain access to inboxes, shared files and, in some deployments, financial tools, that distinction becomes practical OPSEC: operational security for the systems we actually use. We don't need to agree on where we sit on an exponential curve to check what an agent can read, where it can send data, and who approves its actions.

## The reassuring setting that needs another question

“Read-only” sounds reassuring. It is useful, but it describes a particular connection. An agent with read-only Gmail access might still have another tool that sends messages, shares files or makes network requests. Preventing changes to the inbox does not, by itself, prevent information leaving through those other routes. [OpenAI's agent-safety guidance](https://developers.openai.com/api/docs/guides/agent-builder-safety) also warns about private-data leakage through downstream tool calls.

I found it helpful to separate three questions:

- **Account scopes:** What did the connected service authorize the application to access?
- **Runtime permissions:** Which tools and destinations can this particular agent actually use?
- **Action approval:** Who authorized this specific operation, with these recipients and this content?

Google's [Gmail scope reference](https://developers.google.com/workspace/gmail/api/auth/scopes) makes the first distinction concrete. Full-mailbox read-only access is different from the narrowly scoped, user-interaction-based access available to an add-on. Neither description tells you what every other tool in the agent's environment can do.

The place to enforce a decision is where an action executes. Microsoft makes this unusually explicit in its [hosted-agent toolbox documentation](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/use-toolbox-hosted-agent): the endpoint does not enforce its approval setting itself. The agent runtime must do that. A system prompt alone is insufficient.

## The boundary I would want

For an unfamiliar attachment, I want reading and acting separated. The reader should have no action credentials, use an isolated, updated extraction environment, and avoid executing macros or automatically fetching embedded links and remote resources. Extracted text remains untrusted. A sandbox limits some technical exposure; it doesn't make the document's instructions legitimate.

The handoff matters too. If an email says a payment is approved, a summary must preserve “the sender claims approval,” rather than turning it into “payment approved.” Passing that summary into Emma, another agent or a memory system must not erase where it came from. Source, timestamp and uncertainty should survive the handoff.

For consequential actions, show the human the actual account, recipient or resource, content, attachments and relevant amount. Approval should apply to that exact operation, expire, and be unusable for a different payload or a second execution. The executing service must check it, rather than trusting the model to remember.

Endless confirmation boxes aren't the answer either. People stop reading them. Limit unnecessary capabilities first, then make the remaining consequential decisions legible. [OWASP's guidance](https://cheatsheetseries.owasp.org/cheatsheets/LLM_Prompt_Injection_Prevention_Cheat_Sheet.html) supports layered controls, exact-action approval and permission enforcement outside the model, while warning about approval fatigue.

## Before building another security product

Our first impulse was to explore a gate between email and an agent. Then we looked at what already exists.

Google describes scoped flow identities, approvals and data-loss controls in [Workspace Studio](https://workspace.google.com/blog/identity-and-security/defend-against-agentic-risks-with-multi-layered-protections-in-google-workspace-studio). Those are controls for that environment, not a universal shield for every agent connected to Gmail.

[QuilrAI](https://docs.quilrai.dev/mcp-gateway/protect/human-approval) documents gateway approvals bound to the displayed arguments, with single-call execution and expiry. A consequential detail: its approval links work without sign-in by default; authenticated approval is an option. “Human approval” deserves inspection, not just a checkbox.

[Invariant](https://github.com/invariantlabs-ai/invariant) offers open-source policy enforcement through a proxy. That gives builders flexibility, but means integration and policy maintenance. [Lakera](https://docs.lakera.ai/docs/agent-behavior-defense) documents tool screening, allowlists and a beta detector for dangerous deviations from the user's mandate. [Microsoft Prompt Shields](https://learn.microsoft.com/en-us/azure/foundry/openai/concepts/content-filter-prompt-shields) detects attack patterns; it does not certify provenance or establish that an action is authorized.

These are first-party descriptions checked on 28 October 2026, not our independent comparative tests. Availability, configuration and enforcement differ. A gateway helps only with traffic that actually passes through it. Direct credentials or another execution route can leave the same exposure open.

## What our small experiment did and did not prove

We built a bounded synthetic demonstration and ran 30 passing tests. Across nine scripted scenarios, exactly one approved fake action occurred. The checks covered forged approvals, changed recipients and payloads, misleading summaries, expired approvals and replay, among other cases.

It never connected to live Gmail or moved real data. Real attachment ingestion stayed disabled because we could not establish the intended isolation in that environment. The demo also assumes a trusted human interface; an actor controlling the same process could bypass that assumption. It has not had independent security review.

Those results show that the particular fake workflow can enforce its rules under the tested conditions. They do not establish protection for a real agent with other credentials and tools.

So we stopped short of turning the experiment into a commercial build. There is no free working security plugin to announce. The next useful step is to understand the actual access paths and evaluate existing controls against the gaps.

## Ten minutes before the next connection

Here is the check I would do before giving an agent more access:

1. **Minutes 0 to 2:** List what it can read and every route by which it can send, share, delete or spend. Include authenticated browsers and other connectors.
2. **Minutes 2 to 4:** Remove unused access. Prefer deliberately selected messages or files when continuous inbox access is unnecessary.
3. **Minutes 4 to 6:** Find where consequential approval is enforced. Check that the real recipient and payload are visible, not only an agent-written summary.
4. **Minutes 6 to 8:** Check attachment isolation, disabled macros and automatic fetching, and whether summaries retain their source.
5. **Minutes 8 to 10:** Find the logs and the disconnect control. Use synthetic examples to check that missing approval stops an action. Treat a passing check as limited evidence.

My short decision tree: **Only need to understand the content?** Keep the reader isolated from action tools. **Need an action?** Verify that it follows your request and review its exact details. **Cannot establish authority or close a bypass?** Stop the action and do it manually.

That morning started with an attachment and an uncomfortable question. It left us with something useful to share, even without a new product. Before we build another platform, let's use the controls we have, find out where they actually apply, and keep the authority to act with the person who owns the consequences.
