Home

Published

- 7 min read

AI Agent Security: Common Mistakes

img of AI Agent Security: Common Mistakes

AI agents are moving from demo rooms into business workflows. That is exciting, but it also exposes a pattern I see often: teams treat agents as clever chat experiences when they should treat them as untrusted automation with access to tools.

An agent can read, reason, call APIs, write data, trigger workflows, and explain its actions in a persuasive tone. That combination deserves serious security design. The mistakes below are not theoretical. They are the kinds of design gaps that appear when teams move fast without a Zero Trust mindset.

Mistake 7: Putting shared keys in prompts and environment variables

The fastest way to connect an agent to a service is often the worst way to operate it. A team places an API key in an environment variable, copies it into a prompt example, or stores it in a notebook used for testing. The demo works. The security debt begins immediately.

Shared keys are difficult to attribute, difficult to rotate safely, and often too powerful. If the same key is used by several agents, services, or developers, an audit log cannot easily explain which workload performed an action. If the key leaks through a trace or tool error, the blast radius can be large.

In Azure, I replace shared keys with managed identities wherever possible. An agent hosted on Azure Container Apps, App Service, Functions, or AKS can call Azure AI Search, Storage, Key Vault, and Azure OpenAI with Microsoft Entra ID. Roles such as Search Index Data Reader, Storage Blob Data Reader, Key Vault Secrets User, and Cognitive Services OpenAI User give much better control than shared secrets.

If a legacy API still needs a secret, I keep it in Key Vault and let the tool implementation retrieve it. The prompt should describe the tool purpose, not the credential.

Mistake 6: Giving the agent one overprivileged identity

Overprivileged identity is the default failure mode of enterprise prototypes. Someone grants Contributor on a resource group or broad access to a storage account because it unblocks development. Later, the same identity is used in production because nobody wants to break the working demo.

Agents need least privilege even more than traditional services because they can be influenced by user input, retrieved content, and tool output. A prompt injection attempt is less dangerous when the agent can only read a narrow index. It is much more dangerous when the agent can write storage, update search indexes, send messages, and call internal APIs with broad rights.

I split identities by function:

  • Runtime identity for normal user interactions.
  • Ingestion identity for indexing and document processing.
  • Administration identity for deployment and configuration.
  • CI/CD identity for provisioning.

Then I assign roles at the narrowest practical scope. The runtime identity usually does not need write access to the search index. The ingestion identity usually does not need to send emails. The deployment identity should not be available to the running agent.

Mistake 5: No egress control

Many agent designs focus on what the agent can read, but not where it can send data. If a tool runtime can call any public endpoint, prompt injection can become data exfiltration. A malicious document can instruct the agent to summarize confidential content and send it to an external address through an available tool or network path.

Egress control is not always simple, but it is important. I want agent runtimes in controlled networks, with outbound traffic routed through approved paths. For Azure workloads, that may involve virtual network integration, Azure Firewall, private endpoints, private DNS zones, and explicit allow lists for required services.

The key question is: if the agent is tricked, where can it send information. The answer should not be anywhere on the internet.

Tool design matters as well. A web request tool with arbitrary URL access is a high risk capability. If the agent only needs to call three approved APIs, the tool should expose those APIs directly rather than offering a generic HTTP client.

Mistake 4: Trusting tool output blindly

Tool output is data, not truth. Search results can contain stale content. A ticketing system can return user supplied text. A web page can include hostile instructions. A database field can be polluted. If the agent treats every tool result as trusted instruction, the system is fragile.

I separate instructions from evidence. System instructions and developer controlled policies define how the agent behaves. Tool output provides facts to consider, subject to validation and authorization. Retrieved content should not be allowed to override the agent’s security rules.

For high impact actions, I also use structured tool responses. Instead of returning a large blob of text, the tool returns typed fields such as case status, owner, classification, and allowed actions. The agent has less room to misinterpret a hidden instruction embedded in free text.

When a tool result is used to support a decision, I log the source, timestamp, query, and correlation ID. That makes it possible to investigate whether the model made a bad inference or the tool returned bad data.

Mistake 3: Ignoring prompt injection in retrieved content

RAG systems create a direct path from enterprise documents into the model context. That is useful, and it is risky. A document can contain text that says the assistant should ignore previous instructions, reveal secrets, or call a tool. The model may not reliably distinguish business content from hostile instructions unless the system is designed to help it.

Prompt injection defense is layered:

  • Retrieve only documents the user is authorized to see.
  • Keep tool credentials outside the prompt.
  • Use system instructions that classify retrieved content as untrusted.
  • Limit available tools by scenario.
  • Require confirmation for sensitive actions.
  • Validate tool inputs in code.
  • Monitor for suspicious instruction patterns in retrieved content.

Do not rely on one perfect prompt. Prompts are part of the defense, not the whole defense. The strongest controls are authorization, tool constraints, egress limits, and human approval for high impact actions.

Mistake 2: No audit trail

If an agent changes a record, sends a message, opens a ticket, updates an index, or recommends a decision, I need to know how that happened. Without an audit trail, every incident turns into guesswork.

Useful audit records include:

  • Human user identity.
  • Agent workload identity.
  • Prompt template version.
  • Model deployment.
  • Retrieved document identifiers.
  • Tool name, inputs, and result status.
  • Authorization decision.
  • Human approval step where required.
  • Final action taken.
  • Correlation ID across services.

This does not mean logging every sensitive token forever. Logging needs redaction, retention, access control, and privacy review. But the absence of an audit trail is not privacy. It is operational blindness.

I design audit before production. Retrofitting it after a security incident is painful and incomplete.

Mistake 1: Treating agents as trusted users

The biggest mistake is conceptual. An agent is not a trusted employee. It is software that processes untrusted input and may use tools. It can be helpful, but it should not be granted trust because it speaks confidently.

I design agents like constrained workloads:

  • Authenticate the human user.
  • Authenticate the agent workload.
  • Authorize every tool action.
  • Minimize data returned to the model.
  • Scope identities narrowly.
  • Restrict egress.
  • Require human approval for high risk actions.
  • Monitor behavior continuously.

This mindset changes the architecture. Instead of asking what the agent could do if fully trusted, I ask what the agent must do to deliver value safely. That usually leads to smaller tools, clearer policies, better identity separation, and a system that can survive hostile input.

Key takeaways

  • Agents should be treated as untrusted automation with tool access, not as trusted users.
  • Replace shared keys with managed identities and narrowly scoped RBAC.
  • Separate runtime, ingestion, administration, and deployment identities.
  • Control egress and avoid generic tools that can send data anywhere.
  • Build layered defenses against prompt injection, including authorization, validation, monitoring, and human approval.