A tool gateway has one job on the critical path: decide whether this caller, right now, may cause this side effect. Argument validation, payload shaping and response normalization all happen only after that decision is a yes.
The argument for putting the tier check first is not aesthetic. If the gateway parses arguments before checking entitlement, a caller with the wrong tier still gets their payload inspected by your code, and any expensive validation or partial side effect that occurs during parsing runs for a caller who should never have reached that code. Subagent permission work makes the same point: a delegated worker with the parent's scope is "privilege carryover, not least privilege," and the fix is a runtime decision before each tool execution rather than static inheritance the subagent MCP analysis.
Order matters because tool calls are where intent becomes a side effect. Logging authorization at the gateway rather than inside the model is recommended precisely because that is "the moment intent becomes a possible side effect" the agent audit trail guide. A tier check that fires after argument parsing is still an authorization check, but it has already spent CPU and trust on a caller it is about to reject.
The sequence, from arrival to dispatch:
- Authenticate the caller and resolve the principal, including any agent acting on a human's behalf.
- Resolve the requested tool identifier to a registered descriptor carrying the required tier.
- Compare the caller's tier against the required tier.
- On failure, log the refusal, return the 403 and stop. Nothing downstream runs.
- On a pass, parse and validate arguments.
- Apply remaining policy, such as approval requirements for destructive calls.
- Dispatch to the tool adapter and record the outcome.
Step 3 is the decision point. Steps 5 through 7 are what your fixtures must prove never ran.
One counterargument deserves attention: some teams want argument shape inside the authorization decision so a low-tier caller can read but not write on the same tool. That is legitimate, but it is a different decision than tier enforcement. Fold argument inspection into the tier check and you have quietly moved the parser back in front of the refusal. Keep tier a property of the tool, and use a separate, later policy step for argument-sensitive rules. Policy engines support this split: Open Policy Agent backed tool approvals express scope, role and tenant checks and can consult conversation history for thresholds, while the guidance is clear that deterministic checks over structured fields are the strong fit and semantic judgment belongs in a classifier step the AI SDK policy tool approvals documentation.
| Placement of tier check | Parser runs for denied callers | Tool reachable before denial | Fixture can prove no dispatch |
|---|---|---|---|
| Before argument parsing | No | No | Yes |
| After parsing, before dispatch | Yes | No | Yes, but parser ran |
| Inside the tool adapter | Yes | Yes | No, adapter invoked |
| Only as a prompt instruction | Yes | Yes | No |



