Security and privacy for an agent that can act on your data
The threat model for an in-app agent is its tool set, not its microphone. The OWASP entries that apply, the injection path, and the controls worth building first.
About this article
An in-app agent's threat model is the tool set, not the microphone. The two OWASP LLM entries that apply hardest are LLM01 prompt injection and LLM06 excessive agency, and both are answered by the same control: a confirm step written as a branch in server code, so no model decision can commit a write on its own.
Most writing about assistant security starts at the microphone, which is the wrong end of the system. A microphone is an input. The thing worth securing is the set of operations the agent can perform once it has decided what you meant.
An agent with three read tools is a search box with a conversational interface, and its worst day is an embarrassing answer. An agent that can issue a refund, cancel a booking or move money is a piece of software that takes actions on a user’s behalf based on a model’s interpretation of ambiguous input. That is a different product with a different threat model, and the microphone is barely in it.
Start from the catalogue, not from the headlines#
OWASP maintains a Top 10 for LLM applications, currently the 2025 edition, and two of its entries describe most of what can go wrong with an in-app agent.
LLM01:2025 is prompt injection. The version that matters for an agent is the indirect one, described by Greshake and colleagues in Not what you’ve signed up for (February 2023). Their framing is the useful part: LLM-integrated applications “blur the line between data and instructions”, so an attacker can “remotely, without a direct interface, exploit LLM-integrated applications by strategically injecting prompts into data likely to be retrieved”. Their conclusion is blunt about severity, since processing a retrieved prompt “can act as arbitrary code execution, manipulate the application’s functionality, and control how and if other APIs are called”.
Translate that into your app. Your agent reads support tickets, product descriptions, merchant names, delivery notes, a field somebody typed into a form three years ago. Any of those is a place to write a sentence addressed to the model. The attacker does not need to reach your user or your microphone at all.
LLM06:2025 is excessive agency, which OWASP traces to three causes: extensions that include capabilities nobody needed, permissions wider than the downstream system requires, and autonomy without verification before a high-impact action. Their first prevention measure is stated plainly: “Utilise human-in-the-loop control to require a human to approve high-impact actions before they are taken.” They also note that monitoring and rate limiting cannot prevent excessive agency and can only reduce the damage, which is worth remembering the next time an alerting dashboard is offered as a control.
The Model Context Protocol specification says the same thing from the protocol’s side, in its Security and Trust and Safety section. Tools “represent arbitrary code execution and must be treated with appropriate caution”, tool descriptions “should be considered untrusted, unless obtained from a trusted server”, and hosts “must obtain explicit user consent before invoking any tool”. The spec also concedes that it cannot enforce any of this at the protocol level, which puts the obligation in your code.
The control that answers three threats at once#
A confirm step is not a sentence in a prompt telling the model to ask first. It is a branch in your server code: tools that write are intercepted before execution, and what comes back to the client is a description of the proposed action rather than its result. The user sees an amount, a recipient and a date, and taps. Only then does the action run.
Why this holds where prompt instructions do not: a model that has been successfully injected will cheerfully ignore an instruction to confirm, because ignoring instructions is precisely what the attack achieved. A branch in code has no opinion about the conversation that produced the call.

Two design rules make the difference between a confirm card and a dialog box people learn to dismiss. The card describes the specific call, with the actual arguments, so approving it approves something concrete. And there is exactly one card per turn, because a screen with three pending approvals trains the user to tap through all of them. The confirm card as a code boundary covers the implementation in detail, and what happens when an injected instruction reaches the spending path covers the adversarial cases.
Biometrics, tiered rather than sprinkled#
A biometric check is a stronger claim than a tap. It asserts that the person holding the device is the enrolled user at this moment, and it is enforced by hardware rather than by your code. It also costs a second and a small amount of goodwill each time.
Android’s guidance is unusually specific about where that cost is worth paying. Its biometric authentication documentation distinguishes keys with a validity window from auth-per-use keys, which require “the user to present either a biometric credential or a device credential each time your app needs to access data that’s guarded by that key”, and says these “can be useful for high-value transactions, such as making a large payment or updating a person’s health records”. The platform is telling you to tier. iOS has an equivalent hardware boundary in the Secure Enclave, where Apple documents that hardware keys derived from the device UID or GID “stay within the AES Engine and aren’t made visible even to sepOS software”.
In practice a small number of actions deserve a biometric and everything else deserves a tap. Our own deployment reserves it for a single operation, instant settlement, because it is the one that moves money to an external account. Reading a balance has no gate at all. Which actions deserve Face ID is the longer argument for drawing that line deliberately rather than by default.
Where voice actually changes the picture#
Spoken input is easy to forge. The US Federal Trade Commission has warned consumers that a scammer can clone a voice from a short clip taken from social media. That is a real problem for any system that treats a voiceprint as a credential.
It is not much of a problem for a system that never did. If speech only ever produces a proposed action, and the approval is a tap on a device that holds a hardware-bound key, then a perfect clone of the user’s voice buys an attacker the ability to draft something the user will decline. The security property comes from where the approval lives, not from detecting the forgery.
Liveness and synthetic-speech detection are worth having as a second layer, and they are an arms race by construction: every improvement in detection is a training signal for the next generation of synthesis. Architecture that removes voice from the authorisation path does not have to win that race.
What leaves the device, and what you keep#
Privacy work on an agent is mostly subtraction. Send the audio or transcript the turn needs and nothing else. Scrub identifiers before anything reaches a log. Set a retention window short enough that you would be comfortable reading it out in a meeting, and delete on request without a ticket.
Treat recordings of a person’s voice as sensitive by default and design as though a regulator will ask. We are not going to summarise any jurisdiction’s law here, because a blog post is the wrong place to get that from and the old version of this page cited three intermediaries rather than a statute. The engineering rule stands without the legal citation: the recording you did not keep cannot be breached, subpoenaed, or mis-shared.
For governance framing, NIST’s AI Risk Management Framework, released 26 January 2023, organises this work into Govern, Map, Measure and Manage. It is voluntary and it is not a control list, which is exactly why it is useful when someone asks how you decided what to build first.
The order to build them in#
Build the confirm gate first, because three threats end there and because it is the control that keeps working after a model change.
Second, narrow the tool set. Every tool you do not expose is an attack you do not have to reason about, and OWASP’s excessive-agency guidance is a list of ways to expose fewer of them.
Third, bind the session to the device. A hardware key that signs each request means a captured request cannot be replayed from somewhere else, and a stolen token alone is not enough.
Fourth, tier the biometric onto the handful of actions that genuinely warrant it.
Fifth, minimise and expire the data. This is the one most often deferred, and the one an incident makes expensive.
Sixth, add detection. It is a real layer and it belongs last, because it is the only one whose value depends on staying ahead of an adversary.
Latency is the usual objection to all of this, and it is mostly misplaced: the gate costs a tap, while the seconds live in the cold connections and cache misses that have nothing to do with security. The security documentation covers how the confirm interception and the device key are wired in the SDK.
Sources#
- OWASP, “Top 10 for LLM Applications, 2025”, and “LLM06:2025 Excessive Agency”. Accessed 12 September 2026.
- Greshake, K. et al., “Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection”, arXiv:2302.12173, February 2023.
- Model Context Protocol, “Specification, revision 2025-06-18”. Accessed 12 September 2026.
- Android Developers, “Show a biometric authentication dialog”. Accessed 12 September 2026.
- Apple, “Secure Enclave”, Apple Platform Security. Accessed 12 September 2026. The page describes UID- and GID-derived hardware keys staying inside the AES Engine and PKA; it does not make a blanket claim about every private key.
- US Federal Trade Commission, “Scammers use AI to enhance their family emergency schemes”, March 2023.
- NIST, “AI Risk Management Framework”, AI RMF 1.0 released 26 January 2023.
Next
How an action is gated, what the confirm step guarantees, and what leaves the device.
Read the security modelThe rest of Safety
Open the clusterConfirm-first actions, biometric tiering, scoped tokens and the audit trail you need before an agent touches money.
- Confirm cards: letting an agent act without losing controlIf the confirmation lives in the prompt it is a suggestion. Make it a branch in your server code, and decide the tier per tool rather than per sentence.12 min
- Designing a confirm-and-pay flow an agent can runThe payment path end to end: where the write is intercepted, what the card must show, when a biometric is worth asking for, and why speech is never the credential.10 min
- An agent in a banking app, and the gate before money movesHow to let an agent act inside a fintech app: which actions get a confirm card, which get a biometric, and why the gate lives in code.8 min
- Does your agent work eight times out of eight?Average accuracy is the wrong number for a product. Run the same task eight times and count how often it worked every single time.11 min
- Prompt injection when the agent can spend moneyIn a consumer app the untrusted text is your own user's data and the tools move their money, which makes filtering useless and structure the only real defence.10 min
- Which agent actions deserve Face ID, and which do notBiometric-gating everything trains users to approve without reading. Tier agent actions by what they can destroy, and let the platform decide how.10 min
Elsewhere on the map
- An agent in a healthcare app: booking, refills, and the stop lineThe three patient-facing tasks an in-app agent does well, the escalation line that belongs in code, and the compliance question to settle before any of it.Business9 min
- Letting users reorder by voice in three tool callsRepeat purchase is the cheapest first agent feature to ship. Three tools carry it, only one of them writes, and a confirm card sits between the second and the third.Agent basics6 min
- In-app agents that finish the task instead of answeringAn assistant that describes where a setting lives competes with your own navigation. One that completes the request does not. What changed, and what to build.Agent basics8 min
