The decision in one line: agent security is two different jobs wearing one name — the authorization layer you must always build yourself, and the observe-and-halt layer that, past a handful of agents, is now worth buying. CrowdStrike just paid a reported ~$495M for Fiddler AI and Dreadnode and shipped an "AI Kill Switch" — which tells you the second job has become a product category. The trap is buying a monitoring platform and thinking you've bought the first job too. You haven't. Here's where the line actually falls.
Two jobs, one bundle#
When a vendor sells "AI agent security," it usually means one of two things that get blurred together:
- Authorization — what an agent is allowed to do. Per-task least-privilege credentials, tool allowlists, default-deny egress, human-approval gates on dangerous actions. This encodes your product's rules.
- Observability and containment — seeing what the agent actually did, and being able to stop it. Decision traces, cost metrics, anomaly detection across a fleet, and a kill switch.
They sound like one topic. They are not, and the build-vs-buy answer is opposite for each.
The half you must always build#
No external platform can own your authorization boundary, because only your application knows what a given agent is supposed to be allowed to do. A vendor can watch the fence and alert when it's jumped; it cannot decide where the fence goes. So the least-privilege controls stay yours, always: short-lived per-task credentials instead of a standing admin key, an allowlist of callable tools, egress denied by default, and human approval gated on deploys, deletions, payments, and secret reads. That's the checklist Anthropic's own S-1 incident made concrete, and we covered it in full in how to stop your agent from breaking into things it shouldn't. If you buy a shiny dashboard and skip this, you've bought a very good camera pointed at an unlocked door.
A monitoring platform can watch your authorization boundary. It can never be it. Buy the camera if you like — but you still have to build the lock.
The half that's now worth buying#
The other half is where CrowdStrike's checkbook is pointing. Observability and containment get expensive and genuinely hard exactly at fleet scale — and that's the part worth paying for:
- Cross-agent anomaly and drift detection. Spotting that one agent among fifty has started behaving unlike itself is a real data-science job, and it's the core of what Fiddler-style observability does.
- Unified trace retention and audit across teams and tenants, in one place, retained long enough to reconstruct an incident.
- A fleet-wide kill switch — CrowdStrike's "AI Kill Switch" terminates a misbehaving agent, blocks its restart, and revokes its network access across the estate, not just in the one app you remembered to wire it into.
- Pre-deployment red-teaming, Dreadnode-style, mapped to the OWASP LLM Top 10, MITRE ATLAS, and the NIST AI RMF, so "we tested it adversarially" is an artifact, not a claim.
For one or two agents, all of this is overkill. Past roughly five in production — or the first time a customer's security questionnaire asks how you observe and halt your agents — the platform starts earning its price.
The move that keeps the decision reversible#
Here's the part that makes build-vs-buy a choice you can defer instead of a bet you have to win: emit portable signals from day one, no matter what. You cannot buy observability into a system that logged nothing, and you don't want to be locked to the first vendor you tried.
OpenTelemetry's GenAI semantic conventions exist for exactly this — so your agent traces are portable instead of vendor-shaped. The DIY version is a few lines around every model and tool call:
from opentelemetry import trace
tracer = trace.get_tracer("agent")
def call_tool(name, args, run_id):
with tracer.start_as_current_span(f"tool.{name}") as span:
span.set_attribute("gen_ai.agent.run_id", run_id)
span.set_attribute("gen_ai.tool.name", name)
span.set_attribute("gen_ai.tool.args", str(args))
result = TOOLS[name](**args) # <- your allowlist lives here, not in a vendor
span.set_attribute("gen_ai.tool.result_len", len(str(result)))
COST.labels(run_id=run_id).inc(price_of(name, args)) # cost + action counters
return result
Three things fall out of that span-per-call habit: a decision/tool-call trace, cost and action accounting per task (the cheapest way to catch the agent that quietly costs 100x), and a natural place to hang the halt path you must test in a drill. Do that, and adopting a platform later is a layer you add on top — not a migration you have to survive. The authorization boundary stays in your code where it belongs; the observe-and-halt layer becomes a build-or-buy call you make on cost and scale, with the exits already instrumented.



