On Saturday, March 14, I opened six issues in the space of half an hour: crewAI, Haystack, AutoGen, Semantic Kernel, the Vercel AI SDK and OpenClaw, plus comments on an old LangChain permissions issue and an Atlassian MCP server thread. I was looking for one specific thing. Pre-action authorization. The ability to intercept a tool call before it executes and ask: should this actually run?

None of them had it.

On Thursday, March 19 and Friday, March 20, I did the same thing to six more. Same question. Same answer, in six new dialects.

TL;DR

  • 12 frameworks got an issue across two rounds: crewAI, Haystack, AutoGen, Semantic Kernel, Vercel AI SDK, OpenClaw, Superpowers, openfang, Mastra, deer-flow, VoltAgent and AgentScope runtime. LangChain and Atlassian MCP got comments on existing threads
  • All of them have hooks, guardrails, or validation. None enforces pre-action authorization natively
  • The most common answer is "we have guardrails," which usually means output filters, not action blockers
  • The gap maps to OWASP ASI02, Tool Misuse and Exploitation, the highest-risk category for agentic apps
  • Real attacks already exploit it: Comment and Control stole CI secrets from three coding agents in April, and a Morse-code prompt injection moved $175,000 in May
  • The fix is a layer that runs before the tool call, outside the framework. Build it once, wrap anything

The issue-filing happened in March; the attacks in the second half came later.

The scorecard upfront

FrameworkHooks?Policy engine?Decision receipts?Kill switch?Pre-action auth?
crewAIYes (GuardrailProvider)NoNoNoNo
LangChainYes (BaseTool.before_run)NoNoNoNo
AutoGenYes (human-in-loop)NoNoNoNo
Atlassian MCPYes (OAuth)NoNoNoNo
MastraYes (processors)NoNoNoNo
AgentScope runtimeNot documentedNoNoNoNo
VoltAgentNot documentedNoNoNoNo
deer-flowNot at the timeNoNoNoNo
HaystackUnder discussionNoNoNoNo
openfangNot documentedNoNoNoNo
SuperpowersSkill-level onlyNoNoNoNo

Semantic Kernel, the Vercel AI SDK and OpenClaw got the same proposal and are not scored here; those threads were still open when I wrote this. Hooks are not authorization. This table is the whole post in one place.

Why I went framework shopping

I have been building APort, a pre-action authorization layer for AI agents. The core idea is simple: before an agent calls a tool (sends an email, deletes a file, executes a query), something should verify that this specific action is authorized at this specific moment, by this specific agent, with these specific parameters.

The question most frameworks answer is "does this agent have access to the email tool." That is authentication, and it is the wrong question.

The right question: should this agent send this email to these recipients with this content right now?

Those are different questions. Frameworks almost universally answer the first one. Almost none answer the second.

When I say that to developers, the most common response is: "doesn't my framework already handle that?" So I decided to check, systematically, across the frameworks people are actually using.

What I was looking for

Before walking through each framework, I defined what pre-action authorization means concretely:

  1. Intercept before execution: the hook fires before the tool runs, not after
  2. Policy evaluation: a decision (allow / deny / escalate) based on the specific parameters of the call
  3. Per-call receipts: a signed, auditable log of every authorization decision
  4. Kill switch: a way to stop a compromised agent from any future tool calls
  5. Scope limits: a maximum blast radius definition (this agent can only affect these resources)

This is not a fantasy spec. This is what payment processors required of every fintech API by 2018. Every transaction is authorized at the transaction level, every time, rather than once at account-open. AI agents are not more trustworthy than wire transfers. They should not have looser controls.

Round one, March 14: the frameworks everyone runs

crewAI. The guardrail model lives inside GuardrailProvider. You write a class that wraps agent behavior and returns validation results. The interface is clean and the docs are honest about what it does: it validates input and output content. What it does not do is stop a tool call based on the specific parameters of that call. I opened issue #4877 proposing a provider-agnostic GuardrailProvider with a before-tool-call hook. The thread ran to more than 20 comments from other builders comparing notes on suspend-and-resolve patterns and default-deny on timeout. No maintainer replied. You can validate that an email's content looks fine and still send it to the wrong person.

LangChain. The widest surface area of any framework here: callbacks, middleware hooks, tool wrappers, a large ecosystem. The closest thing to what I wanted is BaseTool.before_run. You can override it, add checks, and return early. That is a coding convention, not an authorization primitive. There is no standard policy language, no decision receipt, and no way to enforce it across every tool without writing a custom wrapper for each one. I left a comment on issue #4912, "Add permission model to tools", which has been open since May 2023. The honest summary from the thread: LangChain gives you the hooks, building authorization is on you. Hooks without a policy engine are escape hatches. A fire escape is not a sprinkler system.

AutoGen. Safety is centered on human-in-the-loop confirmation. Before a consequential action, the agent can be configured to ask a human. That is honest and useful for research contexts. It does not scale: you cannot run 50 concurrent agents with a human checkpoint on every file system call. What is missing is automated policy evaluation that approves or denies programmatically, with no human present. Issue #7405 proposes exactly that.

Atlassian MCP. MCP servers have an authentication layer, OAuth-based and improving quickly. What they lack is the authorization layer that sits after authentication and before execution. You can authenticate to Jira. You can be authorized to use the Jira MCP server. Nothing stops an agent with those credentials from closing every ticket in a project if it is prompted, or injected, to do so. OAuth gets the agent in the door. Nothing stops it from rearranging the furniture. I raised it on issue #90; the thread closed the next day.

Haystack (deepset). A mature pipeline framework for RAG and agentic systems, and the most substantive conversation of the two weeks. Issue #10821 drew seven comments by March 19. A contributor offered to build it within a day. A deepset engineer asked them to hold off while the team discussed internally how they wanted to approach it. Promising, and still a conversation rather than a merge.

Round two, March 19 and 20: six more

This round was the newer generation, the ones with momentum right now.

Mastra. TypeScript-first, strong tooling for structured workflows, observability built in, which is more than most. I asked in issue #14545 whether tool execution passes through any authorization hook before the call goes out. The maintainer closed it within half an hour: guardrails are processors under the hood, write your own processor. That is a real extension point, and it is still a convention rather than a policy layer. Observability gives you the receipt. It does not give you the checkpoint.

AgentScope runtime. Handles message passing, agent composition, and sandboxed tool calls well. Tool calls can reach external APIs, write files, and invoke arbitrary tools with no deterministic policy step before execution. Issue #465 was labeled "enhancement" and, as of this writing, has no reply.

VoltAgent. Newer, moving fast. I asked in issue #1166 whether tool invocations can be gated by a policy check before execution. Labeled "enhancement," which is at least honest: this is a future feature, not a current one.

deer-flow (ByteDance). Deep research workflows, chaining tool calls to compile information. For a framework designed to access the web, read documents, and call APIs, the absence of a per-action authorization layer was worth naming. A deer-flow agent could retrieve a sensitive internal document, call an external API with credentials it found in context, or write to a database, without a single check. This one ended well. A maintainer replied to issue #1213 asking for a PR. I opened PR #1240, pre-tool-call authorization middleware with pluggable providers, on March 22. It merged on March 23.

openfang (RightNow-AI). Focused on hand-off execution in multi-agent scenarios. I opened issue #754 proposing pre-action authorization in the Hand tool execution pipeline. Still open, labeled "enhancement." The hand-off pattern is exactly where authorization failures cascade: Agent A authorizes itself, delegates to Agent B, and Agent B inherits permissions it was never explicitly granted.

obra/superpowers. Superpowers is Jesse Vincent's skills library for Claude Code. Its core concept is composable agent skills, which is precisely where pre-action authorization matters most: a skill calls another skill, and with no permission boundary between them you get unbounded capability propagation. I opened issue #841 proposing a permissions stanza in the SKILL.md schema, based on OAP (Open Agent Passport), that would let a framework declare at skill-load time what a skill is authorized to do and enforce it at runtime. obra closed it ten minutes later: "Until this becomes a standardized part of the agent skills spec, I don't think this makes sense for us." I replied that I would take it to the Anthropic team.

That answer is doing a lot of work. The maintainer did not dispute the problem. He said the fix belongs in the spec, upstream, not in one library.

Three kinds of answer

The responses across both rounds fell into three groups.

Observability theater. "We have logging and tracing." That tells you what happened after. Pre-action authorization prevents the thing from happening. Different problems.

Backlog honesty. "Enhancement request." The most honest answer. The teams know the gap and are prioritizing other work.

Escalation. obra's response is rare. It treats the question as architectural instead of additive. You cannot bolt authorization onto a framework that was not designed for it. It has to be part of the spec.

Building permits work this way. You do not get one after construction.

OWASP's 2026 Top 10 for Agentic Applications names this ASI02: Tool Misuse and Exploitation. The definition is an agent using an authorized tool in a destructive way. The mitigation is to enforce strict, granular permissions and validate arguments before tool execution. The word "before" is doing all the work in that sentence, and it is exactly what is missing.

The attack that turns the gap into stolen credentials

None of this stayed theoretical for long.

On April 15, Aonan Guan, with Zhengyu Liu and Gavin Zhong of Johns Hopkins University, published the Comment and Control attack. Someone opens a pull request on a popular repository with a title that looks normal. Hidden in that title is a payload. An AI coding agent running in GitHub Actions reads the PR, processes the diff, starts its security review, and runs a shell command (ps auxeww, which reads the environment of every process) that dumps credentials to a file.

The stolen credentials are not the attacker's. They are the host repository's own GitHub Actions secrets, the ANTHROPIC_API_KEY and GITHUB_TOKEN the maintainer configured to power the agent.

It worked on three of the most widely deployed coding agents: Claude Code Security Review, Google Gemini CLI Action, and GitHub Copilot Agent. All three follow the same flow. The agent reads GitHub data. That data is interpolated into the system prompt with no sanitization. The agent executes tools based on the injected instructions. Results get posted back as comments or commits. The write-up shows the Claude CLI being invoked without --disallowed-tools, giving the agent full access to file reads and command execution.

Anthropic's fix was a --disallowed-tools entry blocking ps. That is the right idea pointed the wrong way. An allowlist of permitted tools is safer than a blocklist of forbidden ones, because the list of dangerous commands is infinite. The next variant can use python3 -c, curl, or awk. A blocklist has to catch all of them. An allowlist only has to name the two or three commands the agent actually needs.

Security layerWhat it protectsComment and Control
Prompt sanitizationModel inputFails, injection bypasses filters
Output filteringModel outputFails, injected commands run before the output check
Tool sandboxingExecution environmentHelps, all-or-nothing
Pre-action authorizationEach tool callStops the attack

Five days after the disclosure, on April 20, the Center for Internet Security published its AI Agents Companion Guide, applying CIS Controls v8.1 to agent architectures and naming unauthorized actions, data leakage and unintended system changes as the risks to control for. VentureBeat's write-up of Comment and Control the next day made a sharper point: a SOC analyst running a full scan that Monday morning would have found zero entries for a critical vulnerability that hit three vendors' agents at once.

Prompt injection is an authorization problem. The model will always follow instructions in the data it processes. That is its job. The question is whether those instructions turn into real actions.

Identity is not authorization

The market noticed half of this. ERC-8004, "Trustless Agents", was drafted in August 2025 by authors from MetaMask, the Ethereum Foundation, Google and Coinbase, and a registry ecosystem has grown around it: on-chain agent identity, reputation scores, discovery so any system can verify who it is dealing with. RNWY, one of the companies building on it, now advertises more than 150,000 registered agents.

Registration is the KYC layer for agents, and it is worth having. It is not the same as deciding whether a given action should happen.

My time at Chimoney made the distinction concrete. The first compliance lesson in any regulated financial system: KYC and transaction authorization are separate layers, handled by separate systems, evaluated at separate moments. KYC tells you who the customer is. It does not decide whether this specific wire, to this counterparty, for this amount, goes through right now. A customer who passes KYC with a perfect score still triggers a fraud hold on an unusual $50,000 transfer.

Agent registry (ERC-8004)Pre-action authorization
Core questionWho is this agent?What can this agent do right now?
MechanismOn-chain identity plus reputationPolicy engine at the call site
When it runsRegistration and discoveryBefore every tool call
What it storesIdentity, provenance, historyDeclared capabilities, per-action decisions
Enforcement modelRegistry, declarativeInterceptor, imperative

These compose. A trust score is a useful signal for a policy engine: strong reputation earns broader capabilities, a new agent with no history gets a tighter default. A deny decision feeds back into what the registry records. Building an agent security stack with only the registry is like building financial infrastructure with KYC and no transaction controls. You have solved half the problem and created confidence about the other half.

Asking a human is not authorization either

On May 7, Twilio launched Ola, an agent-native communication channel built on its Agent-to-Human (A2H) protocol. When an agent wants to act, it sends a structured request. Ola checks it against your permission preferences and auto-approves, routes it to you, or blocks it. Every approval generates a signed artifact linking the intent to the decision. Every intent is logged. There is a kill switch.

The industry standardized how agents talk to tools (MCP), how agents talk to each other (A2A), and how they handle payments. Nobody had standardized how an agent asks permission from the human it works for. Twilio took a swing at that, and the signed approval trail matters: a signed, timestamped authorization beats a Slack "ok" lost in a thread.

It is still one layer short. Ola answers "should the human approve this?" It does not answer "is this tool invocation authorized by policy?"

Three days earlier, on May 4, a prompt injection written in Morse code drained $175,000 in DRB tokens from a wallet controlled by the Bankrbot agent. Someone posted Morse on X, Grok decoded it publicly and tagged Bankrbot, the decoded message said to withdraw all DRB to a named address, and Bankrbot did as it was told. No hacked keys. No contract bug. An agent with authority to move money and no way to check whether the request was legitimate. The attacker sent the value back minutes later.

Routed through Ola, that transfer would have hit a human's phone, and most humans would say no to an unknown destination wallet. Routed through a policy engine, it never reaches the human at all, because the agent was never authorized to transfer the full balance to an arbitrary address in the first place. Corporate banking works the second way: a wire over $10,000 requires two signatures, and the system refuses to execute until both exist.

The fix is a separate layer

The right mental model is borrowed from payments. A processor does not embed authorization logic inside each payment method. It runs a separate authorization service that all payment paths route through. That service evaluates the transaction against policy, returns a decision, and logs a signed receipt. It can be updated without touching the payment methods.

AI agent authorization works the same way. A layer that wraps any tool call, regardless of which framework generated it, and enforces policy before execution.

That is what I have been building with APort. The guardrail intercepts every tool call, evaluates it against the agent's passport and policy definitions, and returns a signed allow or deny. It ships as a Claude Code hook, a Cursor hook, an OpenClaw plugin, a LangChain callback, a crewAI provider, and, since March 23, deer-flow middleware.

When the agent asks to run a command, the layer checks four things: is this tool allowed in this workflow, is this specific argument allowed, who initiated the chain, and what is the blast radius if it goes wrong.

The frameworks will catch up. Some already have roadmap items pointing this way, and one merged the fix. My guess is that the patterns payments normalized take about five years to migrate into an adjacent industry, and agents are about three years into that migration. In the meantime, if you are shipping agents that can send messages, modify records, call APIs, or touch files, you wire this up yourself.

The frameworks are not bad. The category is young, authorization is hard, and nobody shipped it as a default.

What's your setup?

Which agent framework are you running in production? Have you had to build your own authorization layer, or are you relying on the framework's built-in controls? I want to hear what people are actually shipping, because the gap I found in the docs does not always match what teams build in practice.

External references

  1. OWASP Top 10 for Agentic Applications, 2026
  2. Comment and Control disclosure write-up
  3. CIS: AI Agents Companion Guide
  4. Cybersecurity News: prompt injection via GitHub comments
  5. Twilio: introducing Ola
  6. CryptoTimes: Grok prompt injection crypto heist
  7. ERC-8004: Trustless Agents
  8. APort agent guardrails