Everyone is shipping agents. Almost nobody is securing them like they'd secure a cron job that can read email, run SQL, and push to prod. That's the whole problem in one sentence.
An AI agent is not a chatbot with ambition. It's a confused deputy: a process that holds your credentials and will happily do the wrong thing if the prompt stack says so—whether the bad instruction came from a user, a PDF, a Jira ticket, or a poisoned MCP tool description. The model didn't "go rogue." It followed instructions from text you treated as data.
We index breaches where the boring part still wins—stolen OAuth tokens, phished MFA, misconfigured SaaS exports. Agents add a new lane: automation that moves faster than your approval workflows. Here's what actually helps, and what I've watched teams do right before the postmortem.
The mental model (30 seconds)
Classify every agent host—Cursor with MCP, internal LangChain service, support bot with a database plugin—the same way you'd classify a bastion host or a CI runner with production secrets:
- Who can spawn it?
- What credentials does it inherit?
- Which tools can spend money, send email, or exfiltrate rows?
- What untrusted text can reach the model (tickets, web pages, attachments)?
If you can't answer those four questions, you don't have an "AI strategy." You have shadow IT with better marketing.
Do's
1. Treat tools as code, not config fluff
MCP tool descriptions, function schemas, and system prompts are executable policy. Diff them on upgrade. If a community server updates metadata server-side after you clicked approve—that's a rug pull, not a semver bump. Read the raw JSON the host sends to the model, not just the pretty card in the IDE.
2. Split read and write
Schema discovery does not need DELETE. Summarizing a ticket does not need create_wire_transfer. One agent, one job; separate principals for read-only analytics vs. deploy-capable actions. This is IAM 101, but teams keep handing copilots god-mode GitHub PATs because standup is faster that way.
3. Log tool calls, not just chat
"The model did something weird" is not investigable without telemetry: which tool, which subject/user, timestamp, allow/deny, argument hash (redact secrets, keep intent). Stdio MCP on a laptop logs to nowhere useful. Put a gateway in front if you care about forensics—see our MCP gateway writeup if you haven't.
4. Assume indirect prompt injection on every retrieval path
Any document, email, webpage, or ticket body the agent reads is an attack surface. Hidden instructions in white-on-white text, HTML comments, or "ignore previous instructions" in a customer support thread are boringly effective. Design workflows so high-impact tool calls need a human gate—or a second system that doesn't ingest the same untrusted blob.
5. Pin dependencies and sandbox the runtime
npx -y @random/mcp-server is curl | bash with extra steps. Pin versions, prefer signed container images, run servers with read-only mounts and egress allowlists. Same discipline you (hopefully) already apply to npm in CI—extend it to whatever spawns when someone opens Cursor.
6. Scope tokens like you'll leak them tomorrow
Short-lived OAuth, fine-scoped PATs, per-user tokens instead of shared service accounts. Never commit mcp.json with live secrets. Rotate after any vendor incident in your integration chain—Salesforce OAuth raids in 2026 should have been everyone's wake-up call.
7. Inventory agent hosts like you inventory laptops
Cursor, Copilot, homegrown agent APIs—who installed what, on which machine, with access to which VPC? If security can't produce a list, attackers will produce one for you.
Dont's
1. Don't trust "the model refused"
Safety tuning blocks obvious jailbreaks in the chat box. It does not reliably block tool metadata, indirect injection in a PDF, or a poisoned resource the retrieval layer ingested. Test with adversarial inputs; don't debate philosophy in the threat model doc.
2. Don't load 40 tools because more context = better
Hosts silently drop tools when you exceed practical limits. You end up with a random subset, zero understanding of which capabilities are live, and a wider attack surface than any single task needs. Disable what you don't use.
3. Don't point agents at production without rate limits on side effects
Bulk API reads, mass ticket updates, automated refunds—anything that scales abuse needs rate limits, spend caps, and anomaly detection. Agents industrialize throughput; your controls should too.
4. Don't let every developer hold org-admin tokens in a global config
Shared god-mode credentials in ~/.cursor/mcp.json mean one compromised laptop or one malicious repo instruction inherits the whole kingdom. Centralize behind a gateway with RBAC or per-user OAuth where the platform supports it.
5. Don't skip red team because "it's internal only"
Internal copilots read internal email, which attackers phish into constantly. Paste indirect injection test cases into tickets and docs your agents routinely summarize. If nobody on the team can trigger a bad tool call in staging, you haven't finished building.
6. Don't buy an "AI governance framework" slide and call it done
Frameworks without owners, allowlists, and logging are wallpaper. The useful output is: allowed servers list, token rotation schedule, tool-call audit trail, and an on-call runbook for "agent exported customer table."
7. Don't conflate model vendor security with your deployment security
OpenAI/Anthropic/Google harden their APIs. They do not harden your MCP server, your RAG corpus full of pasted customer emails, or your decision to wire the agent to Stripe. Supply-chain and integration risk stays yours.
Where this connects to real breaches
2026 incidents BreachHistory tracks still look familiar up close: credential theft, SaaS misconfigurations, vendor archives left on file stores. Agents don't replace those failures—they accelerate them when the same OAuth token that reads Salesforce also feeds an automation pipeline nobody audited.
If you want depth on specific layers: MCP tool poisoning, what changed in the AI era, and gating MCP for teams.
Minimum viable secure agent (if you're small)
- One read-only tool set for exploration; write tools behind a separate config few people enable.
- Pinned MCP/npm versions; no
@latestin shared configs. - Secrets in a manager, not git.
- Weekly check: what tools are enabled, what tokens expire when.
- One indirect-injection test case in your eval set—ticket with hidden instructions, see if anything fires.
That's not zero trust. It's better than what most teams have today, which is zero inventory and full trust in a JSON file on a developer MacBook.
Further reading: Microsoft on indirect injection in MCP, Invariant Labs tool poisoning, MCP spec.